Initial commit
This commit is contained in:
110
production/classes/cache/cache.php
vendored
Normal file
110
production/classes/cache/cache.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| cache.php
|
||||
| ========================================
|
||||
| Cache Class to Save MySQL Processes
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
class cache {
|
||||
var $filename;
|
||||
var $out;
|
||||
var $cacheStatus = false;
|
||||
var $identifier;
|
||||
|
||||
function cache($identifier = null) {
|
||||
if (!$this->enabled()) return false;
|
||||
if (!cc_is_wriatble(CC_ROOT_DIR.CC_DS."cache")) die("<strong>Error: ".CC_DS."cache folder is not writable!</strong> This can be made writable by accessing your store files with an FTP client or via your web hosting control panel if it has a file manager. The cache folder requires a file permission of 0777 (or as high as your hosting company allows e.g. 0775)");
|
||||
$this->identifier = $identifier;
|
||||
$this->filename .= CC_ROOT_DIR.CC_DS."cache".CC_DS;
|
||||
$this->readCache(false);
|
||||
}
|
||||
|
||||
function enabled() {
|
||||
global $config;
|
||||
return ($config['cache']) ? true : false;
|
||||
}
|
||||
|
||||
function writeCache($dataIn) {
|
||||
if (!$this->enabled()) return false;
|
||||
$this->filename .= $this->path();
|
||||
$this->out = serialize($dataIn);
|
||||
return $this->write();
|
||||
}
|
||||
|
||||
function clearCache() {
|
||||
if (!$this->enabled()) return false;
|
||||
|
||||
if (!empty($this->identifier)) {
|
||||
$filename = $this->filename.$this->path();
|
||||
@unlink($filename);
|
||||
|
||||
#########################
|
||||
|
||||
} else {
|
||||
foreach(glob($this->filename."*.php") as $filename) {
|
||||
@unlink($filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function path() {
|
||||
if (!$this->enabled()) return false;
|
||||
return $this->identifier.".inc.php";
|
||||
}
|
||||
|
||||
function write() {
|
||||
if (!$this->enabled()) return false;
|
||||
if (strlen($this->out)>0) {
|
||||
if (!$handle = fopen($this->filename, 'w')) {
|
||||
$error = true;
|
||||
}
|
||||
|
||||
if (fwrite($handle, $this->out) === false) {
|
||||
$error = TRUE;
|
||||
}
|
||||
fclose($handle);
|
||||
|
||||
if ($error) {
|
||||
die("Cache not writable! Please disable cache functionality or make it writable.");
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function readCache($return = true) {
|
||||
if (!$this->enabled()) return false;
|
||||
$cacheFile = $this->filename.$this->path();
|
||||
if (!@file_exists($cacheFile)) {
|
||||
return false;
|
||||
} else {
|
||||
$this->cacheStatus = true;
|
||||
}
|
||||
if ($return == true) {
|
||||
$fileConts = file_get_contents($cacheFile);
|
||||
$data = unserialize($fileConts);
|
||||
return (!empty($data)) ? $data : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
78
production/classes/cart/encrypt.inc.php
Normal file
78
production/classes/cart/encrypt.inc.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| encrypt.inc.php
|
||||
| ========================================
|
||||
| Class Encrypts Data
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
class encryption {
|
||||
var $td;
|
||||
var $iv;
|
||||
var $ks;
|
||||
var $key;
|
||||
|
||||
##############################################
|
||||
|
||||
function __construct($keyArray = null) {
|
||||
$this->encryption($keyArray);
|
||||
}
|
||||
|
||||
function encryption($keyArray = null) {
|
||||
$this->td = mcrypt_module_open(MCRYPT_RIJNDAEL_256, '', 'ecb', '');
|
||||
$this->iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($this->td), MCRYPT_RAND);
|
||||
$this->ks = mcrypt_enc_get_key_size($this->td);
|
||||
if (!is_null($keyArray) && is_array($keyArray)) $this->generateKey($keyArray);
|
||||
}
|
||||
|
||||
##############################################
|
||||
|
||||
function __destruct() {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
function close() {
|
||||
@mcrypt_module_close($this->td);
|
||||
}
|
||||
|
||||
##############################################
|
||||
|
||||
function generateKey($keyArray) {
|
||||
$this->key = substr(md5(implode('@', $keyArray)), 0, $this->ks);
|
||||
}
|
||||
|
||||
function encrypt($data) {
|
||||
mcrypt_generic_init($this->td, $this->key, $this->iv);
|
||||
$stringEncrypted = mcrypt_generic($this->td, $data);
|
||||
mcrypt_generic_deinit($this->td);
|
||||
return $stringEncrypted;
|
||||
}
|
||||
|
||||
function decrypt($stringEncrypted) {
|
||||
if (!empty($stringEncrypted)) {
|
||||
mcrypt_generic_init($this->td, $this->key, $this->iv);
|
||||
$stringDecrypted = mdecrypt_generic($this->td, $stringEncrypted);
|
||||
mcrypt_generic_deinit($this->td);
|
||||
return trim($stringDecrypted);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
692
production/classes/cart/order.php
Normal file
692
production/classes/cart/order.php
Normal file
@@ -0,0 +1,692 @@
|
||||
<?php
|
||||
/*
|
||||
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| order.php
|
||||
| ========================================
|
||||
| Core Order Class
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
class order {
|
||||
|
||||
var $order;
|
||||
var $orderSum;
|
||||
var $orderInv;
|
||||
|
||||
/*
|
||||
function order() {
|
||||
## Process level constants
|
||||
define('ORDER_PENDING', 1);
|
||||
define('ORDER_PROCESSING', 2);
|
||||
define('ORDER_COMPLETE', 3);
|
||||
define('ORDER_DECLINED', 4);
|
||||
define('ORDER_FAILED', 5);
|
||||
define('ORDER_CANCELLED', 6);
|
||||
}
|
||||
*/
|
||||
|
||||
function storeTrans($transData, $forceLog = true) {
|
||||
global $glob, $db;
|
||||
|
||||
$transDataSQL['time'] = $db->MySQLSafe(time());
|
||||
$transDataSQL['customer_id'] = $db->MySQLSafe($transData['customer_id']);
|
||||
$transDataSQL['gateway'] = $db->MySQLSafe($transData['gateway']);
|
||||
$transDataSQL['extra'] = $db->MySQLSafe($transData['extra']);
|
||||
$transDataSQL['trans_id'] = $db->MySQLSafe($transData['trans_id']);
|
||||
$transDataSQL['order_id'] = $db->MySQLSafe($transData['order_id']);
|
||||
$transDataSQL['status'] = $db->MySQLSafe($transData['status']);
|
||||
$transDataSQL['amount'] = $db->MySQLSafe($transData['amount']);
|
||||
$transDataSQL['notes'] = $db->MySQLSafe($transData['notes']);
|
||||
|
||||
// make sure status isn't repeated on last call
|
||||
$maxStatus = $db->select("SELECT max(`id`), `status` FROM ".$glob['dbprefix']."CubeCart_transactions WHERE `trans_id` = ".$transDataSQL['trans_id']." GROUP BY `id` DESC");
|
||||
|
||||
if (!$forceLog && ($maxStatus[0]['status'] !== $transData['status'] || !$maxStatus)) {
|
||||
$db->insert($glob['dbprefix']."CubeCart_transactions", $transDataSQL);
|
||||
} else if ($forceLog) {
|
||||
$db->insert($glob['dbprefix']."CubeCart_transactions", $transDataSQL);
|
||||
}
|
||||
}
|
||||
|
||||
function mkOrderNo() {
|
||||
$this->cart_order_id = date("ymd-His-").rand(1000, 9999);
|
||||
return $this->cart_order_id;
|
||||
}
|
||||
|
||||
function getOrderSum($cart_order_id) {
|
||||
global $db, $glob;
|
||||
$query = "SELECT * FROM ".$glob['dbprefix']."CubeCart_order_sum INNER JOIN ".$glob['dbprefix']."CubeCart_customer ON ".$glob['dbprefix']."CubeCart_order_sum.customer_id = ".$glob['dbprefix']."CubeCart_customer.customer_id WHERE ".$glob['dbprefix']."CubeCart_order_sum.cart_order_id = ".$db->mySQLSafe($cart_order_id);
|
||||
$order = $db->select($query);
|
||||
$this->orderSum = $order[0];
|
||||
return $order[0];
|
||||
}
|
||||
|
||||
function getOrderInv($cart_order_id) {
|
||||
global $db, $glob;
|
||||
$products = $db->select("SELECT * FROM ".$glob['dbprefix']."CubeCart_order_inv WHERE cart_order_id = ".$db->mySQLSafe($cart_order_id));
|
||||
$this->orderInv = $products;
|
||||
return $this->orderInv;
|
||||
}
|
||||
|
||||
function deleteOrder($cart_order_id) {
|
||||
global $db, $glob;
|
||||
$where = "cart_order_id = '".$cart_order_id."'";
|
||||
$delete = $db->delete($glob['dbprefix']."CubeCart_order_sum", $where);
|
||||
$delete = $db->delete($glob['dbprefix']."CubeCart_order_inv", $where);
|
||||
$delete = $db->delete($glob['dbprefix']."CubeCart_Downloads", $where);
|
||||
}
|
||||
|
||||
function customerOrderCount($customerId, $value) {
|
||||
global $db, $glob;
|
||||
|
||||
$record['noOrders'] = ($value>0) ? "noOrders + ".$value : "noOrders - ".$value;
|
||||
$where = "customer_id = ".$customerId;
|
||||
$update = $db->update($glob['dbprefix']."CubeCart_customer", $record, $where);
|
||||
}
|
||||
|
||||
function manageStock($statusId,$cart_order_id){
|
||||
|
||||
global $db, $glob, $config;
|
||||
|
||||
if(!is_array($this->orderInv)){
|
||||
$this->getOrderInv($cart_order_id);
|
||||
}
|
||||
|
||||
for($i=0; $i<count($this->orderInv); $i++) {
|
||||
|
||||
// see if product uses stock or not
|
||||
$useStock = $db->select("SELECT useStockLevel FROM ".$glob['dbprefix']."CubeCart_inventory WHERE productId = ".$db->mySQLSafe($this->orderInv[$i]['productId']));
|
||||
|
||||
// if it does continue
|
||||
if ($useStock[0]['useStockLevel']) {
|
||||
|
||||
// reduce stock on payment recieved
|
||||
if (!$config['stock_change_time']) {
|
||||
$reduceStockStatus = 3;
|
||||
|
||||
} else if ($config['stock_change_time'] == 1) {
|
||||
$reduceStockStatus = 2;
|
||||
|
||||
} elseif($config['stock_change_time'] == 2) {
|
||||
|
||||
$reduceStockStatus = 1;
|
||||
// override possible config error cant put stock back for pending orders in this state
|
||||
$config['stock_replace_time'][1] = 0;
|
||||
}
|
||||
|
||||
// reduce stock if not already and status matches time to reduce stock
|
||||
if($this->orderInv[$i]['stockUpdated']==0 && $statusId == $reduceStockStatus) {
|
||||
|
||||
$this->stockLevel($this->orderInv[$i]['quantity'], "-", $this->orderInv[$i]['productId'], $this->orderInv[$i]['id'], 1);
|
||||
|
||||
// replace stock if reduced already and status permits
|
||||
} elseif($this->orderInv[$i]['stockUpdated']==1 && $config['stock_replace_time'][$statusId]==1) {
|
||||
|
||||
$this->stockLevel($this->orderInv[$i]['quantity'], "+", $this->orderInv[$i]['productId'], $this->orderInv[$i]['id'], 0);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function orderStatus($statusId, $cart_order_id, $force = false, $skipEmail = false) {
|
||||
global $db, $glob, $config;
|
||||
|
||||
/*
|
||||
1. Pending (New Order)
|
||||
2. Processing (See order notes)
|
||||
3. Order Complete & Dispatched
|
||||
4. Declined (See notes)
|
||||
5. Failed Fraud Review
|
||||
6. Cancelled
|
||||
*/
|
||||
|
||||
// First make sure this process isn't being repeated! Some payment processors
|
||||
// send more than once in the XML if other attributes have changed
|
||||
|
||||
$currentStatus = $db->select("SELECT `status` FROM ".$glob['dbprefix']."CubeCart_order_sum WHERE `cart_order_id` = ".$db->MySQLSafe($cart_order_id) );
|
||||
|
||||
$this->manageStock($statusId, $cart_order_id);
|
||||
|
||||
if ($currentStatus[0]['status'] !== $statusId) {
|
||||
switch($statusId) {
|
||||
case 2; ## Processing Nothing to do
|
||||
## Email the customer to say payment has been accepted and cleared
|
||||
$lang = getLang("email.inc.php");
|
||||
|
||||
$this->getOrderSum($cart_order_id);
|
||||
|
||||
$macroArray = array(
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"RECIP_NAME" => $this->orderSum['name'],
|
||||
"STORE_URL" => $glob['storeURL']
|
||||
);
|
||||
|
||||
$text = macroSub($lang['email']['payment_complete_body'], $macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
## Send email
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
$mail = new htmlMimeMail();
|
||||
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($this->orderSum['email']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$mail->setSubject(macroSub($lang['email']['payment_complete_subject'], array("ORDER_ID" => $this->orderSum['cart_order_id'])));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->setBcc($config['masterEmail']);
|
||||
$mail->send(array($this->orderSum['email']), $config['mailMethod']);
|
||||
break;
|
||||
|
||||
case 3: ## Order Complete (Payment Taken/Cleared)
|
||||
$breakStatus = false;
|
||||
## Look up order
|
||||
$this->getOrderSum($cart_order_id);
|
||||
$this->getOrderInv($cart_order_id);
|
||||
|
||||
# $count = count($this->orderInv);
|
||||
# for ($i=0; $i<$count; $i++) {
|
||||
if (is_array($this->orderInv)) {
|
||||
foreach ($this->orderInv as $i => $orderItem) {
|
||||
|
||||
## If the order contains tangible items, we set it to ORDER_PROCESSING, and break the loop
|
||||
if (!$this->orderInv[$i]['digital'] && !$force) {
|
||||
$this->orderStatus(2, $cart_order_id);
|
||||
$statusId = 2; ## Safeguard
|
||||
$breakStatus = true; ## Stops email sending below no way to stop this case ?!
|
||||
break;
|
||||
}
|
||||
|
||||
## Send Gift Certificate
|
||||
if (!empty($this->orderInv[$i]['custom'])) {
|
||||
$customArray = unserialize($this->orderInv[$i]['custom']);
|
||||
if ($customArray['cert'] == true) {
|
||||
$this->sendCoupon($customArray, $this->orderInv[$i]['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($breakStatus == false) {
|
||||
|
||||
## If order is completely digital send digital file and keep status as complete
|
||||
$this->digitalAccess();
|
||||
|
||||
## Send order complete email OOOOOH it's a bit diiiirty
|
||||
$lang = getLang("email.inc.php");
|
||||
|
||||
if ($this->orderSum['discount']>0) {
|
||||
$grandTotal = priceFormat($this->orderSum['prod_total'], true)." (-".priceFormat($this->orderSum['discount'], true).")";
|
||||
} else {
|
||||
$grandTotal = priceFormat($this->orderSum['prod_total'], true);
|
||||
}
|
||||
|
||||
$macroArray = array(
|
||||
"RECIP_NAME" => $this->orderSum['name'],
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"ORDER_DATE" => formatTime($this->orderSum['time']),
|
||||
"INVOICE_NAME" => $this->orderSum['name'],
|
||||
"SUBTOTAL" => priceFormat($this->orderSum['subtotal'], true),
|
||||
"SHIPPING_COST" => priceFormat($this->orderSum['total_ship'], true),
|
||||
"TAX_COST" => priceFormat($this->orderSum['total_tax'], true),
|
||||
"GRAND_TOTAL" => $grandTotal,
|
||||
"INVOICE_ADD_1" => $this->orderSum['add_1'],
|
||||
"INVOICE_ADD_2" => $this->orderSum['add_2'],
|
||||
"INVOICE_CITY" => $this->orderSum['town'],
|
||||
"INVOICE_REGION" => $this->orderSum['county'],
|
||||
"INVOICE_POSTCODE" => $this->orderSum['postcode'],
|
||||
"INVOICE_COUNTRY" => getCountryFormat($this->orderSum['country'], 'id', 'printable_name'),
|
||||
"DELIVERY_NAME" => $this->orderSum['name_d'],
|
||||
"DELIVERY_ADD_1" => $this->orderSum['add_1_d'],
|
||||
"DELIVERY_ADD_2" => $this->orderSum['add_2_d'],
|
||||
"DELIVERY_CITY" => $this->orderSum['town_d'],
|
||||
"DELIVERY_REGION" => $this->orderSum['county_d'],
|
||||
"DELIVERY_POSTCODE" => $this->orderSum['postcode_d'],
|
||||
"DELIVERY_COUNTRY" => $this->orderSum['country_d'],
|
||||
"PAYMENT_METHOD" => $this->orderSum['gateway'],
|
||||
"DELIVERY_METHOD" => $this->orderSum['shipMethod']
|
||||
);
|
||||
|
||||
$text = macroSub($lang['email']['order_breakdown_1'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
if(!empty($this->orderSum['customer_comments'])) {
|
||||
$macroArray = array(
|
||||
"CUSTOMER_COMMENTS" => $this->orderSum['customer_comments']
|
||||
);
|
||||
|
||||
$text .= macroSub($lang['email']['order_breakdown_2'],$macroArray);
|
||||
|
||||
unset($macroArray);
|
||||
}
|
||||
|
||||
$text .= $lang['email']['order_breakdown_3'];
|
||||
|
||||
for ($i=0; $i<count($this->orderInv); $i++) {
|
||||
$macroArray = array(
|
||||
"PRODUCT_NAME" => $this->orderInv[$i]['name']
|
||||
);
|
||||
|
||||
$text .= macroSub($lang['email']['order_breakdown_4'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
$macroArray = array(
|
||||
"PRODUCT_OPTIONS" => $this->orderInv[$i]['product_options']
|
||||
);
|
||||
|
||||
$text .= macroSub($lang['email']['order_breakdown_5'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
$macroArray = array(
|
||||
"PRODUCT_QUANTITY" => $this->orderInv[$i]['quantity'],
|
||||
"PRODUCT_CODE" => $this->orderInv[$i]['productCode'],
|
||||
"PRODUCT_PRICE" => priceFormat($this->orderInv[$i]['price'],true)
|
||||
);
|
||||
|
||||
$text .= macroSub($lang['email']['order_breakdown_6'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
}
|
||||
|
||||
# //$lang['email']['order_breakdown_7'] => "EXTRA_NOTES", coments to customer to do
|
||||
## Send email
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
|
||||
$mail = new htmlMimeMail();
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($this->orderSum['email']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$mail->setSubject(macroSub($lang['email']['order_breakdown_subject'], array("ORDER_ID" => $this->orderSum['cart_order_id'])));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->setBcc($config['masterEmail']);
|
||||
$mail->send(array($this->orderSum['email']), $config['mailMethod']);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
//case 4: // Declined nothing to do
|
||||
|
||||
//break;
|
||||
|
||||
case 5:
|
||||
## email customer to explain their order failed fraud review
|
||||
$this->orderSum = $this->getOrderSum($cart_order_id);
|
||||
|
||||
$lang = getLang("email.inc.php");
|
||||
|
||||
$macroArray = array(
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"RECIP_NAME" => $this->orderSum['name'],
|
||||
"ORDER_URL_PATH" => $glob['storeURL']."/index.php?_g=co&_a=viewOrder&cart_order_id=".$this->orderSum['cart_order_id'],
|
||||
"STORE_URL" => $glob['storeURL']
|
||||
);
|
||||
|
||||
$text = macroSub($lang['email']['fraud_body'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
## send email
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
|
||||
$mail = new htmlMimeMail();
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($this->orderSum['email']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$mail->setSubject(macroSub($lang['email']['fraud_subject'],array("ORDER_ID" => $this->orderSum['cart_order_id'])));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->setBcc($config['masterEmail']);
|
||||
$mail->send(array($this->orderSum['email']), $config['mailMethod']);
|
||||
break;
|
||||
|
||||
case 6: ## cancelled (Can be cancelled by either admin/customer)
|
||||
$this->orderSum = $this->getOrderSum($cart_order_id);
|
||||
|
||||
if (!$skipEmail) {
|
||||
|
||||
$lang = getLang("email.inc.php");
|
||||
|
||||
$macroArray = array(
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"RECIP_NAME" => $this->orderSum['name'],
|
||||
"ORDER_URL_PATH" => $glob['storeURL']."/index.php?_g=co&_a=viewOrder&cart_order_id=".$this->orderSum['cart_order_id'],
|
||||
"STORE_URL" => $glob['storeURL']
|
||||
);
|
||||
|
||||
$text = macroSub($lang['email']['payment_cancelled_body'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
## Send email
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
$mail = new htmlMimeMail();
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($this->orderSum['email']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$mail->setSubject(macroSub($lang['email']['payment_cancelled_subject'],array("ORDER_ID" => $this->orderSum['cart_order_id'])));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->setBcc($config['masterEmail']);
|
||||
$mail->send(array($this->orderSum['email']), $config['mailMethod']);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$data['status'] = $statusId;
|
||||
$db->update($glob['dbprefix']."CubeCart_order_sum", $data, "cart_order_id=".$db->mySQLSafe($cart_order_id));
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function stockLevel($level, $sign, $productId, $orderInvId, $stockUpdated) {
|
||||
global $db, $glob;
|
||||
|
||||
$query = "UPDATE ".$glob['dbprefix']."CubeCart_inventory SET stock_level = stock_level ".$sign." ".$level." WHERE `productId` = ".$productId;
|
||||
$update = $db->misc($query);
|
||||
|
||||
$query = "UPDATE ".$glob['dbprefix']."CubeCart_order_inv SET stockUpdated = ".$stockUpdated." WHERE `id` = ".$orderInvId;
|
||||
$update = $db->misc($query);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function sendCoupon($customArray, $id) {
|
||||
|
||||
global $db, $cart_order_id, $glob, $lang, $config, $order;
|
||||
|
||||
## Create coupon code for the gift certificate
|
||||
$chars = array("A","B","C","D","E","F","G","H","J","K","L",'M',"N","P","Q","R","S","T","U","V","W","X","Y","Z");
|
||||
$max_chars = count($chars)-1;
|
||||
$coupon = sprintf('%s-%d-%d', $chars[mt_rand(0, $max_chars)].$chars[mt_rand(0, $max_chars)], time(), mt_rand(1000, 9999));
|
||||
|
||||
## e.g: RW-1147691506-6723
|
||||
|
||||
$data['status'] = $db->mySQLSafe(1);
|
||||
$data['code'] = $db->mySQLSafe($coupon);
|
||||
$data['discount_percent'] = $db->mySQLSafe(0);
|
||||
$data['discount_price'] = $db->mySQLSafe($customArray['amount']);
|
||||
$data['expires'] = $db->mySQLSafe(date('m/d/').(date('Y')+2));
|
||||
$data['allowed_uses'] = $db->mySQLSafe(0);
|
||||
$data['cart_order_id'] = $db->mySQLSafe($this->orderSum['cart_order_id']);
|
||||
|
||||
$db->insert($glob['dbprefix']."CubeCart_Coupons", $data);
|
||||
|
||||
$couponId['couponId'] = $db->insertid();
|
||||
$db->update($glob['dbprefix'].'CubeCart_order_inv', $couponId, 'id='.$db->mySQLSafe($id));
|
||||
|
||||
$lang = getLang('email.inc.php');
|
||||
|
||||
$macroArray = array(
|
||||
"RECIP_NAME" => $customArray['recipName'],
|
||||
"SENDER_NAME" => $this->orderSum['name'],
|
||||
"SENDER_EMAIL" => $this->orderSum['email'],
|
||||
"AMOUNT" => priceFormat($customArray['amount'], true),
|
||||
"MESSAGE" => $customArray['message'],
|
||||
"COUPON" => $coupon,
|
||||
"STORE_URL" => $glob['storeURL']
|
||||
);
|
||||
|
||||
$couponText = macroSub($lang['email']['coupon_body'], $macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
## Send email
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
|
||||
$mail = new htmlMimeMail();
|
||||
$mail->setText($couponText);
|
||||
$mail->setReturnPath($customArray['recipEmail']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$mail->setSubject($lang['email']['coupon_subject']);
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->send(array($customArray['recipEmail']), $config['mailMethod']);
|
||||
|
||||
}
|
||||
|
||||
function digitalAccess() {
|
||||
global $db, $glob, $lang, $config;
|
||||
$digitalProducts = $db->select("SELECT * FROM ".$glob['dbprefix']."CubeCart_Downloads INNER JOIN ".$glob['dbprefix']."CubeCart_inventory ON ".$glob['dbprefix']."CubeCart_Downloads.productId = ".$glob['dbprefix']."CubeCart_inventory.productId WHERE cart_order_id = ".$db->mySQLSafe($this->orderSum['cart_order_id']));
|
||||
|
||||
if($digitalProducts == true) {
|
||||
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
$lang = getLang("email.inc.php");
|
||||
$mail = new htmlMimeMail();
|
||||
## build email with access details
|
||||
|
||||
$macroArray = array(
|
||||
"RECIP_NAME" => $this->orderSum['name'],
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"ORDER_DATE" => formatTime($this->orderSum['time']),
|
||||
"EXPIRE_DATE" => formatTime($digitalProducts[0]['expire']),
|
||||
"DOWNLOAD_ATTEMPTS" => $config['dnLoadTimes'],
|
||||
);
|
||||
|
||||
$text = macroSub($lang['email']['downloads_body'],$macroArray);
|
||||
unset($macroArray);
|
||||
|
||||
for($i=0; $i<count($digitalProducts); $i++) {
|
||||
$macroArray = array(
|
||||
"PRODUCT_NAME" => $digitalProducts[$i]['name'],
|
||||
"DOWNLOAD_URL" => $glob['storeURL']."/index.php?_g=dl&pid=".$digitalProducts[$i]['productId']."&oid=".base64_encode($this->orderSum['cart_order_id'])."&ak=".$digitalProducts[$i]['accessKey']
|
||||
);
|
||||
$text .= macroSub($lang['email']['downloads_body_2'], $macroArray);
|
||||
unset($macroArray);
|
||||
}
|
||||
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($this->orderSum['email']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$macroArray = array("ORDER_ID" => $this->orderSum['cart_order_id']);
|
||||
$mail->setSubject(macroSub($lang['email']['downloads_subject'],$macroArray));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->send(array($this->orderSum['email']), $config['mailMethod']);
|
||||
}
|
||||
}
|
||||
|
||||
function cancelOldOrders() {
|
||||
|
||||
global $db, $glob, $config;
|
||||
|
||||
if($config['orderExpire']==0) {
|
||||
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
$expiryLimit = time() - $config['orderExpire'];
|
||||
|
||||
$expiredOrders = $db->select("SELECT `cart_order_id` FROM ".$glob['dbprefix']."CubeCart_order_sum WHERE `status` = 1 AND `time` < ".$expiryLimit);
|
||||
|
||||
if($expiredOrders) {
|
||||
|
||||
for($i=0; $i<count($expiredOrders); $i++) {
|
||||
$this->orderStatus(6, $expiredOrders[$i]['cart_order_id']);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function createOrder($orderInv, $orderSum, $skipEmail = false) {
|
||||
global $glob, $config, $db;
|
||||
/*
|
||||
Repeated Order Inventory Variables
|
||||
|
||||
$orderInv[$i]['productId']
|
||||
$orderInv[$i]['name']
|
||||
$orderInv[$i]['price']
|
||||
$orderInv[$i]['quantity']
|
||||
$orderInv[$i]['product_options']
|
||||
$orderInv[$i]['productCode']
|
||||
$orderInv[$i]['digital']
|
||||
$orderInv[$i]['custom']
|
||||
|
||||
Order Summary Variables
|
||||
|
||||
$orderSum['cart_order_id']
|
||||
$orderSum['customer_id']
|
||||
$orderSum['email']
|
||||
$orderSum['name']
|
||||
$orderSum['add_1']
|
||||
$orderSum['add_2']
|
||||
$orderSum['town']
|
||||
$orderSum['county']
|
||||
$orderSum['postcode']
|
||||
$orderSum['country']
|
||||
$orderSum['phone']
|
||||
$orderSum['mobile']
|
||||
$orderSum['currency']
|
||||
|
||||
$orderSum['name_d']
|
||||
$orderSum['add_1_d']
|
||||
$orderSum['add_2_d']
|
||||
$orderSum['town_d']
|
||||
$orderSum['county_d']
|
||||
$orderSum['postcode_d']
|
||||
$orderSum['country_d']
|
||||
|
||||
$orderSum['subtotal']
|
||||
$orderSum['discount']
|
||||
$orderSum['total_ship']
|
||||
$orderSum['total_tax']
|
||||
$orderSum['prod_total']
|
||||
$orderSum['shipMethod']
|
||||
|
||||
$orderSum['tax'.$i.'_disp'] = $taxes[$i]['display'];
|
||||
$orderSum['tax'.$i.'_amt'] = $taxes[$i]['amount'];
|
||||
|
||||
$orderSum['gateway']
|
||||
|
||||
$orderSum['basket']
|
||||
|
||||
*/
|
||||
|
||||
if (is_array($orderInv)) {
|
||||
for ($i=1; $i<=count($orderInv); $i++) {
|
||||
foreach ($orderInv[$i] as $key => $value) {
|
||||
$orderInvIn[$key] = $db->mySQLSafe($value);
|
||||
$orderInvIn['cart_order_id'] = $db->mySQLSafe($orderSum['cart_order_id']);
|
||||
}
|
||||
$insert = $db->insert($glob['dbprefix']."CubeCart_order_inv", $orderInvIn);
|
||||
|
||||
/*
|
||||
$useStock = $db->select("SELECT useStockLevel FROM ". $glob['dbprefix'] . "CubeCart_inventory WHERE productId = ".$db->mySQLSafe($orderInv[$i]['productId']));
|
||||
|
||||
// lower stock level IF it is set to change on order creation
|
||||
if($useStock[0]['useStockLevel']==1 && $config['stock_change_time']==2) {
|
||||
$this->stockLevel($orderInv[$i]['quantity'],$orderInv[$i]['productId'],$orderSum['cart_order_id']);
|
||||
}
|
||||
*/
|
||||
if ($orderInv[$i]['digital'] == true) {
|
||||
$digitalProduct['cart_order_id'] = $db->mySQLSafe($orderSum['cart_order_id']);
|
||||
$digitalProduct['customerId'] = $db->mySQLSafe($orderSum['customer_id']);
|
||||
$digitalProduct['expire'] = $db->mySQLSafe(time()+$config['dnLoadExpire']);
|
||||
$digitalProduct['productId'] = $db->mySQLSafe($orderInv[$i]['productId']);
|
||||
$digitalProduct['accessKey'] = $db->mySQLSafe(randomPass());
|
||||
$insert = $db->insert($glob['dbprefix']."CubeCart_Downloads", $digitalProduct);
|
||||
}
|
||||
}
|
||||
if (!$insert) {
|
||||
echo "An error building the order inventory was encountered. Please inform a member of staff.";
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
## Insert order summary
|
||||
if (is_array($orderSum)) {
|
||||
foreach ($orderSum as $key => $value) {
|
||||
$orderSumIn[$key] = $db->mySQLSafe($value);
|
||||
}
|
||||
$orderSumIn['ip'] = $db->mySQLSafe(get_ip_address());
|
||||
$orderSumIn['time'] = $db->mySQLSafe(time());
|
||||
$db->insert($glob['dbprefix']."CubeCart_order_sum", $orderSumIn);
|
||||
}
|
||||
|
||||
## update customers order count + 1
|
||||
$this->customerOrderCount($orderSum['customer_id'], 1);
|
||||
$this->orderSum = $orderSum;
|
||||
if($skipEmail==false) {
|
||||
$this->newOrderEmail();
|
||||
}
|
||||
## set order status to 1, this will reduce stock accordingly
|
||||
$this->orderStatus(1, $orderSum['cart_order_id']);
|
||||
$this->cancelOldOrders();
|
||||
}
|
||||
|
||||
function newOrderEmail($cart_order_id = '') {
|
||||
global $glob, $config, $lang;
|
||||
if (!empty($cart_order_id)) {
|
||||
$this->getOrderSum($cart_order_id);
|
||||
$this->getOrderInv($cart_order_id);
|
||||
}
|
||||
|
||||
if (!class_exists('htmlMimeMail')) {
|
||||
require_once CC_ROOT_DIR.CC_DS."classes".CC_DS."htmlMimeMail".CC_DS."htmlMimeMail.php";
|
||||
}
|
||||
$lang = getLang("email.inc.php");
|
||||
## email to storekeeper
|
||||
if ($config['disable_alert_email'] != true) {
|
||||
$mail = new htmlMimeMail();
|
||||
|
||||
$macroArray = array(
|
||||
"CUSTOMER_NAME" => $this->orderSum['name'],
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"ADMIN_ORDER_URL" => $glob['storeURL']."/".$glob['adminFile']."?_g=orders/orderBuilder&edit=".$this->orderSum['cart_order_id'],
|
||||
"SENDER_ID" => get_ip_address(),
|
||||
);
|
||||
$text = macroSub($lang['email']['admin_pending_order_body'],$macroArray);
|
||||
unset($macroArray);
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($config['masterEmail']);
|
||||
$mail->setFrom($this->orderSum['name'].' <'.$this->orderSum['email'].'>');
|
||||
$mail->setSubject(macroSub($lang['email']['admin_pending_order_subject'],array("ORDER_ID" => $this->orderSum['cart_order_id'])));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->send(array($config['masterEmail']), $config['mailMethod']);
|
||||
}
|
||||
|
||||
## email to customer
|
||||
$mail = new htmlMimeMail();
|
||||
$macroArray = array(
|
||||
"CUSTOMER_NAME" => $this->orderSum['name'],
|
||||
"ORDER_ID" => $this->orderSum['cart_order_id'],
|
||||
"ORDER_URL" => $glob['storeURL']."/index.php?_g=co&_a=viewOrder&cart_order_id=".$this->orderSum['cart_order_id']
|
||||
);
|
||||
|
||||
$text = macroSub($lang['email']['order_acknowledgement_body'],$macroArray);
|
||||
unset($macroArray);
|
||||
$mail->setText($text);
|
||||
$mail->setReturnPath($this->orderSum['email']);
|
||||
$mail->setFrom($config['masterName'].' <'.$config['masterEmail'].'>');
|
||||
$mail->setSubject(macroSub($lang['email']['order_acknowledgement_subject'],array("ORDER_ID" => $this->orderSum['cart_order_id'])));
|
||||
$mail->setHeader('X-Mailer', 'CubeCart Mailer');
|
||||
$mail->send(array($this->orderSum['email']), $config['mailMethod']);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
354
production/classes/cart/shoppingCart.php
Normal file
354
production/classes/cart/shoppingCart.php
Normal file
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| shoppingCart.php
|
||||
| ========================================
|
||||
| The Shopping Cart Class
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
class cart {
|
||||
|
||||
var $cartArray;
|
||||
|
||||
function cartContents($sqlValue) {
|
||||
if (!empty($sqlValue)) {
|
||||
$this->cartArray = unserialize(stripslashes($sqlValue));
|
||||
return $this->cartArray;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function add($productId, $quantity, $options) {
|
||||
|
||||
global $config,$db,$glob;
|
||||
|
||||
// SO: FIX FOR CHECKOUT FLOW
|
||||
/* AL: Removed for 1 step CO
|
||||
$this->setVar(1,"currentStep");
|
||||
$this->setVar(2,"stepLimit");
|
||||
*/
|
||||
// EO: FIX FOR CHECKOUT FLOW
|
||||
|
||||
$productKey = $productId.":".$this->buildOptions($options);
|
||||
if (isset($this->cartArray['conts'][$productKey]['quantity']) && $this->cartArray['conts'][$productKey]['quantity'] > 0) {
|
||||
$this->cartArray['conts'][$productKey]['quantity'] += $quantity;
|
||||
} else {
|
||||
$this->cartArray['conts'][$productKey]['quantity'] = $quantity;
|
||||
}
|
||||
/* stock on add to basket for later version maybe
|
||||
$this->stock($productId,$quantity,"-");
|
||||
*/
|
||||
|
||||
//print_r($this->cartArray);
|
||||
//die;
|
||||
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
|
||||
}
|
||||
|
||||
function addCert($certArray) {
|
||||
|
||||
// SO: FIX FOR CHECKOUT FLOW
|
||||
/* AL: Removed for 1 step CO
|
||||
$this->setVar(1,"currentStep");
|
||||
$this->setVar(2,"stepLimit");
|
||||
*/
|
||||
// EO: FIX FOR CHECKOUT FLOW
|
||||
|
||||
$randCode = 'v'.time().'-'.rand(1000, 9999);
|
||||
$this->cartArray['conts'][$randCode]['custom'] = 1;
|
||||
$this->cartArray['conts'][$randCode]['quantity'] = 1;
|
||||
array_walk($certArray, array(&$this, 'sanitize'));
|
||||
$this->cartArray['conts'][$randCode]['gcInfo'] = $certArray;
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
}
|
||||
|
||||
function sanitize(&$value, $key) {
|
||||
$value = stripslashes(html_entity_decode_utf8($value, ENT_COMPAT, 'UTF-8'));
|
||||
$value = htmlentities(strip_tags($value), ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
function setVar($var, $varName, $arrayName = '',$i = '') {
|
||||
|
||||
## unset old delivery address and add new
|
||||
if (is_array($var)) {
|
||||
foreach ($var as $key => $value) {
|
||||
# $var[$key] = str_replace(array("\'", "'"), "'", stripslashes(strip_tags($value)));
|
||||
$var[$key] = htmlspecialchars(stripslashes(strip_tags($value)), ENT_QUOTES);
|
||||
}
|
||||
} else {
|
||||
# $var = str_replace(array("\'", "'"), "'", stripslashes(strip_tags($var)));
|
||||
$var = htmlspecialchars(stripslashes(strip_tags($var)), ENT_QUOTES);
|
||||
}
|
||||
|
||||
if (empty($arrayName)) {
|
||||
unset($this->cartArray[$varName]);
|
||||
$this->cartArray[$varName] = $var;
|
||||
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
} else {
|
||||
if (isset($this->cartArray[$arrayName][$i][$varName])) {
|
||||
unset($this->cartArray[$arrayName][$i][$varName]);
|
||||
}
|
||||
$this->cartArray[$arrayName][$i][$varName] = $var;
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
}
|
||||
}
|
||||
|
||||
function unsetVar($varName) {
|
||||
unset($this->cartArray[$varName]);
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
}
|
||||
|
||||
function remove($productKey) {
|
||||
global $config, $db, $glob;
|
||||
|
||||
// SO: FIX FOR CHECKOUT FLOW
|
||||
/* AL: Removed for 1 step CO
|
||||
$this->setVar(1,"currentStep");
|
||||
$this->setVar(2,"stepLimit");
|
||||
*/
|
||||
// EO: FIX FOR CHECKOUT FLOW
|
||||
|
||||
$productId = $this->getProductId($productKey);
|
||||
$quantity = $this->cartArray['conts'][$productKey]['quantity'];
|
||||
/* stock on add to basket for later version maybe
|
||||
$this->stock($productId, $quantity,"+");
|
||||
*/
|
||||
unset($this->cartArray['conts'][$productKey]);
|
||||
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
}
|
||||
|
||||
function update($productKey, $quantity) {
|
||||
$quantity = ceil($quantity);
|
||||
$productId = $this->getProductId($productKey);
|
||||
$quantityOld = $this->cartArray['conts'][$productKey]['quantity'];
|
||||
|
||||
/*
|
||||
if ($quantity<$quantityOld) {
|
||||
## put them back
|
||||
$difference = $quantityOld - $quantity;
|
||||
$sign = "+";
|
||||
} else if ($quantity>$quantityOld) {
|
||||
## take some more
|
||||
$difference = $quantity - $quantityOld;
|
||||
$sign = "-";
|
||||
}
|
||||
$this->stock($productId, $difference, $sign);
|
||||
*/
|
||||
|
||||
if ($quantity > 0) {
|
||||
$this->cartArray['conts'][$productKey]['quantity'] = $quantity;
|
||||
} else {
|
||||
unset($this->cartArray['conts'][$productKey]);
|
||||
}
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
}
|
||||
|
||||
function sqlValue() {
|
||||
global $db, $glob;
|
||||
$cartData['basket'] = "'".serialize($this->cartArray)."'";
|
||||
## sync database to array
|
||||
$update = $db->update($glob['dbprefix']."CubeCart_sessions", $cartData, 'sessId='.$db->mySQLSafe($GLOBALS[CC_SESSION_NAME]));
|
||||
return ($update) ? true : false;
|
||||
}
|
||||
|
||||
function noItems() {
|
||||
$total = 0;
|
||||
if (is_array($this->cartArray['conts'])) {
|
||||
foreach ($this->cartArray['conts'] as $key => $value) {
|
||||
$total = $this->cartArray['conts'][$key]['quantity'] + $total;
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
return $total;
|
||||
}
|
||||
|
||||
function buildOptions($options) {
|
||||
if (is_array($options)) {
|
||||
foreach ($options as $key => $value) {
|
||||
if (!empty($value)) {
|
||||
$option[] = strip_tags(stripslashes($value));
|
||||
}
|
||||
}
|
||||
if (!empty($option)) {
|
||||
return implode('|', $option);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
/*
|
||||
$optionStr = '';
|
||||
if (is_array($options)) {
|
||||
$amount = count($options);
|
||||
$i=1;
|
||||
foreach ($options as $value) {
|
||||
$optionStr .= $value;
|
||||
if ($i<$amount) {
|
||||
$optionStr .= "|";
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return $optionStr;
|
||||
|
||||
}
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
function getOptions($productKey) {
|
||||
$options = explode(":", $productKey);
|
||||
return $options[1];
|
||||
}
|
||||
|
||||
function getProductId($productKey) {
|
||||
$options = explode(":", $productKey);
|
||||
return $options[0];
|
||||
}
|
||||
|
||||
/* Maybe for a later version gets v complex
|
||||
function returnStock() {
|
||||
global $db, $glob;
|
||||
if (is_array($this->cartArray['conts'])) {
|
||||
foreach ($this->cartArray['conts'] as $key => $value) {
|
||||
|
||||
$prodId = $this->getProductId($key);
|
||||
|
||||
## put the products back
|
||||
$useStock = $db->select("SELECT useStockLevel FROM ".$glob['dbprefix']."CubeCart_inventory WHERE productId = ".$prodId);
|
||||
|
||||
if($useStock[0]['useStockLevel']==1 && $config['stock_change_time']==0){
|
||||
$query = "UPDATE ".$glob['dbprefix']."CubeCart_inventory SET stock_level = stock_level + ".$this->cartArray['conts'][$key]['quantity']." WHERE productId = ".$prodId;
|
||||
$db->misc($query);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
function emptyCart($keepStock = false) {
|
||||
global $config;
|
||||
|
||||
## lets see if we need to return stock
|
||||
/* For a later release maybe
|
||||
if ($keepStock == false && $config['stock_change_time'] == 1) {
|
||||
$this->returnStock();
|
||||
}
|
||||
*/
|
||||
unset($this->cartArray);
|
||||
return (!$this->sqlValue()) ? $this->error() : $this->cartArray;
|
||||
}
|
||||
|
||||
function addCoupon($code) {
|
||||
global $glob,$config,$db;
|
||||
|
||||
## Look up code
|
||||
$coupon = $db->select("SELECT * FROM ".$glob['dbprefix']."CubeCart_Coupons WHERE code = ".$db->mySQLSafe($code)." AND status = 1");
|
||||
## Validate
|
||||
if ($coupon) {
|
||||
if ($coupon[0]['allowed_uses'] > 0 && $coupon[0]['count'] == $coupon[0]['allowed_uses']) {
|
||||
## used too many times
|
||||
$this->setVar(1, "codeResult");
|
||||
} else if (!empty($coupon[0]['expires']) && (strtotime($coupon[0]['expires']) < time())) {
|
||||
## coupon expired
|
||||
$this->setVar(2, "codeResult");
|
||||
} else {
|
||||
## success
|
||||
$this->setVar(0,"codeResult");
|
||||
$this->setVar($coupon[0]['code'],"code");
|
||||
$this->setVar($coupon[0]['discount_percent'],"discount_percent");
|
||||
$this->setVar($coupon[0]['discount_price'],"discount_price");
|
||||
|
||||
## Will have a cart id if it is a gift certificate therefore if subtotal < gift cert it needs to retan value
|
||||
if(!empty($coupon[0]['cart_order_id'])) {
|
||||
$this->setVar(true,"code_is_purchased");
|
||||
}
|
||||
|
||||
## add count = count + 1
|
||||
$record['count'] = "count + 1";
|
||||
$where = "id = ".$coupon[0]['id'];
|
||||
$update = $db->update($glob['dbprefix']."CubeCart_Coupons", $record, $where);
|
||||
}
|
||||
} else {
|
||||
## coupon not found
|
||||
$this->setVar(3, "codeResult");
|
||||
}
|
||||
return $this->cartArray;
|
||||
}
|
||||
|
||||
function removeCoupon($code) {
|
||||
global $glob, $config, $db;
|
||||
|
||||
if($this->cartArray["code_is_purchased"] == true && $this->cartArray["code_remainder"]>0) {
|
||||
$record['discount_price'] = $db->mySQLSafe($this->cartArray["discount_price"]);
|
||||
} else {
|
||||
## subtract count = count - 1
|
||||
$record['count'] = "count - 1";
|
||||
}
|
||||
|
||||
$where = "code = ".$db->mySQLSafe(base64_decode($code));
|
||||
$update = $db->update($glob['dbprefix']."CubeCart_Coupons", $record, $where);
|
||||
|
||||
$this->unsetVar("codeResult");
|
||||
$this->unsetVar("code");
|
||||
$this->unsetVar("discount_percent");
|
||||
$this->unsetVar("discount_price");
|
||||
$this->unsetVar("code_is_purchased");
|
||||
|
||||
return $this->cartArray;
|
||||
}
|
||||
|
||||
function addByCode($code) {
|
||||
global $glob,$config,$db;
|
||||
$result = $db->select("SELECT productId FROM ".$glob['dbprefix']."CubeCart_inventory WHERE productCode = ".$db->mySQLSafe($code));
|
||||
if ($result) {
|
||||
## check for product options (if so go to view product page)
|
||||
$noOpts = $db->numrows("SELECT product FROM ".$glob['dbprefix']."CubeCart_options_bot WHERE product = ".$db->mySQLSafe($result[0]['productId']));
|
||||
|
||||
if ($noOpts>0) {
|
||||
httpredir("index.php?_a=viewProd&productId=".$result[0]['productId']."¬ice=1");
|
||||
} else {
|
||||
$this->add($result[0]['productId'],1,"");
|
||||
httpredir(currentPage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* maybe for a later version
|
||||
function stock($productId, $quantity, $sign) {
|
||||
global $config,$glob,$db;
|
||||
if ($quantity>0) {
|
||||
## check product is set to use stock control
|
||||
$stock = $db->select("SELECT useStockLevel, stock_level FROM ".$glob['dbprefix']."CubeCart_inventory","productId = ".$db->mySQLSafe($productId));
|
||||
## change stock if product is set to use stock control
|
||||
if($config['stock_change_time']==1 && $stock[0]['useStockLevel']==1) {
|
||||
$query = "UPDATE ".$glob['dbprefix']."CubeCart_inventory SET stock_level = stock_level ".$sign." ".$quantity." WHERE productId = ".$db->mySQLSafe($productId);
|
||||
$update = $db->misc($query);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
function error() {
|
||||
return "<b style='font-family: Arial, Helvetica, sans-serif; color: #0B70CE;'>Cart Error</b><br />\n<span style='font-family: Arial, Helvetica, sans-serif; color: #000000;'>There was an error updating the basket.</span><br />\n";
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
415
production/classes/db/db.php
Normal file
415
production/classes/db/db.php
Normal file
@@ -0,0 +1,415 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| db.php
|
||||
| ========================================
|
||||
| Database Class
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
if (class_exists('db')) {
|
||||
return;
|
||||
}
|
||||
|
||||
class db {
|
||||
|
||||
var $query;
|
||||
var $db;
|
||||
var $queryArray = array();
|
||||
|
||||
function db() {
|
||||
global $glob;
|
||||
|
||||
$this->db = mysql_connect($glob['dbhost'], $glob['dbusername'], $glob['dbpassword']) or die(mysql_error());
|
||||
if (!$this->db) die($this->debug(true));
|
||||
|
||||
$selectdb = mysql_select_db($glob['dbdatabase'], $this->db);
|
||||
if (!$selectdb) die ($this->debug());
|
||||
|
||||
}
|
||||
|
||||
function select($query, $maxRows = 0, $pageNum = 0) {
|
||||
$this->query = $query;
|
||||
$this->queryArray[] = $query;
|
||||
|
||||
## start limit if $maxRows is greater than 0
|
||||
if ($maxRows > 0) {
|
||||
$startRow = $pageNum * $maxRows;
|
||||
$query = sprintf("%s LIMIT %d, %d", $query, $startRow, $maxRows);
|
||||
}
|
||||
$result = mysql_query($query);
|
||||
|
||||
if ($this->error()) die ($this->debug());
|
||||
|
||||
if (mysql_num_rows($result) >= 1) {
|
||||
for ($n=0; $n < mysql_num_rows($result); $n++) {
|
||||
$row = mysql_fetch_assoc($result);
|
||||
$output[$n] = $row;
|
||||
}
|
||||
return $output;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function misc($query, $debug = true) {
|
||||
$this->query = $query;
|
||||
$result = mysql_query($query);
|
||||
if ($this->error() && $debug == true) die ($this->debug());
|
||||
return ($result) ? true : false;
|
||||
}
|
||||
|
||||
function numrows($query) {
|
||||
$this->query = $query;
|
||||
$result = mysql_query($query);
|
||||
return mysql_num_rows($result);
|
||||
}
|
||||
|
||||
function getRows($query) {
|
||||
$this->query = $query;
|
||||
$result = mysql_query($query);
|
||||
$tables = array();
|
||||
while ($row = mysql_fetch_row($result)) {
|
||||
$tables[] = $row;
|
||||
}
|
||||
return $tables;
|
||||
}
|
||||
|
||||
function insert($tablename, $record) {
|
||||
if (!is_array($record)) die($this->debug("array", "Insert", $tablename));
|
||||
|
||||
foreach ($record as $field => $value) {
|
||||
$fields[] = sprintf("`%s`", $field);
|
||||
$values[] = sprintf("%s", $value);
|
||||
}
|
||||
|
||||
$this->query = sprintf("INSERT INTO %s (%s) VALUES (%s);", $tablename, implode(',', $fields), implode(',', $values));
|
||||
mysql_query($this->query);
|
||||
if ($this->error()) die ($this->debug());
|
||||
return ($this->affected() > 0) ? true : false;
|
||||
}
|
||||
|
||||
function update($tablename, $record, $where = '') {
|
||||
if(!is_array($record)) die ($this->debug("array", "Update", $tablename));
|
||||
|
||||
foreach ($record as $field => $value) {
|
||||
$set[] = sprintf("`%s` = %s", $field, $value);
|
||||
}
|
||||
|
||||
if(!empty($where)) {
|
||||
if (is_array($where)) {
|
||||
foreach ($where as $field => $value) {
|
||||
$whereArray[] = sprintf("`%s` = '%s'", $field, $value);
|
||||
}
|
||||
$where = "WHERE ".implode(' AND ', $whereArray);
|
||||
} else {
|
||||
$where = "WHERE ".$where;
|
||||
}
|
||||
}
|
||||
|
||||
$this->query = sprintf("UPDATE %s SET %s %s;", $tablename, implode(',', $set), $where);
|
||||
mysql_query($this->query);
|
||||
if ($this->error()) die ($this->debug());
|
||||
return ($this->affected() > 0) ? true : false;
|
||||
|
||||
}
|
||||
|
||||
function categoryNos($cat_id, $sign, $amount = 1) {
|
||||
global $glob;
|
||||
if ($cat_id > 0) {
|
||||
do {
|
||||
$record['noProducts'] = " noProducts ".$sign.$amount;
|
||||
$where = "cat_id = ".$cat_id;
|
||||
$this->update($glob['dbprefix']."CubeCart_category", $record, $where, "");
|
||||
$query = "SELECT cat_father_id FROM ".$glob['dbprefix']."CubeCart_category WHERE cat_id = ".$cat_id;
|
||||
$cfi = $this->select($query);
|
||||
$cat_id = $cfi['0']['cat_father_id'];
|
||||
}
|
||||
while ($cat_id > 0);
|
||||
}
|
||||
}
|
||||
|
||||
function delete($tablename, $where, $limit = '') {
|
||||
|
||||
$query = "DELETE from ".$tablename." WHERE ".$where;
|
||||
if (!empty($limit)) $query .= " LIMIT " . $limit;
|
||||
|
||||
$this->query = $query;
|
||||
mysql_query($query);
|
||||
|
||||
if ($this->error()) die ($this->debug());
|
||||
return ($this->affected() > 0) ? true : false;
|
||||
}
|
||||
|
||||
function truncate($tablename) {
|
||||
$this->query = sprintf('TRUNCATE %s;', $tablename);
|
||||
mysql_query($this->query);
|
||||
if ($this->error()) die ($this->debug());
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
## Clean SQL Variables (Security Function)
|
||||
/*********************************************/
|
||||
|
||||
function mySQLSafe($value, $quote = "'") {
|
||||
|
||||
## Stripslashes
|
||||
if (get_magic_quotes_gpc()) {
|
||||
$value = stripslashes($value);
|
||||
}
|
||||
## Strip quotes if already in
|
||||
$value = str_replace(array("\'","'"), "'", $value);
|
||||
|
||||
## Quote value
|
||||
if (function_exists('mysql_real_escape_string')) {
|
||||
$value = mysql_real_escape_string($value, $this->db);
|
||||
} else {
|
||||
$value = mysql_escape_string($value, $this->db);
|
||||
}
|
||||
$value = $quote . trim($value) . $quote;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
function sqldumptable($table, $drop, $structure, $data) {
|
||||
$tabledump = '';
|
||||
if ($drop == true && $structure == true) {
|
||||
$tabledump .= "-- --------------------------------------------------------\n\nDROP TABLE IF EXISTS ".$table.";\n\n";
|
||||
}
|
||||
if ($structure == true) {
|
||||
$tabledump .= "-- --------------------------------------------------------\n\n-- \n-- Table structure for table `".$table."`\n--\n\nCREATE TABLE ".$table." (\n";
|
||||
$firstfield = true;
|
||||
$query = "SHOW FIELDS FROM ".$table;
|
||||
$this->query = $query;
|
||||
## get columns and spec
|
||||
$fields = mysql_query($query);
|
||||
while ($field = mysql_fetch_array($fields)) {
|
||||
if (!$firstfield) {
|
||||
$tabledump .= ",\n";
|
||||
} else {
|
||||
$firstfield = 0;
|
||||
}
|
||||
$tabledump .= " ".$field['Field']." ".$field['Type'];
|
||||
if (!empty($field["Default"])) $tabledump .= " DEFAULT '".$field['Default']."'";
|
||||
if ($field['Null'] != "YES") $tabledump .= " NOT NULL";
|
||||
if (!empty($field['Extra'])) $tabledump .= " ".$field['Extra'];
|
||||
}
|
||||
mysql_free_result($fields);
|
||||
|
||||
## get keys list
|
||||
$keys = mysql_query("SHOW KEYS FROM ".$table);
|
||||
while ($key = mysql_fetch_array($keys)) {
|
||||
$kname = $key['Key_name'];
|
||||
if ($kname != "PRIMARY" and $key['Non_unique'] == false) $kname="UNIQUE|".$kname;
|
||||
if (!is_array($index[$kname])) $index[$kname] = array();
|
||||
$index[$kname][] = $key['Column_name'];
|
||||
}
|
||||
mysql_free_result($keys);
|
||||
|
||||
## get each key info
|
||||
while (list($kname, $columns) = @each($index)) {
|
||||
$tabledump .= ",\n";
|
||||
$colnames=implode($columns,",");
|
||||
|
||||
if ($kname == "PRIMARY") {
|
||||
// do primary key
|
||||
$tabledump .= " PRIMARY KEY (".$colnames.")";
|
||||
} else {
|
||||
// do standard key
|
||||
if (substr($kname,0,6) == "UNIQUE") {
|
||||
// key is unique
|
||||
$kname=substr($kname,7);
|
||||
}
|
||||
$tabledump .= " KEY ".$kname." (".$colnames.")";
|
||||
}
|
||||
}
|
||||
$tabledump .= "\n);\n\n";
|
||||
}
|
||||
if ($data == true) {
|
||||
## get data
|
||||
$rows = mysql_query("SELECT * FROM ".$table);
|
||||
$numfields = mysql_num_fields($rows);
|
||||
if ($numfields > 0) $tabledump .="--\n-- Dumping data for table `".$table."`\n--\n\n";
|
||||
while ($row = mysql_fetch_array($rows)) {
|
||||
$tabledump .= "INSERT INTO ".$table." VALUES(";
|
||||
$fieldcounter = -1;
|
||||
$firstfield = true;
|
||||
|
||||
## get each field's data
|
||||
while (++$fieldcounter<$numfields) {
|
||||
|
||||
if (!$firstfield) {
|
||||
$tabledump.=', ';
|
||||
} else {
|
||||
$firstfield = 0;
|
||||
}
|
||||
if (!isset($row[$fieldcounter])) {
|
||||
$tabledump .= "NULL";
|
||||
} else {
|
||||
$tabledump .= "'".mysql_escape_string($row[$fieldcounter])."'";
|
||||
}
|
||||
}
|
||||
$tabledump .= ");\n";
|
||||
}
|
||||
mysql_free_result($rows);
|
||||
}
|
||||
return $tabledump;
|
||||
}
|
||||
|
||||
// This function has been built to prevent brute force attacks
|
||||
function blocker($user, $level, $time, $login, $loc) {
|
||||
global $glob;
|
||||
$expireTime = time()-($time*5);
|
||||
$this->delete($glob['dbprefix']."CubeCart_blocker","lastTime<".$expireTime);
|
||||
$query = "SELECT * FROM ".$glob['dbprefix']."CubeCart_blocker WHERE `browser` = ".$this->mySQLSafe($_SERVER['HTTP_USER_AGENT'])." AND `ip` = ".$this->mySQLSafe(get_ip_address())." AND `loc`= '".$loc."'";
|
||||
$blackList = $this->select($query);
|
||||
|
||||
if ($blackList && $blackList[0]['blockTime']>time()) {
|
||||
// do nothing the user is still banned
|
||||
return true;
|
||||
} else if ($blackList && $blackList[0]['blockTime']>0 && $blackList[0]['blockTime']<time() && $blackList[0]['blockLevel'] == $level) {
|
||||
## delete the db row as user is no longer banned
|
||||
$this->delete($glob['dbprefix']."CubeCart_blocker","id=".$blackList[0]['id']);
|
||||
return false;
|
||||
} else if ($blackList && !$login && $blackList[0]['blockTime'] == false) {
|
||||
|
||||
$newdata['lastTime'] = time();
|
||||
## If last attempt was more than the time limit ago we need to set the level to one
|
||||
## This stops a consecutive fail weeks later blocking on first attempt
|
||||
$timeAgo = time() - $time;
|
||||
$newdata['blockLevel'] = ($blackList[0]['lastTime']<$timeAgo) ? 1 : $blackList[0]['blockLevel']+1;
|
||||
|
||||
if ($newdata['blockLevel']==$level) {
|
||||
$newdata['blockTime'] = time() + $time;
|
||||
$this->update($glob['dbprefix']."CubeCart_blocker", $newdata, "id=".$blackList[0]['id'],$stripQuotes="");
|
||||
return true;
|
||||
} else {
|
||||
$newdata['blockTime'] = 0;
|
||||
$this->update($glob['dbprefix']."CubeCart_blocker", $newdata, "id=".$blackList[0]['id'],$stripQuotes="");
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (!$blackList && !$login) {
|
||||
## insert
|
||||
$newdata['blockLevel'] = 1;
|
||||
$newdata['blockTime'] = 0;
|
||||
$newdata['browser'] = $this->mySQLSafe($_SERVER['HTTP_USER_AGENT']);
|
||||
$newdata['ip'] = $this->mySQLSafe(get_ip_address());
|
||||
$newdata['username'] = $this->mySQLSafe($user);
|
||||
$newdata['loc'] = "'".$loc."'";
|
||||
$newdata['lastTime'] = time();
|
||||
$this->insert($glob['dbprefix']."CubeCart_blocker", $newdata);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function debug($type = '', $action = '', $tablename = '') {
|
||||
switch ($type) {
|
||||
case "connect":
|
||||
$message = "MySQL Error Occured";
|
||||
$result = mysql_errno() . ": " . mysql_error();
|
||||
$query = "";
|
||||
$output = "Could not connect to the database. Be sure to check that your database connection settings are correct and that the MySQL server in running.";
|
||||
break;
|
||||
case "array":
|
||||
$message = $action." Error Occured";
|
||||
$result = "Could not update ".$tablename." as variable supplied must be an array.";
|
||||
$query = "";
|
||||
$output = "Sorry an error has occured accessing the database. Be sure to check that your database connection settings are correct and that the MySQL server in running.";
|
||||
break;
|
||||
default:
|
||||
if (mysql_errno($this->db)) {
|
||||
$message = "MySQL Error Occured";
|
||||
$result = mysql_errno($this->db) . ": " . mysql_error($this->db);
|
||||
$output = "Sorry an error has occured accessing the database. Be sure to check that your database connection settings are correct and that the MySQL server in running.";
|
||||
} else {
|
||||
$message = "MySQL Query Executed Succesfully.";
|
||||
$result = mysql_affected_rows($this->db) . " Rows Affected";
|
||||
$output = "view logs for details";
|
||||
}
|
||||
$linebreaks = array("\n", "\r");
|
||||
$query = (!empty($this->query)) ? "<strong>SQL:</strong><br /> " . str_replace($linebreaks, " ", $this->query) : '';
|
||||
}
|
||||
$output = "<h1 style='font-family: Arial, Helvetica, sans-serif; color: #0B70CE;'>".$message."</h1>\n<p style='font-family: Arial, Helvetica, sans-serif; color: #000000;'><strong>Error Message:</strong><br/>".$result."</p>\n";
|
||||
|
||||
if (!empty($query)) $output .= "<p style='font-family: Courier New, Courier, mono; border: 1px dashed #666666; padding: 10px; color: #000000;'>".$query."</p>\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
function getFulltextIndex($table = 'inventory', $prefix = false) {
|
||||
global $glob;
|
||||
|
||||
if (is_array($table)) {
|
||||
foreach ($table as $name) {
|
||||
$fieldlist[$name] = $this->getFulltextIndex($name);
|
||||
}
|
||||
} else {
|
||||
$sql = sprintf("SHOW INDEX FROM %sCubeCart_%s;", $glob['dbprefix'], $table);
|
||||
$query = mysql_query($sql);
|
||||
while($index = mysql_fetch_assoc($query)) {
|
||||
if ($index['Index_type'] == 'FULLTEXT' && $index['Key_name'] == 'fulltext') {
|
||||
if ($prefix) {
|
||||
$fieldlist[] = sprintf('%s.%s', $prefix, $index['Column_name']);
|
||||
} else {
|
||||
$fieldlist[] = $index['Column_name'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $fieldlist;
|
||||
}
|
||||
|
||||
function serverVersion() {
|
||||
return mysql_get_server_info($this->db);
|
||||
}
|
||||
|
||||
function error() {
|
||||
return (mysql_errno($this->db))? true : false;
|
||||
}
|
||||
function errorstring() {
|
||||
return mysql_error($this->db);
|
||||
}
|
||||
|
||||
function insertid() {
|
||||
return mysql_insert_id($this->db);
|
||||
}
|
||||
|
||||
function affected() {
|
||||
return mysql_affected_rows($this->db);
|
||||
}
|
||||
|
||||
function close() {
|
||||
mysql_close($this->db);
|
||||
}
|
||||
|
||||
## New for 4.1.x
|
||||
function getFields($table) {
|
||||
global $glob;
|
||||
$list = mysql_list_fields($glob['dbdatabase'], $table, $this->db);
|
||||
$cols = mysql_num_fields($list);
|
||||
for ($i = 0; $i < $cols; $i++) {
|
||||
$array = (array) mysql_fetch_field($list, $i);
|
||||
$return[$array['name']] = $array['name'];
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
?>
|
||||
BIN
production/classes/gd/fonts/anonymous.gdf
Normal file
BIN
production/classes/gd/fonts/anonymous.gdf
Normal file
Binary file not shown.
243
production/classes/gd/gd.inc.php
Normal file
243
production/classes/gd/gd.inc.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| gd.inc.php
|
||||
| ========================================
|
||||
| GD Class
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
class gd {
|
||||
|
||||
var $config;
|
||||
var $glob;
|
||||
var $img;
|
||||
var $rootpath;
|
||||
|
||||
function gd($imgfile = '', $width = 0, $height = 0) {
|
||||
global $config, $glob, $rootpath;
|
||||
|
||||
$this->config = $config;
|
||||
$this->glob = $glob;
|
||||
$this->rootpath = $rootpath;
|
||||
|
||||
|
||||
|
||||
|
||||
## Detect image format
|
||||
$this->img["format"] = ereg_replace(".*\.(.*)$", "\\1", $imgfile);
|
||||
$this->img["format"] = strtoupper($this->img["format"]);
|
||||
|
||||
if ($config['gdversion']) {
|
||||
|
||||
if (!file_exists($imgfile)) {
|
||||
echo 'no file at '.$imgfile;
|
||||
exit;
|
||||
}
|
||||
|
||||
$img = getimagesize($imgfile);
|
||||
$this->img['format'] = $img[2];
|
||||
|
||||
switch($img[2]) {
|
||||
case IMAGETYPE_JPEG:
|
||||
$this->img["src"] = imagecreatefromjpeg($imgfile);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
$this->img["src"] = imagecreatefrompng($imgfile);
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
$this->img["src"] = imagecreatefromgif($imgfile);
|
||||
break;
|
||||
default:
|
||||
echo "Filetype unsupported!";
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($width>0 && $height>0) {
|
||||
$this->img["width"] = $width;
|
||||
$this->img["height"] = $height;
|
||||
} else {
|
||||
@$this->img["width"] = imagesx($this->img["src"]);
|
||||
@$this->img["height"] = imagesy($this->img["src"]);
|
||||
}
|
||||
|
||||
## Default JPEG quality
|
||||
$this->img["quality"] = $this->config['gdquality'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function size_custom($width = 100, $height = 100) {
|
||||
$this->img["width_thumb"] = $width;
|
||||
$this->img["height_thumb"] = $height;
|
||||
}
|
||||
|
||||
function size_width($size = 100) {
|
||||
$this->img["width_thumb"] = $size;
|
||||
@$this->img["height_thumb"] = ($this->img["width_thumb"]/$this->img["width"])*$this->img["height"];
|
||||
}
|
||||
|
||||
function size_height($size = 100) {
|
||||
$this->img["height_thumb"] = $size;
|
||||
@$this->img["width_thumb"] = ($this->img["height_thumb"]/$this->img["height"])*$this->img["width"];
|
||||
}
|
||||
|
||||
function size_auto($size = 100) {
|
||||
// size automatically
|
||||
if ($this->img["width"] >= $this->img["height"]) {
|
||||
$this->img["width_thumb"] = $size;
|
||||
@$this->img["height_thumb"] = ($this->img["width_thumb"]/$this->img["width"])*$this->img["height"];
|
||||
} else {
|
||||
$this->img["height_thumb"] = $size;
|
||||
@$this->img["width_thumb"] = ($this->img["height_thumb"]/$this->img["height"])*$this->img["width"];
|
||||
}
|
||||
}
|
||||
|
||||
function jpeg_quality($quality = 80) {
|
||||
$this->img["quality"]=$quality;
|
||||
}
|
||||
|
||||
|
||||
function randImage($rand) {
|
||||
## Generate a CAPTCHA image
|
||||
if (!defined('CC_ROOT_DIR')) define('CC_ROOT_DIR', $this->rootPath);
|
||||
|
||||
## Define some default colours
|
||||
$bgColor = imagecolorallocate ($this->img["src"], 255, 255, 255);
|
||||
$textColor = imagecolorallocate ($this->img["src"], 0, 0, 0);
|
||||
$lineColor = imagecolorallocate ($this->img["src"], 215, 215, 215);
|
||||
|
||||
## Add Random polygons
|
||||
$noise_x = $this->img["width"] - 5;
|
||||
$noise_y = $this->img["height"] - 2;
|
||||
for ($i=0; $i<3; $i++) {
|
||||
$polyCoords = array(
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y),
|
||||
rand(5, $noise_x), rand(5, $noise_y)
|
||||
);
|
||||
$randomcolor = imagecolorallocate($this->img["src"], rand(150, 255), rand(150, 255),rand(150, 255));
|
||||
imagefilledpolygon($this->img["src"], $polyCoords, 6, $randomcolor);
|
||||
}
|
||||
|
||||
## write the random chars
|
||||
$font = imageloadfont(CC_ROOT_DIR.CC_DS."classes".CC_DS."gd".CC_DS."fonts".CC_DS."anonymous.gdf");
|
||||
imagestring($this->img["src"], $font, 3, 0, $rand, $textColor);
|
||||
|
||||
## Add Random noise
|
||||
for ($i = 0; $i < 25; $i++) {
|
||||
$rx1 = rand(0,$this->img["width"]);
|
||||
$rx2 = rand(0,$this->img["width"]);
|
||||
$ry1 = rand(0,$this->img["height"]);
|
||||
$ry2 = rand(0,$this->img["height"]);
|
||||
$rcVal = rand(0,255);
|
||||
$rc1 = imagecolorallocate($this->img["src"],rand(0,255),rand(0,255),rand(100,255));
|
||||
imageline ($this->img["src"], $rx1, $ry1, $rx2, $ry2, $rc1);
|
||||
}
|
||||
$this->show(1);
|
||||
}
|
||||
|
||||
function show($noThumb = false) {
|
||||
global $config;
|
||||
|
||||
@header("Expires: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
@header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
|
||||
@header("Cache-Control: no-store, no-cache, must-revalidate");
|
||||
@header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
@header("Pragma: no-cache");
|
||||
@header("Content-Type: ".image_type_to_mime_type($this->img["format"]));
|
||||
|
||||
|
||||
if ($noThumb) {
|
||||
$this->img["width_thumb"] = $this->img["width"];
|
||||
$this->img["height_thumb"] = $this->img["height"];
|
||||
}
|
||||
|
||||
if ($config['gdversion'] >= 2) {
|
||||
$this->img["des"] = imagecreatetruecolor($this->img["width_thumb"],$this->img["height_thumb"]);
|
||||
@imagecopyresampled ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["width_thumb"],$this->img["height_thumb"], $this->img["width"], $this->img["height"]);
|
||||
} else if ($config['gdversion'] == 1) {
|
||||
$this->img["des"] = imagecreate($this->img["width_thumb"],$this->img["height_thumb"]);
|
||||
@imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["width_thumb"],$this->img["height_thumb"], $this->img["width"], $this->img["height"]);
|
||||
}
|
||||
|
||||
if ($config['gdversion']>0) {
|
||||
@touch($this->img["des"]);
|
||||
|
||||
switch($this->img['format']) {
|
||||
case IMAGETYPE_JPEG:
|
||||
imagejpeg($this->img["des"], '', $this->img["quality"]);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
imagepng($this->img["des"]);
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
imagegif($this->img["des"]);
|
||||
break;
|
||||
}
|
||||
imagedestroy($this->img["des"]);
|
||||
}
|
||||
}
|
||||
|
||||
function save($save = '', $noThumb = false) {
|
||||
global $config;
|
||||
|
||||
if ($noThumb) {
|
||||
$this->img["width_thumb"] = $this->img["width"];
|
||||
$this->img["height_thumb"] = $this->img["height"];
|
||||
}
|
||||
|
||||
if ($config['gdversion'] >= 2) {
|
||||
$this->img["des"] = imagecreatetruecolor($this->img["width_thumb"],$this->img["height_thumb"]);
|
||||
@imagecopyresampled ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["width_thumb"], $this->img["height_thumb"], $this->img["width"], $this->img["height"]);
|
||||
|
||||
} else if ($config['gdversion'] == 1) {
|
||||
$this->img["des"] = imagecreate($this->img["width_thumb"],$this->img["height_thumb"]);
|
||||
@imagecopyresized ($this->img["des"], $this->img["src"], 0, 0, 0, 0, $this->img["width_thumb"], $this->img["height_thumb"], $this->img["width"], $this->img["height"]);
|
||||
}
|
||||
|
||||
if ($config['gdversion']>0) {
|
||||
switch($this->img['format']) {
|
||||
case IMAGETYPE_JPEG:
|
||||
imagejpeg($this->img["des"], $save, $this->img["quality"]);
|
||||
break;
|
||||
case IMAGETYPE_PNG:
|
||||
imagepng($this->img["des"], $save);
|
||||
break;
|
||||
case IMAGETYPE_GIF:
|
||||
imagegif($this->img["des"], $save);
|
||||
break;
|
||||
}
|
||||
imagedestroy($this->img["des"]);
|
||||
@chmod($this->img["des"], 0644);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
4389
production/classes/gd/phplot.php
Normal file
4389
production/classes/gd/phplot.php
Normal file
File diff suppressed because it is too large
Load Diff
876
production/classes/htmlMimeMail/RFC822.php
Normal file
876
production/classes/htmlMimeMail/RFC822.php
Normal file
@@ -0,0 +1,876 @@
|
||||
<?php
|
||||
/**
|
||||
* RFC 822 Email address list validation Utility
|
||||
*
|
||||
* What is it?
|
||||
*
|
||||
* This class will take an address string, and parse it into it's consituent
|
||||
* parts, be that either addresses, groups, or combinations. Nested groups
|
||||
* are not supported. The structure it returns is pretty straight forward,
|
||||
* and is similar to that provided by the imap_rfc822_parse_adrlist(). Use
|
||||
* print_r() to view the structure.
|
||||
*
|
||||
* How do I use it?
|
||||
*
|
||||
* $address_string = 'My Group: "Richard Heyes" <richard@localhost> (A comment), ted@example.com (Ted Bloggs), Barney;';
|
||||
* $structure = Mail_RFC822::parseAddressList($address_string, 'example.com', TRUE)
|
||||
* print_r($structure);
|
||||
*
|
||||
* @author Richard Heyes <richard@phpguru.org>
|
||||
* @author Chuck Hagenbuch <chuck@horde.org>
|
||||
* @version $Revision: 1.1 $
|
||||
* @package Mail
|
||||
This version Modded by Alistair Brookbanks - Devellion Limited
|
||||
*/
|
||||
|
||||
class Mail_RFC822
|
||||
{
|
||||
/**
|
||||
* The address being parsed by the RFC822 object.
|
||||
* @var string $address
|
||||
*/
|
||||
var $address = '';
|
||||
|
||||
/**
|
||||
* The default domain to use for unqualified addresses.
|
||||
* @var string $default_domain
|
||||
*/
|
||||
var $default_domain = 'localhost';
|
||||
|
||||
/**
|
||||
* Should we return a nested array showing groups, or flatten everything?
|
||||
* @var boolean $nestGroups
|
||||
*/
|
||||
var $nestGroups = true;
|
||||
|
||||
/**
|
||||
* Whether or not to validate atoms for non-ascii characters.
|
||||
* @var boolean $validate
|
||||
*/
|
||||
var $validate = true;
|
||||
|
||||
/**
|
||||
* The array of raw addresses built up as we parse.
|
||||
* @var array $addresses
|
||||
*/
|
||||
var $addresses = array();
|
||||
|
||||
/**
|
||||
* The final array of parsed address information that we build up.
|
||||
* @var array $structure
|
||||
*/
|
||||
var $structure = array();
|
||||
|
||||
/**
|
||||
* The current error message, if any.
|
||||
* @var string $error
|
||||
*/
|
||||
var $error = null;
|
||||
|
||||
/**
|
||||
* An internal counter/pointer.
|
||||
* @var integer $index
|
||||
*/
|
||||
var $index = null;
|
||||
|
||||
/**
|
||||
* The number of groups that have been found in the address list.
|
||||
* @var integer $num_groups
|
||||
* @access public
|
||||
*/
|
||||
var $num_groups = 0;
|
||||
|
||||
/**
|
||||
* A variable so that we can tell whether or not we're inside a
|
||||
* Mail_RFC822 object.
|
||||
* @var boolean $mailRFC822
|
||||
*/
|
||||
var $mailRFC822 = true;
|
||||
|
||||
/**
|
||||
* A limit after which processing stops
|
||||
* @var int $limit
|
||||
*/
|
||||
var $limit = null;
|
||||
|
||||
|
||||
/**
|
||||
* Sets up the object. The address must either be set here or when
|
||||
* calling parseAddressList(). One or the other.
|
||||
*
|
||||
* @access public
|
||||
* @param string $address The address(es) to validate.
|
||||
* @param string $default_domain Default domain/host etc. If not supplied, will be set to localhost.
|
||||
* @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
|
||||
* @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
|
||||
*
|
||||
* @return object Mail_RFC822 A new Mail_RFC822 object.
|
||||
*/
|
||||
function Mail_RFC822($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
|
||||
{
|
||||
if (isset($address)) $this->address = $address;
|
||||
if (isset($default_domain)) $this->default_domain = $default_domain;
|
||||
if (isset($nest_groups)) $this->nestGroups = $nest_groups;
|
||||
if (isset($validate)) $this->validate = $validate;
|
||||
if (isset($limit)) $this->limit = $limit;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Starts the whole process. The address must either be set here
|
||||
* or when creating the object. One or the other.
|
||||
*
|
||||
* @access public
|
||||
* @param string $address The address(es) to validate.
|
||||
* @param string $default_domain Default domain/host etc.
|
||||
* @param boolean $nest_groups Whether to return the structure with groups nested for easier viewing.
|
||||
* @param boolean $validate Whether to validate atoms. Turn this off if you need to run addresses through before encoding the personal names, for instance.
|
||||
*
|
||||
* @return array A structured array of addresses.
|
||||
*/
|
||||
function parseAddressList($address = null, $default_domain = null, $nest_groups = null, $validate = null, $limit = null)
|
||||
{
|
||||
|
||||
if (!isset($this->mailRFC822)) {
|
||||
$obj = new Mail_RFC822($address, $default_domain, $nest_groups, $validate, $limit);
|
||||
return $obj->parseAddressList();
|
||||
}
|
||||
|
||||
if (isset($address)) $this->address = $address;
|
||||
if (isset($default_domain)) $this->default_domain = $default_domain;
|
||||
if (isset($nest_groups)) $this->nestGroups = $nest_groups;
|
||||
if (isset($validate)) $this->validate = $validate;
|
||||
if (isset($limit)) $this->limit = $limit;
|
||||
|
||||
$this->structure = array();
|
||||
$this->addresses = array();
|
||||
$this->error = null;
|
||||
$this->index = null;
|
||||
|
||||
while ($this->address = $this->_splitAddresses($this->address)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($this->address === false || isset($this->error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reset timer since large amounts of addresses can take a long time to
|
||||
// get here
|
||||
// *Edit by Brooky* Off if safemode is on because it chucks an error.
|
||||
if(@ini_get('safe_mode')==FALSE){
|
||||
set_time_limit(30);
|
||||
}
|
||||
|
||||
// Loop through all the addresses
|
||||
for ($i = 0; $i < count($this->addresses); $i++){
|
||||
|
||||
if (($return = $this->_validateAddress($this->addresses[$i])) === false
|
||||
|| isset($this->error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->nestGroups) {
|
||||
$this->structure = array_merge($this->structure, $return);
|
||||
} else {
|
||||
$this->structure[] = $return;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Splits an address into seperate addresses.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The addresses to split.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _splitAddresses($address)
|
||||
{
|
||||
|
||||
if (!empty($this->limit) AND count($this->addresses) == $this->limit) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($this->_isGroup($address) && !isset($this->error)) {
|
||||
$split_char = ';';
|
||||
$is_group = true;
|
||||
} elseif (!isset($this->error)) {
|
||||
$split_char = ',';
|
||||
$is_group = false;
|
||||
} elseif (isset($this->error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Split the string based on the above ten or so lines.
|
||||
$parts = explode($split_char, $address);
|
||||
$string = $this->_splitCheck($parts, $split_char);
|
||||
|
||||
// If a group...
|
||||
if ($is_group) {
|
||||
// If $string does not contain a colon outside of
|
||||
// brackets/quotes etc then something's fubar.
|
||||
|
||||
// First check there's a colon at all:
|
||||
if (strpos($string, ':') === false) {
|
||||
$this->error = 'Invalid address: ' . $string;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now check it's outside of brackets/quotes:
|
||||
if (!$this->_splitCheck(explode(':', $string), ':'))
|
||||
return false;
|
||||
|
||||
// We must have a group at this point, so increase the counter:
|
||||
$this->num_groups++;
|
||||
}
|
||||
|
||||
// $string now contains the first full address/group.
|
||||
// Add to the addresses array.
|
||||
$this->addresses[] = array(
|
||||
'address' => trim($string),
|
||||
'group' => $is_group
|
||||
);
|
||||
|
||||
// Remove the now stored address from the initial line, the +1
|
||||
// is to account for the explode character.
|
||||
$address = trim(substr($address, strlen($string) + 1));
|
||||
|
||||
// If the next char is a comma and this was a group, then
|
||||
// there are more addresses, otherwise, if there are any more
|
||||
// chars, then there is another address.
|
||||
if ($is_group && substr($address, 0, 1) == ','){
|
||||
$address = trim(substr($address, 1));
|
||||
return $address;
|
||||
|
||||
} elseif (strlen($address) > 0) {
|
||||
return $address;
|
||||
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
// If you got here then something's off
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for a group at the start of the string.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The address to check.
|
||||
* @return boolean Whether or not there is a group at the start of the string.
|
||||
*/
|
||||
function _isGroup($address)
|
||||
{
|
||||
// First comma not in quotes, angles or escaped:
|
||||
$parts = explode(',', $address);
|
||||
$string = $this->_splitCheck($parts, ',');
|
||||
|
||||
// Now we have the first address, we can reliably check for a
|
||||
// group by searching for a colon that's not escaped or in
|
||||
// quotes or angle brackets.
|
||||
if (count($parts = explode(':', $string)) > 1) {
|
||||
$string2 = $this->_splitCheck($parts, ':');
|
||||
return ($string2 !== $string);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A common function that will check an exploded string.
|
||||
*
|
||||
* @access private
|
||||
* @param array $parts The exloded string.
|
||||
* @param string $char The char that was exploded on.
|
||||
* @return mixed False if the string contains unclosed quotes/brackets, or the string on success.
|
||||
*/
|
||||
function _splitCheck($parts, $char)
|
||||
{
|
||||
$string = $parts[0];
|
||||
|
||||
for ($i = 0; $i < count($parts); $i++) {
|
||||
if ($this->_hasUnclosedQuotes($string)
|
||||
|| $this->_hasUnclosedBrackets($string, '<>')
|
||||
|| $this->_hasUnclosedBrackets($string, '[]')
|
||||
|| $this->_hasUnclosedBrackets($string, '()')
|
||||
|| substr($string, -1) == '\\') {
|
||||
if (isset($parts[$i + 1])) {
|
||||
$string = $string . $char . $parts[$i + 1];
|
||||
} else {
|
||||
$this->error = 'Invalid address spec. Unclosed bracket or quotes';
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$this->index = $i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string has an unclosed quotes or not.
|
||||
*
|
||||
* @access private
|
||||
* @param string $string The string to check.
|
||||
* @return boolean True if there are unclosed quotes inside the string, false otherwise.
|
||||
*/
|
||||
function _hasUnclosedQuotes($string)
|
||||
{
|
||||
$string = explode('"', $string);
|
||||
$string_cnt = count($string);
|
||||
|
||||
for ($i = 0; $i < (count($string) - 1); $i++)
|
||||
if (substr($string[$i], -1) == '\\')
|
||||
$string_cnt--;
|
||||
|
||||
return ($string_cnt % 2 === 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a string has an unclosed brackets or not. IMPORTANT:
|
||||
* This function handles both angle brackets and square brackets;
|
||||
*
|
||||
* @access private
|
||||
* @param string $string The string to check.
|
||||
* @param string $chars The characters to check for.
|
||||
* @return boolean True if there are unclosed brackets inside the string, false otherwise.
|
||||
*/
|
||||
function _hasUnclosedBrackets($string, $chars)
|
||||
{
|
||||
$num_angle_start = substr_count($string, $chars[0]);
|
||||
$num_angle_end = substr_count($string, $chars[1]);
|
||||
|
||||
$this->_hasUnclosedBracketsSub($string, $num_angle_start, $chars[0]);
|
||||
$this->_hasUnclosedBracketsSub($string, $num_angle_end, $chars[1]);
|
||||
|
||||
if ($num_angle_start < $num_angle_end) {
|
||||
$this->error = 'Invalid address spec. Unmatched quote or bracket (' . $chars . ')';
|
||||
return false;
|
||||
} else {
|
||||
return ($num_angle_start > $num_angle_end);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sub function that is used only by hasUnclosedBrackets().
|
||||
*
|
||||
* @access private
|
||||
* @param string $string The string to check.
|
||||
* @param integer &$num The number of occurences.
|
||||
* @param string $char The character to count.
|
||||
* @return integer The number of occurences of $char in $string, adjusted for backslashes.
|
||||
*/
|
||||
function _hasUnclosedBracketsSub($string, &$num, $char)
|
||||
{
|
||||
$parts = explode($char, $string);
|
||||
for ($i = 0; $i < count($parts); $i++){
|
||||
if (substr($parts[$i], -1) == '\\' || $this->_hasUnclosedQuotes($parts[$i]))
|
||||
$num--;
|
||||
if (isset($parts[$i + 1]))
|
||||
$parts[$i + 1] = $parts[$i] . $char . $parts[$i + 1];
|
||||
}
|
||||
|
||||
return $num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to begin checking the address.
|
||||
*
|
||||
* @access private
|
||||
* @param string $address The address to validate.
|
||||
* @return mixed False on failure, or a structured array of address information on success.
|
||||
*/
|
||||
function _validateAddress($address)
|
||||
{
|
||||
$is_group = false;
|
||||
|
||||
if ($address['group']) {
|
||||
$is_group = true;
|
||||
|
||||
// Get the group part of the name
|
||||
$parts = explode(':', $address['address']);
|
||||
$groupname = $this->_splitCheck($parts, ':');
|
||||
$structure = array();
|
||||
|
||||
// And validate the group part of the name.
|
||||
if (!$this->_validatePhrase($groupname)){
|
||||
$this->error = 'Group name did not validate.';
|
||||
return false;
|
||||
} else {
|
||||
// Don't include groups if we are not nesting
|
||||
// them. This avoids returning invalid addresses.
|
||||
if ($this->nestGroups) {
|
||||
$structure = new stdClass;
|
||||
$structure->groupname = $groupname;
|
||||
}
|
||||
}
|
||||
|
||||
$address['address'] = ltrim(substr($address['address'], strlen($groupname . ':')));
|
||||
}
|
||||
|
||||
// If a group then split on comma and put into an array.
|
||||
// Otherwise, Just put the whole address in an array.
|
||||
if ($is_group) {
|
||||
while (strlen($address['address']) > 0) {
|
||||
$parts = explode(',', $address['address']);
|
||||
$addresses[] = $this->_splitCheck($parts, ',');
|
||||
$address['address'] = trim(substr($address['address'], strlen(end($addresses) . ',')));
|
||||
}
|
||||
} else {
|
||||
$addresses[] = $address['address'];
|
||||
}
|
||||
|
||||
// Check that $addresses is set, if address like this:
|
||||
// Groupname:;
|
||||
// Then errors were appearing.
|
||||
if (!isset($addresses)){
|
||||
$this->error = 'Empty group.';
|
||||
return false;
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($addresses); $i++) {
|
||||
$addresses[$i] = trim($addresses[$i]);
|
||||
}
|
||||
|
||||
// Validate each mailbox.
|
||||
// Format could be one of: name <geezer@domain.com>
|
||||
// geezer@domain.com
|
||||
// geezer
|
||||
// ... or any other format valid by RFC 822.
|
||||
array_walk($addresses, array($this, 'validateMailbox'));
|
||||
|
||||
// Nested format
|
||||
if ($this->nestGroups) {
|
||||
if ($is_group) {
|
||||
$structure->addresses = $addresses;
|
||||
} else {
|
||||
$structure = $addresses[0];
|
||||
}
|
||||
|
||||
// Flat format
|
||||
} else {
|
||||
if ($is_group) {
|
||||
$structure = array_merge($structure, $addresses);
|
||||
} else {
|
||||
$structure = $addresses;
|
||||
}
|
||||
}
|
||||
|
||||
return $structure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a phrase.
|
||||
*
|
||||
* @access private
|
||||
* @param string $phrase The phrase to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validatePhrase($phrase)
|
||||
{
|
||||
// Splits on one or more Tab or space.
|
||||
$parts = preg_split('/[ \\x09]+/', $phrase, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$phrase_parts = array();
|
||||
while (count($parts) > 0){
|
||||
$phrase_parts[] = $this->_splitCheck($parts, ' ');
|
||||
for ($i = 0; $i < $this->index + 1; $i++)
|
||||
array_shift($parts);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($phrase_parts); $i++) {
|
||||
// If quoted string:
|
||||
if (substr($phrase_parts[$i], 0, 1) == '"') {
|
||||
if (!$this->_validateQuotedString($phrase_parts[$i]))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise it's an atom:
|
||||
if (!$this->_validateAtom($phrase_parts[$i])) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate an atom which from rfc822 is:
|
||||
* atom = 1*<any CHAR except specials, SPACE and CTLs>
|
||||
*
|
||||
* If validation ($this->validate) has been turned off, then
|
||||
* validateAtom() doesn't actually check anything. This is so that you
|
||||
* can split a list of addresses up before encoding personal names
|
||||
* (umlauts, etc.), for example.
|
||||
*
|
||||
* @access private
|
||||
* @param string $atom The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateAtom($atom)
|
||||
{
|
||||
if (!$this->validate) {
|
||||
// Validation has been turned off; assume the atom is okay.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check for any char from ASCII 0 - ASCII 127
|
||||
if (!preg_match('/^[\\x00-\\x7E]+$/i', $atom, $matches)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for specials:
|
||||
if (preg_match('/[][()<>@,;\\:". ]/', $atom)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for control characters (ASCII 0-31):
|
||||
if (preg_match('/[\\x00-\\x1F]+/', $atom)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate quoted string, which is:
|
||||
* quoted-string = <"> *(qtext/quoted-pair) <">
|
||||
*
|
||||
* @access private
|
||||
* @param string $qstring The string to check
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateQuotedString($qstring)
|
||||
{
|
||||
// Leading and trailing "
|
||||
$qstring = substr($qstring, 1, -1);
|
||||
|
||||
// Perform check.
|
||||
return !(preg_match('/(.)[\x0D\\\\"]/', $qstring, $matches) && $matches[1] != '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a mailbox, which is:
|
||||
* mailbox = addr-spec ; simple address
|
||||
* / phrase route-addr ; name and route-addr
|
||||
*
|
||||
* @access public
|
||||
* @param string &$mailbox The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function validateMailbox(&$mailbox)
|
||||
{
|
||||
// A couple of defaults.
|
||||
$phrase = '';
|
||||
$comment = '';
|
||||
|
||||
// Catch any RFC822 comments and store them separately
|
||||
$_mailbox = $mailbox;
|
||||
while (strlen(trim($_mailbox)) > 0) {
|
||||
$parts = explode('(', $_mailbox);
|
||||
$before_comment = $this->_splitCheck($parts, '(');
|
||||
if ($before_comment != $_mailbox) {
|
||||
// First char should be a (
|
||||
$comment = substr(str_replace($before_comment, '', $_mailbox), 1);
|
||||
$parts = explode(')', $comment);
|
||||
$comment = $this->_splitCheck($parts, ')');
|
||||
$comments[] = $comment;
|
||||
|
||||
// +1 is for the trailing )
|
||||
$_mailbox = substr($_mailbox, strpos($_mailbox, $comment)+strlen($comment)+1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for($i=0; $i<count(@$comments); $i++){
|
||||
$mailbox = str_replace('('.$comments[$i].')', '', $mailbox);
|
||||
}
|
||||
$mailbox = trim($mailbox);
|
||||
|
||||
// Check for name + route-addr
|
||||
if (substr($mailbox, -1) == '>' && substr($mailbox, 0, 1) != '<') {
|
||||
$parts = explode('<', $mailbox);
|
||||
$name = $this->_splitCheck($parts, '<');
|
||||
|
||||
$phrase = trim($name);
|
||||
$route_addr = trim(substr($mailbox, strlen($name.'<'), -1));
|
||||
|
||||
if ($this->_validatePhrase($phrase) === false || ($route_addr = $this->_validateRouteAddr($route_addr)) === false)
|
||||
return false;
|
||||
|
||||
// Only got addr-spec
|
||||
} else {
|
||||
// First snip angle brackets if present.
|
||||
if (substr($mailbox,0,1) == '<' && substr($mailbox,-1) == '>')
|
||||
$addr_spec = substr($mailbox,1,-1);
|
||||
else
|
||||
$addr_spec = $mailbox;
|
||||
|
||||
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Construct the object that will be returned.
|
||||
$mbox = new stdClass();
|
||||
|
||||
// Add the phrase (even if empty) and comments
|
||||
$mbox->personal = $phrase;
|
||||
$mbox->comment = isset($comments) ? $comments : array();
|
||||
|
||||
if (isset($route_addr)) {
|
||||
$mbox->mailbox = $route_addr['local_part'];
|
||||
$mbox->host = $route_addr['domain'];
|
||||
$route_addr['adl'] !== '' ? $mbox->adl = $route_addr['adl'] : '';
|
||||
} else {
|
||||
$mbox->mailbox = $addr_spec['local_part'];
|
||||
$mbox->host = $addr_spec['domain'];
|
||||
}
|
||||
|
||||
$mailbox = $mbox;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function validates a route-addr which is:
|
||||
* route-addr = "<" [route] addr-spec ">"
|
||||
*
|
||||
* Angle brackets have already been removed at the point of
|
||||
* getting to this function.
|
||||
*
|
||||
* @access private
|
||||
* @param string $route_addr The string to check.
|
||||
* @return mixed False on failure, or an array containing validated address/route information on success.
|
||||
*/
|
||||
function _validateRouteAddr($route_addr)
|
||||
{
|
||||
// Check for colon.
|
||||
if (strpos($route_addr, ':') !== false) {
|
||||
$parts = explode(':', $route_addr);
|
||||
$route = $this->_splitCheck($parts, ':');
|
||||
} else {
|
||||
$route = $route_addr;
|
||||
}
|
||||
|
||||
// If $route is same as $route_addr then the colon was in
|
||||
// quotes or brackets or, of course, non existent.
|
||||
if ($route === $route_addr){
|
||||
unset($route);
|
||||
$addr_spec = $route_addr;
|
||||
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// Validate route part.
|
||||
if (($route = $this->_validateRoute($route)) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$addr_spec = substr($route_addr, strlen($route . ':'));
|
||||
|
||||
// Validate addr-spec part.
|
||||
if (($addr_spec = $this->_validateAddrSpec($addr_spec)) === false) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($route)) {
|
||||
$return['adl'] = $route;
|
||||
} else {
|
||||
$return['adl'] = '';
|
||||
}
|
||||
|
||||
$return = array_merge($return, $addr_spec);
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a route, which is:
|
||||
* route = 1#("@" domain) ":"
|
||||
*
|
||||
* @access private
|
||||
* @param string $route The string to check.
|
||||
* @return mixed False on failure, or the validated $route on success.
|
||||
*/
|
||||
function _validateRoute($route)
|
||||
{
|
||||
// Split on comma.
|
||||
$domains = explode(',', trim($route));
|
||||
|
||||
for ($i = 0; $i < count($domains); $i++) {
|
||||
$domains[$i] = str_replace('@', '', trim($domains[$i]));
|
||||
if (!$this->_validateDomain($domains[$i])) return false;
|
||||
}
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a domain, though this is not quite what
|
||||
* you expect of a strict internet domain.
|
||||
*
|
||||
* domain = sub-domain *("." sub-domain)
|
||||
*
|
||||
* @access private
|
||||
* @param string $domain The string to check.
|
||||
* @return mixed False on failure, or the validated domain on success.
|
||||
*/
|
||||
function _validateDomain($domain)
|
||||
{
|
||||
// Note the different use of $subdomains and $sub_domains
|
||||
$subdomains = explode('.', $domain);
|
||||
|
||||
while (count($subdomains) > 0) {
|
||||
$sub_domains[] = $this->_splitCheck($subdomains, '.');
|
||||
for ($i = 0; $i < $this->index + 1; $i++)
|
||||
array_shift($subdomains);
|
||||
}
|
||||
|
||||
for ($i = 0; $i < count($sub_domains); $i++) {
|
||||
if (!$this->_validateSubdomain(trim($sub_domains[$i])))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Managed to get here, so return input.
|
||||
return $domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a subdomain:
|
||||
* subdomain = domain-ref / domain-literal
|
||||
*
|
||||
* @access private
|
||||
* @param string $subdomain The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateSubdomain($subdomain)
|
||||
{
|
||||
if (preg_match('|^\[(.*)]$|', $subdomain, $arr)){
|
||||
if (!$this->_validateDliteral($arr[1])) return false;
|
||||
} else {
|
||||
if (!$this->_validateAtom($subdomain)) return false;
|
||||
}
|
||||
|
||||
// Got here, so return successful.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate a domain literal:
|
||||
* domain-literal = "[" *(dtext / quoted-pair) "]"
|
||||
*
|
||||
* @access private
|
||||
* @param string $dliteral The string to check.
|
||||
* @return boolean Success or failure.
|
||||
*/
|
||||
function _validateDliteral($dliteral)
|
||||
{
|
||||
return !preg_match('/(.)[][\x0D\\\\]/', $dliteral, $matches) && $matches[1] != '\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate an addr-spec.
|
||||
*
|
||||
* addr-spec = local-part "@" domain
|
||||
*
|
||||
* @access private
|
||||
* @param string $addr_spec The string to check.
|
||||
* @return mixed False on failure, or the validated addr-spec on success.
|
||||
*/
|
||||
function _validateAddrSpec($addr_spec)
|
||||
{
|
||||
$addr_spec = trim($addr_spec);
|
||||
|
||||
// Split on @ sign if there is one.
|
||||
if (strpos($addr_spec, '@') !== false) {
|
||||
$parts = explode('@', $addr_spec);
|
||||
$local_part = $this->_splitCheck($parts, '@');
|
||||
$domain = substr($addr_spec, strlen($local_part . '@'));
|
||||
|
||||
// No @ sign so assume the default domain.
|
||||
} else {
|
||||
$local_part = $addr_spec;
|
||||
$domain = $this->default_domain;
|
||||
}
|
||||
|
||||
if (($local_part = $this->_validateLocalPart($local_part)) === false) return false;
|
||||
if (($domain = $this->_validateDomain($domain)) === false) return false;
|
||||
|
||||
// Got here so return successful.
|
||||
return array('local_part' => $local_part, 'domain' => $domain);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to validate the local part of an address:
|
||||
* local-part = word *("." word)
|
||||
*
|
||||
* @access private
|
||||
* @param string $local_part
|
||||
* @return mixed False on failure, or the validated local part on success.
|
||||
*/
|
||||
function _validateLocalPart($local_part)
|
||||
{
|
||||
$parts = explode('.', $local_part);
|
||||
|
||||
// Split the local_part into words.
|
||||
while (count($parts) > 0){
|
||||
$words[] = $this->_splitCheck($parts, '.');
|
||||
for ($i = 0; $i < $this->index + 1; $i++) {
|
||||
array_shift($parts);
|
||||
}
|
||||
}
|
||||
|
||||
// Validate each word.
|
||||
for ($i = 0; $i < count($words); $i++) {
|
||||
if ($this->_validatePhrase(trim($words[$i])) === false) return false;
|
||||
}
|
||||
|
||||
// Managed to get here, so return the input.
|
||||
return $local_part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an approximate count of how many addresses are
|
||||
* in the given string. This is APPROXIMATE as it only splits
|
||||
* based on a comma which has no preceding backslash. Could be
|
||||
* useful as large amounts of addresses will end up producing
|
||||
* *large* structures when used with parseAddressList().
|
||||
*
|
||||
* @param string $data Addresses to count
|
||||
* @return int Approximate count
|
||||
*/
|
||||
function approximateCount($data)
|
||||
{
|
||||
return count(preg_split('/(?<!\\\\),/', $data));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a email validating function seperate to the rest
|
||||
* of the class. It simply validates whether an email is of
|
||||
* the common internet form: <user>@<domain>. This can be
|
||||
* sufficient for most people. Optional stricter mode can
|
||||
* be utilised which restricts mailbox characters allowed
|
||||
* to alphanumeric, full stop, hyphen and underscore.
|
||||
*
|
||||
* @param string $data Address to check
|
||||
* @param boolean $strict Optional stricter mode
|
||||
* @return mixed False if it fails, an indexed array
|
||||
* username/domain if it matches
|
||||
*/
|
||||
function isValidInetAddress($data, $strict = false)
|
||||
{
|
||||
$regex = $strict ? '/^([.0-9a-z_-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i' : '/^([*+!.&#$|\'\\%\/0-9a-z^_`{}=?~:-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,4})$/i';
|
||||
if (preg_match($regex, trim($data), $matches)) {
|
||||
return array($matches[1], $matches[2]);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
820
production/classes/htmlMimeMail/htmlMimeMail.php
Normal file
820
production/classes/htmlMimeMail/htmlMimeMail.php
Normal file
@@ -0,0 +1,820 @@
|
||||
<?php
|
||||
/**
|
||||
* Filename.......: class.html.mime.mail.inc
|
||||
* Project........: HTML Mime mail class
|
||||
* Last Modified..: $Date: 2002/07/24 13:14:10 $
|
||||
* CVS Revision...: $Revision: 1.4 $
|
||||
* Copyright......: 2001, 2002 Richard Heyes
|
||||
This version Modded by Alistair Brookbanks - Devellion Limited
|
||||
*/
|
||||
|
||||
require_once(dirname(__FILE__) . '/mimePart.php');
|
||||
|
||||
if (class_exists('htmlMimeMail'))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
class htmlMimeMail
|
||||
{
|
||||
/**
|
||||
* The html part of the message
|
||||
* @var string
|
||||
*/
|
||||
var $html;
|
||||
|
||||
/**
|
||||
* The text part of the message(only used in TEXT only messages)
|
||||
* @var string
|
||||
*/
|
||||
var $text;
|
||||
|
||||
/**
|
||||
* The main body of the message after building
|
||||
* @var string
|
||||
*/
|
||||
var $output;
|
||||
|
||||
/**
|
||||
* The alternative text to the HTML part (only used in HTML messages)
|
||||
* @var string
|
||||
*/
|
||||
var $html_text;
|
||||
|
||||
/**
|
||||
* An array of embedded images/objects
|
||||
* @var array
|
||||
*/
|
||||
var $html_images;
|
||||
|
||||
/**
|
||||
* An array of recognised image types for the findHtmlImages() method
|
||||
* @var array
|
||||
*/
|
||||
var $image_types;
|
||||
|
||||
/**
|
||||
* Parameters that affect the build process
|
||||
* @var array
|
||||
*/
|
||||
var $build_params;
|
||||
|
||||
/**
|
||||
* Array of attachments
|
||||
* @var array
|
||||
*/
|
||||
var $attachments;
|
||||
|
||||
/**
|
||||
* The main message headers
|
||||
* @var array
|
||||
*/
|
||||
var $headers;
|
||||
|
||||
/**
|
||||
* Whether the message has been built or not
|
||||
* @var boolean
|
||||
*/
|
||||
var $is_built;
|
||||
|
||||
/**
|
||||
* The return path address. If not set the From:
|
||||
* address is used instead
|
||||
* @var string
|
||||
*/
|
||||
var $return_path;
|
||||
|
||||
/**
|
||||
* Array of information needed for smtp sending
|
||||
* @var array
|
||||
*/
|
||||
var $smtp_params;
|
||||
|
||||
/**
|
||||
* Constructor function. Sets the headers
|
||||
* if supplied.
|
||||
*/
|
||||
|
||||
function htmlMimeMail()
|
||||
{
|
||||
/**
|
||||
* Initialise some variables.
|
||||
*/
|
||||
global $config;
|
||||
$this->html_images = array();
|
||||
$this->headers = array();
|
||||
$this->is_built = false;
|
||||
|
||||
/**
|
||||
* If you want the auto load functionality
|
||||
* to find other image/file types, add the
|
||||
* extension and content type here.
|
||||
*/
|
||||
$this->image_types = array(
|
||||
'gif' => 'image/gif',
|
||||
'jpg' => 'image/jpeg',
|
||||
'jpeg' => 'image/jpeg',
|
||||
'jpe' => 'image/jpeg',
|
||||
'bmp' => 'image/bmp',
|
||||
'png' => 'image/png',
|
||||
'tif' => 'image/tiff',
|
||||
'tiff' => 'image/tiff',
|
||||
'swf' => 'application/x-shockwave-flash'
|
||||
);
|
||||
|
||||
/**
|
||||
* Set these up
|
||||
*/
|
||||
$this->build_params['html_encoding'] = 'quoted-printable';
|
||||
$this->build_params['text_encoding'] = '7bit';
|
||||
/*
|
||||
$this->build_params['html_charset'] = 'ISO-8859-1';
|
||||
$this->build_params['text_charset'] = 'ISO-8859-1';
|
||||
$this->build_params['head_charset'] = 'ISO-8859-1';
|
||||
*/
|
||||
$this->build_params['html_charset'] = 'UTF-8';
|
||||
$this->build_params['text_charset'] = 'UTF-8';
|
||||
$this->build_params['head_charset'] = 'UTF-8';
|
||||
$this->build_params['text_wrap'] = 998;
|
||||
|
||||
/**
|
||||
* Defaults for smtp sending
|
||||
*/
|
||||
if (!empty($GLOBALS['HTTP_SERVER_VARS']['HTTP_HOST'])) {
|
||||
$helo = $GLOBALS['HTTP_SERVER_VARS']['HTTP_HOST'];
|
||||
} elseif (!empty($GLOBALS['HTTP_SERVER_VARS']['SERVER_NAME'])) {
|
||||
$helo = $GLOBALS['HTTP_SERVER_VARS']['SERVER_NAME'];
|
||||
} else {
|
||||
$helo = 'localhost';
|
||||
}
|
||||
|
||||
if(!isset($config['smtpHost']) OR empty($config['smtpHost'])) {
|
||||
$this->smtp_params['host'] = 'localhost';
|
||||
} else {
|
||||
$this->smtp_params['host'] = $config['smtpHost'];
|
||||
}
|
||||
|
||||
if(!isset($config['smtpPort']) OR empty($config['smtpPort'])) {
|
||||
$this->smtp_params['port'] = 25;
|
||||
} else {
|
||||
$this->smtp_params['port'] = $config['smtpPort'];
|
||||
}
|
||||
|
||||
if(!isset($config['smtpAuth']) OR empty($config['smtpAuth'])) {
|
||||
$this->smtp_params['auth'] = FALSE;
|
||||
} else {
|
||||
$this->smtp_params['auth'] = $config['smtpAuth'];
|
||||
}
|
||||
|
||||
if(!isset($config['smtpUsername']) OR empty($config['smtpUsername'])) {
|
||||
$this->smtp_params['user'] = '';
|
||||
} else {
|
||||
$this->smtp_params['user'] = $config['smtpUsername'];
|
||||
}
|
||||
if(!isset($config['smtpPassword']) OR empty($config['smtpPassword'])) {
|
||||
$this->smtp_params['pass'] = '';
|
||||
} else {
|
||||
$this->smtp_params['pass'] = $config['smtpPassword'];
|
||||
}
|
||||
|
||||
$this->smtp_params['helo'] = $helo;
|
||||
|
||||
/**
|
||||
* Make sure the MIME version header is first.
|
||||
*/
|
||||
$this->headers['MIME-Version'] = '1.0';
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will read a file in
|
||||
* from a supplied filename and return
|
||||
* it. This can then be given as the first
|
||||
* argument of the the functions
|
||||
* add_html_image() or add_attachment().
|
||||
*/
|
||||
function getFile($filename)
|
||||
{
|
||||
$return = '';
|
||||
if ($fp = fopen($filename, 'rb')) {
|
||||
while (!feof($fp)) {
|
||||
$return .= fread($fp, 1024);
|
||||
}
|
||||
fclose($fp);
|
||||
return $return;
|
||||
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to set the CRLF style
|
||||
*/
|
||||
function setCrlf($crlf = "\n")
|
||||
{
|
||||
if (!defined('CRLF')) {
|
||||
define('CRLF', $crlf, true);
|
||||
}
|
||||
|
||||
if (!defined('MAIL_MIMEPART_CRLF')) {
|
||||
define('MAIL_MIMEPART_CRLF', $crlf, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to set the SMTP parameters
|
||||
*/
|
||||
function setSMTPParams($host = null, $port = null, $helo = null, $auth = null, $user = null, $pass = null)
|
||||
{
|
||||
if (!is_null($host)) $this->smtp_params['host'] = $host;
|
||||
if (!is_null($port)) $this->smtp_params['port'] = $port;
|
||||
if (!is_null($helo)) $this->smtp_params['helo'] = $helo;
|
||||
if (!is_null($auth)) $this->smtp_params['auth'] = $auth;
|
||||
if (!is_null($user)) $this->smtp_params['user'] = $user;
|
||||
if (!is_null($pass)) $this->smtp_params['pass'] = $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor function to set the text encoding
|
||||
*/
|
||||
function setTextEncoding($encoding = '7bit')
|
||||
{
|
||||
$this->build_params['text_encoding'] = $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor function to set the HTML encoding
|
||||
*/
|
||||
function setHtmlEncoding($encoding = 'quoted-printable')
|
||||
{
|
||||
$this->build_params['html_encoding'] = $encoding;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor function to set the text charset
|
||||
*/
|
||||
function setTextCharset($charset = 'UTF-8')
|
||||
{
|
||||
$this->build_params['text_charset'] = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor function to set the HTML charset
|
||||
*/
|
||||
function setHtmlCharset($charset = 'UTF-8')
|
||||
{
|
||||
$this->build_params['html_charset'] = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor function to set the header encoding charset
|
||||
*/
|
||||
function setHeadCharset($charset = 'UTF-8')
|
||||
{
|
||||
$this->build_params['head_charset'] = $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor function to set the text wrap count
|
||||
*/
|
||||
function setTextWrap($count = 998)
|
||||
{
|
||||
$this->build_params['text_wrap'] = $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to set a header
|
||||
*/
|
||||
function setHeader($name, $value)
|
||||
{
|
||||
$this->headers[$name] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to add a Subject: header
|
||||
*/
|
||||
function setSubject($subject)
|
||||
{
|
||||
$this->headers['Subject'] = $subject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to add a From: header
|
||||
*/
|
||||
function setFrom($from)
|
||||
{
|
||||
$this->headers['From'] = $from;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to set the return path
|
||||
*/
|
||||
function setReturnPath($return_path)
|
||||
{
|
||||
|
||||
if(@ini_get('safe_mode')==TRUE){
|
||||
|
||||
return FALSE;
|
||||
|
||||
} else {
|
||||
|
||||
$this->return_path = $return_path;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to add a Cc: header
|
||||
*/
|
||||
function setCc($cc)
|
||||
{
|
||||
$this->headers['Cc'] = $cc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor to add a Bcc: header
|
||||
*/
|
||||
function setBcc($bcc)
|
||||
{
|
||||
$this->headers['Bcc'] = $bcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds plain text. Use this function
|
||||
* when NOT sending html email
|
||||
*/
|
||||
function setText($text = '')
|
||||
{
|
||||
$this->text = str_replace("'","'",$text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a html part to the mail.
|
||||
* Also replaces image names with
|
||||
* content-id's.
|
||||
*/
|
||||
function setHtml($html, $text = null, $images_dir = null)
|
||||
{
|
||||
$this->html = $html;
|
||||
$this->html_text = $text;
|
||||
|
||||
if (isset($images_dir)) {
|
||||
$this->_findHtmlImages($images_dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function for extracting images from
|
||||
* html source. This function will look
|
||||
* through the html code supplied by add_html()
|
||||
* and find any file that ends in one of the
|
||||
* extensions defined in $obj->image_types.
|
||||
* If the file exists it will read it in and
|
||||
* embed it, (not an attachment).
|
||||
*
|
||||
* @author Dan Allen
|
||||
*/
|
||||
function _findHtmlImages($images_dir)
|
||||
{
|
||||
// Build the list of image extensions
|
||||
while (list($key,) = each($this->image_types)) {
|
||||
$extensions[] = $key;
|
||||
}
|
||||
|
||||
preg_match_all('/(?:"|\')([^"\']+\.('.implode('|', $extensions).'))(?:"|\')/Ui', $this->html, $images);
|
||||
|
||||
for ($i=0; $i<count($images[1]); $i++) {
|
||||
if (file_exists($images_dir . $images[1][$i])) {
|
||||
$html_images[] = $images[1][$i];
|
||||
$this->html = str_replace($images[1][$i], basename($images[1][$i]), $this->html);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($html_images)) {
|
||||
|
||||
// If duplicate images are embedded, they may show up as attachments, so remove them.
|
||||
$html_images = array_unique($html_images);
|
||||
sort($html_images);
|
||||
|
||||
for ($i=0; $i<count($html_images); $i++) {
|
||||
if ($image = $this->getFile($images_dir.$html_images[$i])) {
|
||||
$ext = substr($html_images[$i], strrpos($html_images[$i], '.') + 1);
|
||||
$content_type = $this->image_types[strtolower($ext)];
|
||||
$this->addHtmlImage($image, basename($html_images[$i]), $content_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an image to the list of embedded
|
||||
* images.
|
||||
*/
|
||||
function addHtmlImage($file, $name = '', $c_type='application/octet-stream')
|
||||
{
|
||||
$this->html_images[] = array(
|
||||
'body' => $file,
|
||||
'name' => $name,
|
||||
'c_type' => $c_type,
|
||||
'cid' => md5(uniqid(time()))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a file to the list of attachments.
|
||||
*/
|
||||
function addAttachment($file, $name = '', $c_type='application/octet-stream', $encoding = 'base64')
|
||||
{
|
||||
$this->attachments[] = array(
|
||||
'body' => $file,
|
||||
'name' => $name,
|
||||
'c_type' => $c_type,
|
||||
'encoding' => $encoding
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a text subpart to a mime_part object
|
||||
*/
|
||||
function &_addTextPart(&$obj, $text)
|
||||
{
|
||||
$params['content_type'] = 'text/plain';
|
||||
$params['encoding'] = $this->build_params['text_encoding'];
|
||||
$params['charset'] = $this->build_params['text_charset'];
|
||||
if (is_object($obj)) {
|
||||
return $obj->addSubpart($text, $params);
|
||||
} else {
|
||||
return new Mail_mimePart($text, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a html subpart to a mime_part object
|
||||
*/
|
||||
function &_addHtmlPart(&$obj)
|
||||
{
|
||||
$params['content_type'] = 'text/html';
|
||||
$params['encoding'] = $this->build_params['html_encoding'];
|
||||
$params['charset'] = $this->build_params['html_charset'];
|
||||
if (is_object($obj)) {
|
||||
return $obj->addSubpart($this->html, $params);
|
||||
} else {
|
||||
return new Mail_mimePart($this->html, $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a message with a mixed part
|
||||
*/
|
||||
function &_addMixedPart()
|
||||
{
|
||||
$params['content_type'] = 'multipart/mixed';
|
||||
return new Mail_mimePart('', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an alternative part to a mime_part object
|
||||
*/
|
||||
function &_addAlternativePart(&$obj)
|
||||
{
|
||||
$params['content_type'] = 'multipart/alternative';
|
||||
if (is_object($obj)) {
|
||||
return $obj->addSubpart('', $params);
|
||||
} else {
|
||||
return new Mail_mimePart('', $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a html subpart to a mime_part object
|
||||
*/
|
||||
function &_addRelatedPart(&$obj)
|
||||
{
|
||||
$params['content_type'] = 'multipart/related';
|
||||
if (is_object($obj)) {
|
||||
return $obj->addSubpart('', $params);
|
||||
} else {
|
||||
return new Mail_mimePart('', $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an html image subpart to a mime_part object
|
||||
*/
|
||||
function &_addHtmlImagePart(&$obj, $value)
|
||||
{
|
||||
$params['content_type'] = $value['c_type'];
|
||||
$params['encoding'] = 'base64';
|
||||
$params['disposition'] = 'inline';
|
||||
$params['dfilename'] = $value['name'];
|
||||
$params['cid'] = $value['cid'];
|
||||
$obj->addSubpart($value['body'], $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attachment subpart to a mime_part object
|
||||
*/
|
||||
function &_addAttachmentPart(&$obj, $value)
|
||||
{
|
||||
$params['content_type'] = $value['c_type'];
|
||||
$params['encoding'] = $value['encoding'];
|
||||
$params['disposition'] = 'attachment';
|
||||
$params['dfilename'] = $value['name'];
|
||||
$obj->addSubpart($value['body'], $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the multipart message from the
|
||||
* list ($this->_parts). $params is an
|
||||
* array of parameters that shape the building
|
||||
* of the message. Currently supported are:
|
||||
*
|
||||
* $params['html_encoding'] - The type of encoding to use on html. Valid options are
|
||||
* "7bit", "quoted-printable" or "base64" (all without quotes).
|
||||
* 7bit is EXPRESSLY NOT RECOMMENDED. Default is quoted-printable
|
||||
* $params['text_encoding'] - The type of encoding to use on plain text Valid options are
|
||||
* "7bit", "quoted-printable" or "base64" (all without quotes).
|
||||
* Default is 7bit
|
||||
* $params['text_wrap'] - The character count at which to wrap 7bit encoded data.
|
||||
* Default this is 998.
|
||||
* $params['html_charset'] - The character set to use for a html section.
|
||||
* Default is ISO-8859-1
|
||||
* $params['text_charset'] - The character set to use for a text section.
|
||||
* - Default is ISO-8859-1
|
||||
* $params['head_charset'] - The character set to use for header encoding should it be needed.
|
||||
* - Default is ISO-8859-1
|
||||
*/
|
||||
function buildMessage($params = array())
|
||||
{
|
||||
if (!empty($params)) {
|
||||
while (list($key, $value) = each($params)) {
|
||||
$this->build_params[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->html_images)) {
|
||||
foreach ($this->html_images as $value) {
|
||||
$this->html = str_replace($value['name'], 'cid:'.$value['cid'], $this->html);
|
||||
}
|
||||
}
|
||||
|
||||
$null = null;
|
||||
$attachments = !empty($this->attachments) ? true : false;
|
||||
$html_images = !empty($this->html_images) ? true : false;
|
||||
$html = !empty($this->html) ? true : false;
|
||||
$text = isset($this->text) ? true : false;
|
||||
|
||||
switch (true) {
|
||||
case $text AND !$attachments:
|
||||
$message = &$this->_addTextPart($null, $this->text);
|
||||
break;
|
||||
|
||||
case !$text AND $attachments AND !$html:
|
||||
$message = &$this->_addMixedPart();
|
||||
|
||||
for ($i=0; $i<count($this->attachments); $i++) {
|
||||
$this->_addAttachmentPart($message, $this->attachments[$i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case $text AND $attachments:
|
||||
$message = &$this->_addMixedPart();
|
||||
$this->_addTextPart($message, $this->text);
|
||||
|
||||
for ($i=0; $i<count($this->attachments); $i++) {
|
||||
$this->_addAttachmentPart($message, $this->attachments[$i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case $html AND !$attachments AND !$html_images:
|
||||
if (!is_null($this->html_text)) {
|
||||
$message = &$this->_addAlternativePart($null);
|
||||
$this->_addTextPart($message, $this->html_text);
|
||||
$this->_addHtmlPart($message);
|
||||
} else {
|
||||
$message = &$this->_addHtmlPart($null);
|
||||
}
|
||||
break;
|
||||
|
||||
case $html AND !$attachments AND $html_images:
|
||||
if (!is_null($this->html_text)) {
|
||||
$message = &$this->_addAlternativePart($null);
|
||||
$this->_addTextPart($message, $this->html_text);
|
||||
$related = &$this->_addRelatedPart($message);
|
||||
} else {
|
||||
$message = &$this->_addRelatedPart($null);
|
||||
$related = &$message;
|
||||
}
|
||||
$this->_addHtmlPart($related);
|
||||
for ($i=0; $i<count($this->html_images); $i++) {
|
||||
$this->_addHtmlImagePart($related, $this->html_images[$i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case $html AND $attachments AND !$html_images:
|
||||
$message = &$this->_addMixedPart();
|
||||
if (!is_null($this->html_text)) {
|
||||
$alt = &$this->_addAlternativePart($message);
|
||||
$this->_addTextPart($alt, $this->html_text);
|
||||
$this->_addHtmlPart($alt);
|
||||
} else {
|
||||
$this->_addHtmlPart($message);
|
||||
}
|
||||
for ($i=0; $i<count($this->attachments); $i++) {
|
||||
$this->_addAttachmentPart($message, $this->attachments[$i]);
|
||||
}
|
||||
break;
|
||||
|
||||
case $html AND $attachments AND $html_images:
|
||||
$message = &$this->_addMixedPart();
|
||||
if (!is_null($this->html_text)) {
|
||||
$alt = &$this->_addAlternativePart($message);
|
||||
$this->_addTextPart($alt, $this->html_text);
|
||||
$rel = &$this->_addRelatedPart($alt);
|
||||
} else {
|
||||
$rel = &$this->_addRelatedPart($message);
|
||||
}
|
||||
$this->_addHtmlPart($rel);
|
||||
for ($i=0; $i<count($this->html_images); $i++) {
|
||||
$this->_addHtmlImagePart($rel, $this->html_images[$i]);
|
||||
}
|
||||
for ($i=0; $i<count($this->attachments); $i++) {
|
||||
$this->_addAttachmentPart($message, $this->attachments[$i]);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (isset($message)) {
|
||||
$output = $message->encode();
|
||||
$this->output = $output['body'];
|
||||
$this->headers = array_merge($this->headers, $output['headers']);
|
||||
|
||||
// Add message ID header
|
||||
srand((double)microtime()*10000000);
|
||||
$message_id = sprintf('<%s.%s@%s>', base_convert(time(), 10, 36), base_convert(rand(), 10, 36), !empty($GLOBALS['HTTP_SERVER_VARS']['HTTP_HOST']) ? $GLOBALS['HTTP_SERVER_VARS']['HTTP_HOST'] : $GLOBALS['HTTP_SERVER_VARS']['SERVER_NAME']);
|
||||
$this->headers['Message-ID'] = $message_id;
|
||||
|
||||
$this->is_built = true;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to encode a header if necessary
|
||||
* according to RFC2047
|
||||
*/
|
||||
function _encodeHeader($input, $charset = 'UTF-8')
|
||||
{
|
||||
preg_match_all('/(\w*[\x80-\xFF]+\w*)/', $input, $matches);
|
||||
foreach ($matches[1] as $value) {
|
||||
$replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
|
||||
$input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the mail.
|
||||
*
|
||||
* @param array $recipients
|
||||
* @param string $type OPTIONAL
|
||||
* @return mixed
|
||||
*/
|
||||
function send($recipients, $type = 'mail')
|
||||
{
|
||||
if (!defined('CRLF')) {
|
||||
$this->setCrlf($type == 'mail' ? "\n" : "\r\n");
|
||||
}
|
||||
|
||||
if (!$this->is_built) {
|
||||
$this->buildMessage();
|
||||
}
|
||||
|
||||
switch ($type) {
|
||||
case 'mail':
|
||||
$subject = '';
|
||||
if (!empty($this->headers['Subject'])) {
|
||||
$subject = $this->_encodeHeader($this->headers['Subject'], $this->build_params['head_charset']);
|
||||
unset($this->headers['Subject']);
|
||||
}
|
||||
|
||||
// Get flat representation of headers
|
||||
foreach ($this->headers as $name => $value) {
|
||||
$headers[] = $name . ': ' . $this->_encodeHeader($value, $this->build_params['head_charset']);
|
||||
}
|
||||
|
||||
$to = $this->_encodeHeader(implode(', ', $recipients), $this->build_params['head_charset']);
|
||||
|
||||
if (!empty($this->return_path)) {
|
||||
$result = mail($to, $subject, $this->output, implode(CRLF, $headers), '-f' . $this->return_path);
|
||||
} else {
|
||||
$result = mail($to, $subject, $this->output, implode(CRLF, $headers));
|
||||
}
|
||||
|
||||
// Reset the subject in case mail is resent
|
||||
if ($subject !== '') {
|
||||
$this->headers['Subject'] = $subject;
|
||||
}
|
||||
|
||||
// Return
|
||||
return $result;
|
||||
break;
|
||||
|
||||
case 'smtp':
|
||||
require_once(dirname(__FILE__) . '/smtp.php');
|
||||
require_once(dirname(__FILE__) . '/RFC822.php');
|
||||
$smtp = &smtp::connect($this->smtp_params);
|
||||
|
||||
// Parse recipients argument for internet addresses
|
||||
foreach ($recipients as $recipient) {
|
||||
$addresses = Mail_RFC822::parseAddressList($recipient, $this->smtp_params['helo'], null, false);
|
||||
foreach ($addresses as $address) {
|
||||
$smtp_recipients[] = sprintf('%s@%s', $address->mailbox, $address->host);
|
||||
}
|
||||
}
|
||||
unset($addresses); // These are reused
|
||||
unset($address); // These are reused
|
||||
|
||||
// Get flat representation of headers, parsing
|
||||
// Cc and Bcc as we go
|
||||
foreach ($this->headers as $name => $value) {
|
||||
if ($name == 'Cc' OR $name == 'Bcc') {
|
||||
$addresses = Mail_RFC822::parseAddressList($value, $this->smtp_params['helo'], null, false);
|
||||
foreach ($addresses as $address) {
|
||||
$smtp_recipients[] = sprintf('%s@%s', $address->mailbox, $address->host);
|
||||
}
|
||||
}
|
||||
if ($name == 'Bcc') {
|
||||
continue;
|
||||
}
|
||||
$headers[] = $name . ': ' . $this->_encodeHeader($value, $this->build_params['head_charset']);
|
||||
}
|
||||
// Add To header based on $recipients argument
|
||||
$headers[] = 'To: ' . $this->_encodeHeader(implode(', ', $recipients), $this->build_params['head_charset']);
|
||||
|
||||
// Add headers to send_params
|
||||
$send_params['headers'] = $headers;
|
||||
$send_params['recipients'] = array_values(array_unique($smtp_recipients));
|
||||
$send_params['body'] = $this->output;
|
||||
|
||||
// Setup return path
|
||||
if (isset($this->return_path)) {
|
||||
$send_params['from'] = $this->return_path;
|
||||
} elseif (!empty($this->headers['From'])) {
|
||||
$from = Mail_RFC822::parseAddressList($this->headers['From']);
|
||||
$send_params['from'] = sprintf('%s@%s', $from[0]->mailbox, $from[0]->host);
|
||||
} else {
|
||||
$send_params['from'] = 'postmaster@' . $this->smtp_params['helo'];
|
||||
}
|
||||
|
||||
// Send it
|
||||
if (!$smtp->send($send_params)) {
|
||||
$this->errors = $smtp->errors;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this method to return the email
|
||||
* in message/rfc822 format. Useful for
|
||||
* adding an email to another email as
|
||||
* an attachment. there's a commented
|
||||
* out example in example.php.
|
||||
*/
|
||||
function getRFC822($recipients)
|
||||
{
|
||||
// Make up the date header as according to RFC822
|
||||
$this->setHeader('Date', date('D, d M y H:i:s O'));
|
||||
|
||||
if (!defined('CRLF')) {
|
||||
$this->setCrlf($type == 'mail' ? "\n" : "\r\n");
|
||||
}
|
||||
|
||||
if (!$this->is_built) {
|
||||
$this->buildMessage();
|
||||
}
|
||||
|
||||
// Return path ?
|
||||
if (isset($this->return_path)) {
|
||||
$headers[] = 'Return-Path: ' . $this->return_path;
|
||||
}
|
||||
|
||||
// Get flat representation of headers
|
||||
foreach ($this->headers as $name => $value) {
|
||||
$headers[] = $name . ': ' . $value;
|
||||
}
|
||||
$headers[] = 'To: ' . implode(', ', $recipients);
|
||||
|
||||
return implode(CRLF, $headers) . CRLF . CRLF . $this->output;
|
||||
}
|
||||
} // End of class.
|
||||
?>
|
||||
333
production/classes/htmlMimeMail/mimePart.php
Normal file
333
production/classes/htmlMimeMail/mimePart.php
Normal file
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
//
|
||||
// +----------------------------------------------------------------------+
|
||||
// | PHP Version 4 |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Copyright (c) 1997-2002 The PHP Group |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | This source file is subject to version 2.02 of the PHP license, |
|
||||
// | that is bundled with this package in the file LICENSE, and is |
|
||||
// | available at through the world-wide-web at |
|
||||
// | http://www.php.net/license/2_02.txt. |
|
||||
// | If you did not receive a copy of the PHP license and are unable to |
|
||||
// | obtain it through the world-wide-web, please send a note to |
|
||||
// | license@php.net so we can mail you a copy immediately. |
|
||||
// +----------------------------------------------------------------------+
|
||||
// | Authors: Richard Heyes <richard@phpguru.org> |
|
||||
// +----------------------------------------------------------------------+
|
||||
|
||||
/**
|
||||
*
|
||||
* Raw mime encoding class
|
||||
*
|
||||
* What is it?
|
||||
* This class enables you to manipulate and build
|
||||
* a mime email from the ground up.
|
||||
*
|
||||
* Why use this instead of mime.php?
|
||||
* mime.php is a userfriendly api to this class for
|
||||
* people who aren't interested in the internals of
|
||||
* mime mail. This class however allows full control
|
||||
* over the email.
|
||||
*
|
||||
* Eg.
|
||||
*
|
||||
* // Since multipart/mixed has no real body, (the body is
|
||||
* // the subpart), we set the body argument to blank.
|
||||
*
|
||||
* $params['content_type'] = 'multipart/mixed';
|
||||
* $email = new Mail_mimePart('', $params);
|
||||
*
|
||||
* // Here we add a text part to the multipart we have
|
||||
* // already. Assume $body contains plain text.
|
||||
*
|
||||
* $params['content_type'] = 'text/plain';
|
||||
* $params['encoding'] = '7bit';
|
||||
* $text = $email->addSubPart($body, $params);
|
||||
*
|
||||
* // Now add an attachment. Assume $attach is
|
||||
* the contents of the attachment
|
||||
*
|
||||
* $params['content_type'] = 'application/zip';
|
||||
* $params['encoding'] = 'base64';
|
||||
* $params['disposition'] = 'attachment';
|
||||
* $params['dfilename'] = 'example.zip';
|
||||
* $attach =& $email->addSubPart($body, $params);
|
||||
*
|
||||
* // Now build the email. Note that the encode
|
||||
* // function returns an associative array containing two
|
||||
* // elements, body and headers. You will need to add extra
|
||||
* // headers, (eg. Mime-Version) before sending.
|
||||
*
|
||||
* $email = $message->encode();
|
||||
* $email['headers'][] = 'Mime-Version: 1.0';
|
||||
*
|
||||
*
|
||||
* Further examples are available at http://www.phpguru.org
|
||||
*
|
||||
* TODO:
|
||||
* - Set encode() to return the $obj->encoded if encode()
|
||||
* has already been run. Unless a flag is passed to specifically
|
||||
* re-build the message.
|
||||
*
|
||||
* @author Richard Heyes <richard@phpguru.org>
|
||||
* @version $Revision: 1.3 $
|
||||
* @package Mail
|
||||
*/
|
||||
|
||||
class Mail_mimePart {
|
||||
|
||||
/**
|
||||
* The encoding type of this part
|
||||
* @var string
|
||||
*/
|
||||
var $_encoding;
|
||||
|
||||
/**
|
||||
* An array of subparts
|
||||
* @var array
|
||||
*/
|
||||
var $_subparts;
|
||||
|
||||
/**
|
||||
* The output of this part after being built
|
||||
* @var string
|
||||
*/
|
||||
var $_encoded;
|
||||
|
||||
/**
|
||||
* Headers for this part
|
||||
* @var array
|
||||
*/
|
||||
var $_headers;
|
||||
|
||||
/**
|
||||
* The body of this part (not encoded)
|
||||
* @var string
|
||||
*/
|
||||
var $_body;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Sets up the object.
|
||||
*
|
||||
* @param $body - The body of the mime part if any.
|
||||
* @param $params - An associative array of parameters:
|
||||
* content_type - The content type for this part eg multipart/mixed
|
||||
* encoding - The encoding to use, 7bit, 8bit, base64, or quoted-printable
|
||||
* cid - Content ID to apply
|
||||
* disposition - Content disposition, inline or attachment
|
||||
* dfilename - Optional filename parameter for content disposition
|
||||
* description - Content description
|
||||
* charset - Character set to use
|
||||
* @access public
|
||||
*/
|
||||
function Mail_mimePart($body = '', $params = array())
|
||||
{
|
||||
if (!defined('MAIL_MIMEPART_CRLF')) {
|
||||
define('MAIL_MIMEPART_CRLF', defined('MAIL_MIME_CRLF') ? MAIL_MIME_CRLF : "\r\n", TRUE);
|
||||
}
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
switch ($key) {
|
||||
case 'content_type':
|
||||
$headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : '');
|
||||
break;
|
||||
|
||||
case 'encoding':
|
||||
$this->_encoding = $value;
|
||||
$headers['Content-Transfer-Encoding'] = $value;
|
||||
break;
|
||||
|
||||
case 'cid':
|
||||
$headers['Content-ID'] = '<' . $value . '>';
|
||||
break;
|
||||
|
||||
case 'disposition':
|
||||
$headers['Content-Disposition'] = $value . (isset($dfilename) ? '; filename="' . $dfilename . '"' : '');
|
||||
break;
|
||||
|
||||
case 'dfilename':
|
||||
if (isset($headers['Content-Disposition'])) {
|
||||
$headers['Content-Disposition'] .= '; filename="' . $value . '"';
|
||||
} else {
|
||||
$dfilename = $value;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'description':
|
||||
$headers['Content-Description'] = $value;
|
||||
break;
|
||||
|
||||
case 'charset':
|
||||
if (isset($headers['Content-Type'])) {
|
||||
$headers['Content-Type'] .= '; charset="' . $value . '"';
|
||||
} else {
|
||||
$charset = $value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Default content-type
|
||||
if (!isset($headers['Content-Type'])) {
|
||||
$headers['Content-Type'] = 'text/plain';
|
||||
}
|
||||
|
||||
//Default encoding
|
||||
if (!isset($this->_encoding)) {
|
||||
$this->_encoding = '7bit';
|
||||
}
|
||||
|
||||
// Assign stuff to member variables
|
||||
$this->_encoded = array();
|
||||
$this->_headers = $headers;
|
||||
$this->_body = $body;
|
||||
}
|
||||
|
||||
/**
|
||||
* encode()
|
||||
*
|
||||
* Encodes and returns the email. Also stores
|
||||
* it in the encoded member variable
|
||||
*
|
||||
* @return An associative array containing two elements,
|
||||
* body and headers. The headers element is itself
|
||||
* an indexed array.
|
||||
* @access public
|
||||
*/
|
||||
function encode()
|
||||
{
|
||||
$encoded =& $this->_encoded;
|
||||
|
||||
if (!empty($this->_subparts)) {
|
||||
srand((double)microtime()*1000000);
|
||||
$boundary = '=_' . md5(uniqid(rand()) . microtime());
|
||||
$this->_headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . "\t" . 'boundary="' . $boundary . '"';
|
||||
|
||||
// Add body parts to $subparts
|
||||
for ($i = 0; $i < count($this->_subparts); $i++) {
|
||||
$headers = array();
|
||||
$tmp = $this->_subparts[$i]->encode();
|
||||
foreach ($tmp['headers'] as $key => $value) {
|
||||
$headers[] = $key . ': ' . $value;
|
||||
}
|
||||
$subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body'];
|
||||
}
|
||||
|
||||
$encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF .
|
||||
implode('--' . $boundary . MAIL_MIMEPART_CRLF, $subparts) .
|
||||
'--' . $boundary.'--' . MAIL_MIMEPART_CRLF;
|
||||
|
||||
} else {
|
||||
$encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding) . MAIL_MIMEPART_CRLF;
|
||||
}
|
||||
|
||||
// Add headers to $encoded
|
||||
$encoded['headers'] =& $this->_headers;
|
||||
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* &addSubPart()
|
||||
*
|
||||
* Adds a subpart to current mime part and returns
|
||||
* a reference to it
|
||||
*
|
||||
* @param $body The body of the subpart, if any.
|
||||
* @param $params The parameters for the subpart, same
|
||||
* as the $params argument for constructor.
|
||||
* @return A reference to the part you just added. It is
|
||||
* crucial if using multipart/* in your subparts that
|
||||
* you use =& in your script when calling this function,
|
||||
* otherwise you will not be able to add further subparts.
|
||||
* @access public
|
||||
*/
|
||||
function &addSubPart($body, $params)
|
||||
{
|
||||
$this->_subparts[] = new Mail_mimePart($body, $params);
|
||||
return $this->_subparts[count($this->_subparts) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* _getEncodedData()
|
||||
*
|
||||
* Returns encoded data based upon encoding passed to it
|
||||
*
|
||||
* @param $data The data to encode.
|
||||
* @param $encoding The encoding type to use, 7bit, base64,
|
||||
* or quoted-printable.
|
||||
* @access private
|
||||
*/
|
||||
function _getEncodedData($data, $encoding)
|
||||
{
|
||||
switch ($encoding) {
|
||||
case '8bit':
|
||||
case '7bit':
|
||||
return $data;
|
||||
break;
|
||||
|
||||
case 'quoted-printable':
|
||||
return $this->_quotedPrintableEncode($data);
|
||||
break;
|
||||
|
||||
case 'base64':
|
||||
return rtrim(chunk_split(base64_encode($data), 76, MAIL_MIMEPART_CRLF));
|
||||
break;
|
||||
|
||||
default:
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* quoteadPrintableEncode()
|
||||
*
|
||||
* Encodes data to quoted-printable standard.
|
||||
*
|
||||
* @param $input The data to encode
|
||||
* @param $line_max Optional max line length. Should
|
||||
* not be more than 76 chars
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _quotedPrintableEncode($input , $line_max = 76)
|
||||
{
|
||||
$lines = preg_split("/\r?\n/", $input);
|
||||
$eol = MAIL_MIMEPART_CRLF;
|
||||
$escape = '=';
|
||||
$output = '';
|
||||
|
||||
while(list(, $line) = each($lines)){
|
||||
|
||||
$linlen = strlen($line);
|
||||
$newline = '';
|
||||
|
||||
for ($i = 0; $i < $linlen; $i++) {
|
||||
$char = substr($line, $i, 1);
|
||||
$dec = ord($char);
|
||||
|
||||
if (($dec == 32) AND ($i == ($linlen - 1))){ // convert space at eol only
|
||||
$char = '=20';
|
||||
|
||||
} elseif($dec == 9) {
|
||||
; // Do nothing if a tab.
|
||||
} elseif(($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) {
|
||||
$char = $escape . strtoupper(sprintf('%02s', dechex($dec)));
|
||||
}
|
||||
|
||||
if ((strlen($newline) + strlen($char)) >= $line_max) { // MAIL_MIMEPART_CRLF is not counted
|
||||
$output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
|
||||
$newline = '';
|
||||
}
|
||||
$newline .= $char;
|
||||
} // end of for
|
||||
$output .= $newline . $eol;
|
||||
}
|
||||
$output = substr($output, 0, -1 * strlen($eol)); // Don't want last crlf
|
||||
return $output;
|
||||
}
|
||||
} // End of class
|
||||
?>
|
||||
359
production/classes/htmlMimeMail/smtp.php
Normal file
359
production/classes/htmlMimeMail/smtp.php
Normal file
@@ -0,0 +1,359 @@
|
||||
<?php
|
||||
/**
|
||||
* Filename.......: class.smtp.inc
|
||||
* Project........: SMTP Class
|
||||
* Version........: 1.0.5
|
||||
* Last Modified..: 21 December 2001
|
||||
*/
|
||||
|
||||
define('SMTP_STATUS_NOT_CONNECTED', 1, TRUE);
|
||||
define('SMTP_STATUS_CONNECTED', 2, TRUE);
|
||||
|
||||
class smtp{
|
||||
|
||||
var $authenticated;
|
||||
var $connection;
|
||||
var $recipients;
|
||||
var $headers;
|
||||
var $timeout;
|
||||
var $errors;
|
||||
var $status;
|
||||
var $body;
|
||||
var $from;
|
||||
var $host;
|
||||
var $port;
|
||||
var $helo;
|
||||
var $auth;
|
||||
var $user;
|
||||
var $pass;
|
||||
|
||||
/**
|
||||
* Constructor function. Arguments:
|
||||
* $params - An assoc array of parameters:
|
||||
*
|
||||
* host - The hostname of the smtp server Default: localhost
|
||||
* port - The port the smtp server runs on Default: 25
|
||||
* helo - What to send as the HELO command Default: localhost
|
||||
* (typically the hostname of the
|
||||
* machine this script runs on)
|
||||
* auth - Whether to use basic authentication Default: FALSE
|
||||
* user - Username for authentication Default: <blank>
|
||||
* pass - Password for authentication Default: <blank>
|
||||
* timeout - The timeout in seconds for the call Default: 5
|
||||
* to fsockopen()
|
||||
*/
|
||||
|
||||
function smtp($params = array()){
|
||||
|
||||
if(!defined('CRLF'))
|
||||
define('CRLF', "\r\n", TRUE);
|
||||
|
||||
$this->authenticated = FALSE;
|
||||
$this->timeout = 5;
|
||||
$this->status = SMTP_STATUS_NOT_CONNECTED;
|
||||
$this->host = 'localhost';
|
||||
$this->port = 25;
|
||||
$this->helo = 'localhost';
|
||||
$this->auth = FALSE;
|
||||
$this->user = '';
|
||||
$this->pass = '';
|
||||
$this->errors = array();
|
||||
|
||||
foreach($params as $key => $value){
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect function. This will, when called
|
||||
* statically, create a new smtp object,
|
||||
* call the connect function (ie this function)
|
||||
* and return it. When not called statically,
|
||||
* it will connect to the server and send
|
||||
* the HELO command.
|
||||
*/
|
||||
|
||||
function &connect($params = array()){
|
||||
|
||||
if(!isset($this->status)){
|
||||
$obj = new smtp($params);
|
||||
if($obj->connect()){
|
||||
$obj->status = SMTP_STATUS_CONNECTED;
|
||||
}
|
||||
|
||||
return $obj;
|
||||
|
||||
}else{
|
||||
$this->connection = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
|
||||
if(function_exists('socket_set_timeout')){
|
||||
@socket_set_timeout($this->connection, 5, 0);
|
||||
}
|
||||
|
||||
$greeting = $this->get_data();
|
||||
if(is_resource($this->connection)){
|
||||
return $this->auth ? $this->ehlo() : $this->helo();
|
||||
}else{
|
||||
$this->errors[] = 'Failed to connect to server: '.$errstr;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function which handles sending the mail.
|
||||
* Arguments:
|
||||
* $params - Optional assoc array of parameters.
|
||||
* Can contain:
|
||||
* recipients - Indexed array of recipients
|
||||
* from - The from address. (used in MAIL FROM:),
|
||||
* this will be the return path
|
||||
* headers - Indexed array of headers, one header per array entry
|
||||
* body - The body of the email
|
||||
* It can also contain any of the parameters from the connect()
|
||||
* function
|
||||
*/
|
||||
|
||||
function send($params = array()){
|
||||
|
||||
foreach($params as $key => $value){
|
||||
$this->set($key, $value);
|
||||
}
|
||||
|
||||
if($this->is_connected()){
|
||||
|
||||
// Do we auth or not? Note the distinction between the auth variable and auth() function
|
||||
if($this->auth AND !$this->authenticated){
|
||||
if(!$this->auth())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$this->mail($this->from);
|
||||
if(is_array($this->recipients))
|
||||
foreach($this->recipients as $value)
|
||||
$this->rcpt($value);
|
||||
else
|
||||
$this->rcpt($this->recipients);
|
||||
|
||||
if(!$this->data())
|
||||
return FALSE;
|
||||
|
||||
// Transparency
|
||||
$headers = str_replace(CRLF.'.', CRLF.'..', trim(implode(CRLF, $this->headers)));
|
||||
$body = str_replace(CRLF.'.', CRLF.'..', $this->body);
|
||||
$body = $body[0] == '.' ? '.'.$body : $body;
|
||||
|
||||
$this->send_data($headers);
|
||||
$this->send_data('');
|
||||
$this->send_data($body);
|
||||
$this->send_data('.');
|
||||
|
||||
$result = (substr(trim($this->get_data()), 0, 3) === '250');
|
||||
//$this->rset();
|
||||
return $result;
|
||||
}else{
|
||||
$this->errors[] = 'Not connected!';
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to implement HELO cmd
|
||||
*/
|
||||
|
||||
function helo(){
|
||||
if(is_resource($this->connection)
|
||||
AND $this->send_data('HELO '.$this->helo)
|
||||
AND substr(trim($error = $this->get_data()), 0, 3) === '250' ){
|
||||
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = 'HELO command failed, output: ' . trim(substr(trim($error),3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to implement EHLO cmd
|
||||
*/
|
||||
|
||||
function ehlo(){
|
||||
if(is_resource($this->connection)
|
||||
AND $this->send_data('EHLO '.$this->helo)
|
||||
AND substr(trim($error = $this->get_data()), 0, 3) === '250' ){
|
||||
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = 'EHLO command failed, output: ' . trim(substr(trim($error),3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to implement RSET cmd
|
||||
*/
|
||||
|
||||
function rset(){
|
||||
if(is_resource($this->connection)
|
||||
AND $this->send_data('RSET')
|
||||
AND substr(trim($error = $this->get_data()), 0, 3) === '250' ){
|
||||
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = 'RSET command failed, output: ' . trim(substr(trim($error),3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to implement QUIT cmd
|
||||
*/
|
||||
|
||||
function quit(){
|
||||
if(is_resource($this->connection)
|
||||
AND $this->send_data('QUIT')
|
||||
AND substr(trim($error = $this->get_data()), 0, 3) === '221' ){
|
||||
|
||||
fclose($this->connection);
|
||||
$this->status = SMTP_STATUS_NOT_CONNECTED;
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = 'QUIT command failed, output: ' . trim(substr(trim($error),3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to implement AUTH cmd
|
||||
*/
|
||||
|
||||
function auth(){
|
||||
if(is_resource($this->connection)
|
||||
AND $this->send_data('AUTH LOGIN')
|
||||
AND substr(trim($error = $this->get_data()), 0, 3) === '334'
|
||||
AND $this->send_data(base64_encode($this->user)) // Send username
|
||||
AND substr(trim($error = $this->get_data()),0,3) === '334'
|
||||
AND $this->send_data(base64_encode($this->pass)) // Send password
|
||||
AND substr(trim($error = $this->get_data()),0,3) === '235' ){
|
||||
|
||||
$this->authenticated = TRUE;
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = 'AUTH command failed: ' . trim(substr(trim($error),3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that handles the MAIL FROM: cmd
|
||||
*/
|
||||
|
||||
function mail($from){
|
||||
|
||||
if($this->is_connected()
|
||||
AND $this->send_data('MAIL FROM:<'.$from.'>')
|
||||
AND substr(trim($this->get_data()), 0, 2) === '250' ){
|
||||
|
||||
return TRUE;
|
||||
|
||||
}else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that handles the RCPT TO: cmd
|
||||
*/
|
||||
|
||||
function rcpt($to){
|
||||
|
||||
if($this->is_connected()
|
||||
AND $this->send_data('RCPT TO:<'.$to.'>')
|
||||
AND substr(trim($error = $this->get_data()), 0, 2) === '25' ){
|
||||
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = trim(substr(trim($error), 3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function that sends the DATA cmd
|
||||
*/
|
||||
|
||||
function data(){
|
||||
|
||||
if($this->is_connected()
|
||||
AND $this->send_data('DATA')
|
||||
AND substr(trim($error = $this->get_data()), 0, 3) === '354' ){
|
||||
|
||||
return TRUE;
|
||||
|
||||
}else{
|
||||
$this->errors[] = trim(substr(trim($error), 3));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to determine if this object
|
||||
* is connected to the server or not.
|
||||
*/
|
||||
|
||||
function is_connected(){
|
||||
|
||||
return (is_resource($this->connection) AND ($this->status === SMTP_STATUS_CONNECTED));
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to send a bit of data
|
||||
*/
|
||||
|
||||
function send_data($data){
|
||||
|
||||
if(is_resource($this->connection)){
|
||||
return fwrite($this->connection, $data.CRLF, strlen($data)+2);
|
||||
|
||||
}else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to get data.
|
||||
*/
|
||||
|
||||
function &get_data(){
|
||||
|
||||
$return = '';
|
||||
$line = '';
|
||||
$loops = 0;
|
||||
|
||||
if(is_resource($this->connection)){
|
||||
while((strpos($return, CRLF) === FALSE OR substr($line,3,1) !== ' ') AND $loops < 100){
|
||||
$line = fgets($this->connection, 512);
|
||||
$return .= $line;
|
||||
$loops++;
|
||||
}
|
||||
return $return;
|
||||
|
||||
}else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a variable
|
||||
*/
|
||||
|
||||
function set($var, $value){
|
||||
|
||||
$this->$var = $value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
} // End of class
|
||||
?>
|
||||
3
production/classes/index.php
Normal file
3
production/classes/index.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
die("Access Denied");
|
||||
?>
|
||||
900
production/classes/magpie/extlib/Snoopy.class.inc
Normal file
900
production/classes/magpie/extlib/Snoopy.class.inc
Normal file
@@ -0,0 +1,900 @@
|
||||
<?php
|
||||
|
||||
/*************************************************
|
||||
|
||||
Snoopy - the PHP net client
|
||||
Author: Monte Ohrt <monte@ispi.net>
|
||||
Copyright (c): 1999-2000 ispi, all rights reserved
|
||||
Version: 1.0
|
||||
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
You may contact the author of Snoopy by e-mail at:
|
||||
monte@ispi.net
|
||||
|
||||
Or, write to:
|
||||
Monte Ohrt
|
||||
CTO, ispi
|
||||
237 S. 70th suite 220
|
||||
Lincoln, NE 68510
|
||||
|
||||
The latest version of Snoopy can be obtained from:
|
||||
http://snoopy.sourceforge.com
|
||||
|
||||
*************************************************/
|
||||
|
||||
class Snoopy
|
||||
{
|
||||
/**** Public variables ****/
|
||||
|
||||
/* user definable vars */
|
||||
|
||||
var $host = "www.php.net"; // host name we are connecting to
|
||||
var $port = 80; // port we are connecting to
|
||||
var $proxy_host = ""; // proxy host to use
|
||||
var $proxy_port = ""; // proxy port to use
|
||||
var $agent = "Snoopy v1.0"; // agent we masquerade as
|
||||
var $referer = ""; // referer info to pass
|
||||
var $cookies = array(); // array of cookies to pass
|
||||
// $cookies["username"]="joe";
|
||||
var $rawheaders = array(); // array of raw headers to send
|
||||
// $rawheaders["Content-type"]="text/html";
|
||||
|
||||
var $maxredirs = 5; // http redirection depth maximum. 0 = disallow
|
||||
var $lastredirectaddr = ""; // contains address of last redirected address
|
||||
var $offsiteok = true; // allows redirection off-site
|
||||
var $maxframes = 0; // frame content depth maximum. 0 = disallow
|
||||
var $expandlinks = true; // expand links to fully qualified URLs.
|
||||
// this only applies to fetchlinks()
|
||||
// or submitlinks()
|
||||
var $passcookies = true; // pass set cookies back through redirects
|
||||
// NOTE: this currently does not respect
|
||||
// dates, domains or paths.
|
||||
|
||||
var $user = ""; // user for http authentication
|
||||
var $pass = ""; // password for http authentication
|
||||
|
||||
// http accept types
|
||||
var $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
|
||||
|
||||
var $results = ""; // where the content is put
|
||||
|
||||
var $error = ""; // error messages sent here
|
||||
var $response_code = ""; // response code returned from server
|
||||
var $headers = array(); // headers returned from server sent here
|
||||
var $maxlength = 500000; // max return data length (body)
|
||||
var $read_timeout = 0; // timeout on read operations, in seconds
|
||||
// supported only since PHP 4 Beta 4
|
||||
// set to 0 to disallow timeouts
|
||||
var $timed_out = false; // if a read operation timed out
|
||||
var $status = 0; // http request status
|
||||
|
||||
var $curl_path = "/usr/bin/curl";
|
||||
// Snoopy will use cURL for fetching
|
||||
// SSL content if a full system path to
|
||||
// the cURL binary is supplied here.
|
||||
// set to false if you do not have
|
||||
// cURL installed. See http://curl.haxx.se
|
||||
// for details on installing cURL.
|
||||
// Snoopy does *not* use the cURL
|
||||
// library functions built into php,
|
||||
// as these functions are not stable
|
||||
// as of this Snoopy release.
|
||||
|
||||
// send Accept-encoding: gzip?
|
||||
var $use_gzip = true;
|
||||
|
||||
/**** Private variables ****/
|
||||
|
||||
var $_maxlinelen = 4096; // max line length (headers)
|
||||
|
||||
var $_httpmethod = "GET"; // default http request method
|
||||
var $_httpversion = "HTTP/1.0"; // default http request version
|
||||
var $_submit_method = "POST"; // default submit method
|
||||
var $_submit_type = "application/x-www-form-urlencoded"; // default submit type
|
||||
var $_mime_boundary = ""; // MIME boundary for multipart/form-data submit type
|
||||
var $_redirectaddr = false; // will be set if page fetched is a redirect
|
||||
var $_redirectdepth = 0; // increments on an http redirect
|
||||
var $_frameurls = array(); // frame src urls
|
||||
var $_framedepth = 0; // increments on frame depth
|
||||
|
||||
var $_isproxy = false; // set if using a proxy server
|
||||
var $_fp_timeout = 30; // timeout for socket connection
|
||||
|
||||
/*======================================================================*\
|
||||
Function: fetch
|
||||
Purpose: fetch the contents of a web page
|
||||
(and possibly other protocols in the
|
||||
future like ftp, nntp, gopher, etc.)
|
||||
Input: $URI the location of the page to fetch
|
||||
Output: $this->results the output text from the fetch
|
||||
\*======================================================================*/
|
||||
|
||||
function fetch($URI)
|
||||
{
|
||||
|
||||
//preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
|
||||
$URI_PARTS = parse_url($URI);
|
||||
if (!empty($URI_PARTS["user"]))
|
||||
$this->user = $URI_PARTS["user"];
|
||||
if (!empty($URI_PARTS["pass"]))
|
||||
$this->pass = $URI_PARTS["pass"];
|
||||
|
||||
switch($URI_PARTS["scheme"])
|
||||
{
|
||||
case "http":
|
||||
$this->host = $URI_PARTS["host"];
|
||||
if(!empty($URI_PARTS["port"]))
|
||||
$this->port = $URI_PARTS["port"];
|
||||
if($this->_connect($fp))
|
||||
{
|
||||
if($this->_isproxy)
|
||||
{
|
||||
// using proxy, send entire URI
|
||||
$this->_httprequest($URI,$fp,$URI,$this->_httpmethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = $URI_PARTS["path"].(isset($URI_PARTS["query"]) ? "?".$URI_PARTS["query"] : "");
|
||||
// no proxy, send only the path
|
||||
$this->_httprequest($path, $fp, $URI, $this->_httpmethod);
|
||||
}
|
||||
|
||||
$this->_disconnect($fp);
|
||||
|
||||
if($this->_redirectaddr)
|
||||
{
|
||||
/* url was redirected, check if we've hit the max depth */
|
||||
if($this->maxredirs > $this->_redirectdepth)
|
||||
{
|
||||
// only follow redirect if it's on this site, or offsiteok is true
|
||||
if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
|
||||
{
|
||||
/* follow the redirect */
|
||||
$this->_redirectdepth++;
|
||||
$this->lastredirectaddr=$this->_redirectaddr;
|
||||
$this->fetch($this->_redirectaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
|
||||
{
|
||||
$frameurls = $this->_frameurls;
|
||||
$this->_frameurls = array();
|
||||
|
||||
while(list(,$frameurl) = each($frameurls))
|
||||
{
|
||||
if($this->_framedepth < $this->maxframes)
|
||||
{
|
||||
$this->fetch($frameurl);
|
||||
$this->_framedepth++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case "https":
|
||||
if(!$this->curl_path || (!is_executable($this->curl_path))) {
|
||||
$this->error = "Bad curl ($this->curl_path), can't fetch HTTPS \n";
|
||||
return false;
|
||||
}
|
||||
$this->host = $URI_PARTS["host"];
|
||||
if(!empty($URI_PARTS["port"]))
|
||||
$this->port = $URI_PARTS["port"];
|
||||
if($this->_isproxy)
|
||||
{
|
||||
// using proxy, send entire URI
|
||||
$this->_httpsrequest($URI,$URI,$this->_httpmethod);
|
||||
}
|
||||
else
|
||||
{
|
||||
$path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
|
||||
// no proxy, send only the path
|
||||
$this->_httpsrequest($path, $URI, $this->_httpmethod);
|
||||
}
|
||||
|
||||
if($this->_redirectaddr)
|
||||
{
|
||||
/* url was redirected, check if we've hit the max depth */
|
||||
if($this->maxredirs > $this->_redirectdepth)
|
||||
{
|
||||
// only follow redirect if it's on this site, or offsiteok is true
|
||||
if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
|
||||
{
|
||||
/* follow the redirect */
|
||||
$this->_redirectdepth++;
|
||||
$this->lastredirectaddr=$this->_redirectaddr;
|
||||
$this->fetch($this->_redirectaddr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)
|
||||
{
|
||||
$frameurls = $this->_frameurls;
|
||||
$this->_frameurls = array();
|
||||
|
||||
while(list(,$frameurl) = each($frameurls))
|
||||
{
|
||||
if($this->_framedepth < $this->maxframes)
|
||||
{
|
||||
$this->fetch($frameurl);
|
||||
$this->_framedepth++;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
// not a valid protocol
|
||||
$this->error = 'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*======================================================================*\
|
||||
Private functions
|
||||
\*======================================================================*/
|
||||
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _striplinks
|
||||
Purpose: strip the hyperlinks from an html document
|
||||
Input: $document document to strip.
|
||||
Output: $match an array of the links
|
||||
\*======================================================================*/
|
||||
|
||||
function _striplinks($document)
|
||||
{
|
||||
preg_match_all("'<\s*a\s+.*href\s*=\s* # find <a href=
|
||||
([\"\'])? # find single or double quote
|
||||
(?(1) (.*?)\\1 | ([^\s\>]+)) # if quote found, match up to next matching
|
||||
# quote, otherwise match up to next space
|
||||
'isx",$document,$links);
|
||||
|
||||
|
||||
// catenate the non-empty matches from the conditional subpattern
|
||||
|
||||
while(list($key,$val) = each($links[2]))
|
||||
{
|
||||
if(!empty($val))
|
||||
$match[] = $val;
|
||||
}
|
||||
|
||||
while(list($key,$val) = each($links[3]))
|
||||
{
|
||||
if(!empty($val))
|
||||
$match[] = $val;
|
||||
}
|
||||
|
||||
// return the links
|
||||
return $match;
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _stripform
|
||||
Purpose: strip the form elements from an html document
|
||||
Input: $document document to strip.
|
||||
Output: $match an array of the links
|
||||
\*======================================================================*/
|
||||
|
||||
function _stripform($document)
|
||||
{
|
||||
preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements);
|
||||
|
||||
// catenate the matches
|
||||
$match = implode("\r\n",$elements[0]);
|
||||
|
||||
// return the links
|
||||
return $match;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _striptext
|
||||
Purpose: strip the text from an html document
|
||||
Input: $document document to strip.
|
||||
Output: $text the resulting text
|
||||
\*======================================================================*/
|
||||
|
||||
function _striptext($document)
|
||||
{
|
||||
|
||||
// I didn't use preg eval (//e) since that is only available in PHP 4.0.
|
||||
// so, list your entities one by one here. I included some of the
|
||||
// more common ones.
|
||||
|
||||
$search = array("'<script[^>]*?>.*?</script>'si", // strip out javascript
|
||||
"'<[\/\!]*?[^<>]*?>'si", // strip out html tags
|
||||
"'([\r\n])[\s]+'", // strip out white space
|
||||
"'&(quote|#34);'i", // replace html entities
|
||||
"'&(amp|#38);'i",
|
||||
"'&(lt|#60);'i",
|
||||
"'&(gt|#62);'i",
|
||||
"'&(nbsp|#160);'i",
|
||||
"'&(iexcl|#161);'i",
|
||||
"'&(cent|#162);'i",
|
||||
"'&(pound|#163);'i",
|
||||
"'&(copy|#169);'i"
|
||||
);
|
||||
$replace = array( "",
|
||||
"",
|
||||
"\\1",
|
||||
"\"",
|
||||
"&",
|
||||
"<",
|
||||
">",
|
||||
" ",
|
||||
chr(161),
|
||||
chr(162),
|
||||
chr(163),
|
||||
chr(169));
|
||||
|
||||
$text = preg_replace($search,$replace,$document);
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _expandlinks
|
||||
Purpose: expand each link into a fully qualified URL
|
||||
Input: $links the links to qualify
|
||||
$URI the full URI to get the base from
|
||||
Output: $expandedLinks the expanded links
|
||||
\*======================================================================*/
|
||||
|
||||
function _expandlinks($links,$URI)
|
||||
{
|
||||
|
||||
preg_match("/^[^\?]+/",$URI,$match);
|
||||
|
||||
$match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]);
|
||||
|
||||
$search = array( "|^http://".preg_quote($this->host)."|i",
|
||||
"|^(?!http://)(\/)?(?!mailto:)|i",
|
||||
"|/\./|",
|
||||
"|/[^\/]+/\.\./|"
|
||||
);
|
||||
|
||||
$replace = array( "",
|
||||
$match."/",
|
||||
"/",
|
||||
"/"
|
||||
);
|
||||
|
||||
$expandedLinks = preg_replace($search,$replace,$links);
|
||||
|
||||
return $expandedLinks;
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _httprequest
|
||||
Purpose: go get the http data from the server
|
||||
Input: $url the url to fetch
|
||||
$fp the current open file pointer
|
||||
$URI the full URI
|
||||
$body body contents to send if any (POST)
|
||||
Output:
|
||||
\*======================================================================*/
|
||||
|
||||
function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
|
||||
{
|
||||
if($this->passcookies && $this->_redirectaddr)
|
||||
$this->setcookies();
|
||||
|
||||
$URI_PARTS = parse_url($URI);
|
||||
if(empty($url))
|
||||
$url = "/";
|
||||
$headers = $http_method." ".$url." ".$this->_httpversion."\r\n";
|
||||
if(!empty($this->agent))
|
||||
$headers .= "User-Agent: ".$this->agent."\r\n";
|
||||
if(!empty($this->host) && !isset($this->rawheaders['Host']))
|
||||
$headers .= "Host: ".$this->host."\r\n";
|
||||
if(!empty($this->accept))
|
||||
$headers .= "Accept: ".$this->accept."\r\n";
|
||||
|
||||
if($this->use_gzip) {
|
||||
// make sure PHP was built with --with-zlib
|
||||
// and we can handle gzipp'ed data
|
||||
if ( function_exists(gzinflate) ) {
|
||||
$headers .= "Accept-encoding: gzip\r\n";
|
||||
}
|
||||
else {
|
||||
trigger_error(
|
||||
"use_gzip is on, but PHP was built without zlib support.".
|
||||
" Requesting file(s) without gzip encoding.",
|
||||
E_USER_NOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
if(!empty($this->referer))
|
||||
$headers .= "Referer: ".$this->referer."\r\n";
|
||||
if(!empty($this->cookies))
|
||||
{
|
||||
if(!is_array($this->cookies))
|
||||
$this->cookies = (array)$this->cookies;
|
||||
|
||||
reset($this->cookies);
|
||||
if ( count($this->cookies) > 0 ) {
|
||||
$cookie_headers .= 'Cookie: ';
|
||||
foreach ( $this->cookies as $cookieKey => $cookieVal ) {
|
||||
$cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
|
||||
}
|
||||
$headers .= substr($cookie_headers,0,-2) . "\r\n";
|
||||
}
|
||||
}
|
||||
if(!empty($this->rawheaders))
|
||||
{
|
||||
if(!is_array($this->rawheaders))
|
||||
$this->rawheaders = (array)$this->rawheaders;
|
||||
while(list($headerKey,$headerVal) = each($this->rawheaders))
|
||||
$headers .= $headerKey.": ".$headerVal."\r\n";
|
||||
}
|
||||
if(!empty($content_type)) {
|
||||
$headers .= "Content-type: $content_type";
|
||||
if ($content_type == "multipart/form-data")
|
||||
$headers .= "; boundary=".$this->_mime_boundary;
|
||||
$headers .= "\r\n";
|
||||
}
|
||||
if(!empty($body))
|
||||
$headers .= "Content-length: ".strlen($body)."\r\n";
|
||||
if(!empty($this->user) || !empty($this->pass))
|
||||
$headers .= "Authorization: BASIC ".base64_encode($this->user.":".$this->pass)."\r\n";
|
||||
|
||||
$headers .= "\r\n";
|
||||
|
||||
// set the read timeout if needed
|
||||
if ($this->read_timeout > 0)
|
||||
socket_set_timeout($fp, $this->read_timeout);
|
||||
$this->timed_out = false;
|
||||
|
||||
fwrite($fp,$headers.$body,strlen($headers.$body));
|
||||
|
||||
$this->_redirectaddr = false;
|
||||
unset($this->headers);
|
||||
|
||||
// content was returned gzip encoded?
|
||||
$is_gzipped = false;
|
||||
|
||||
while($currentHeader = fgets($fp,$this->_maxlinelen))
|
||||
{
|
||||
if ($this->read_timeout > 0 && $this->_check_timeout($fp))
|
||||
{
|
||||
$this->status=-100;
|
||||
return false;
|
||||
}
|
||||
|
||||
// if($currentHeader == "\r\n")
|
||||
if(preg_match("/^\r?\n$/", $currentHeader) )
|
||||
break;
|
||||
|
||||
// if a header begins with Location: or URI:, set the redirect
|
||||
if(preg_match("/^(Location:|URI:)/i",$currentHeader))
|
||||
{
|
||||
// get URL portion of the redirect
|
||||
preg_match("/^(Location:|URI:)\s+(.*)/",chop($currentHeader),$matches);
|
||||
// look for :// in the Location header to see if hostname is included
|
||||
if(!preg_match("|\:\/\/|",$matches[2]))
|
||||
{
|
||||
// no host in the path, so prepend
|
||||
$this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
|
||||
// eliminate double slash
|
||||
if(!preg_match("|^/|",$matches[2]))
|
||||
$this->_redirectaddr .= "/".$matches[2];
|
||||
else
|
||||
$this->_redirectaddr .= $matches[2];
|
||||
}
|
||||
else
|
||||
$this->_redirectaddr = $matches[2];
|
||||
}
|
||||
|
||||
if(preg_match("|^HTTP/|",$currentHeader))
|
||||
{
|
||||
if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
|
||||
{
|
||||
$this->status= $status[1];
|
||||
}
|
||||
$this->response_code = $currentHeader;
|
||||
}
|
||||
|
||||
if (preg_match("/Content-Encoding: gzip/", $currentHeader) ) {
|
||||
$is_gzipped = true;
|
||||
}
|
||||
|
||||
$this->headers[] = $currentHeader;
|
||||
}
|
||||
|
||||
# $results = fread($fp, $this->maxlength);
|
||||
$results = "";
|
||||
while ( $data = fread($fp, $this->maxlength) ) {
|
||||
$results .= $data;
|
||||
if (
|
||||
strlen($results) > $this->maxlength ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// gunzip
|
||||
if ( $is_gzipped ) {
|
||||
// per http://www.php.net/manual/en/function.gzencode.php
|
||||
$results = substr($results, 10);
|
||||
$results = gzinflate($results);
|
||||
}
|
||||
|
||||
if ($this->read_timeout > 0 && $this->_check_timeout($fp))
|
||||
{
|
||||
$this->status=-100;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if there is a a redirect meta tag
|
||||
|
||||
if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
|
||||
{
|
||||
$this->_redirectaddr = $this->_expandlinks($match[1],$URI);
|
||||
}
|
||||
|
||||
// have we hit our frame depth and is there frame src to fetch?
|
||||
if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
|
||||
{
|
||||
$this->results[] = $results;
|
||||
for($x=0; $x<count($match[1]); $x++)
|
||||
$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
|
||||
}
|
||||
// have we already fetched framed content?
|
||||
elseif(is_array($this->results))
|
||||
$this->results[] = $results;
|
||||
// no framed content
|
||||
else
|
||||
$this->results = $results;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _httpsrequest
|
||||
Purpose: go get the https data from the server using curl
|
||||
Input: $url the url to fetch
|
||||
$URI the full URI
|
||||
$body body contents to send if any (POST)
|
||||
Output:
|
||||
\*======================================================================*/
|
||||
|
||||
function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")
|
||||
{
|
||||
if($this->passcookies && $this->_redirectaddr)
|
||||
$this->setcookies();
|
||||
|
||||
$headers = array();
|
||||
|
||||
$URI_PARTS = parse_url($URI);
|
||||
if(empty($url))
|
||||
$url = "/";
|
||||
// GET ... header not needed for curl
|
||||
//$headers[] = $http_method." ".$url." ".$this->_httpversion;
|
||||
if(!empty($this->agent))
|
||||
$headers[] = "User-Agent: ".$this->agent;
|
||||
if(!empty($this->host))
|
||||
$headers[] = "Host: ".$this->host;
|
||||
if(!empty($this->accept))
|
||||
$headers[] = "Accept: ".$this->accept;
|
||||
if(!empty($this->referer))
|
||||
$headers[] = "Referer: ".$this->referer;
|
||||
if(!empty($this->cookies))
|
||||
{
|
||||
if(!is_array($this->cookies))
|
||||
$this->cookies = (array)$this->cookies;
|
||||
|
||||
reset($this->cookies);
|
||||
if ( count($this->cookies) > 0 ) {
|
||||
$cookie_str = 'Cookie: ';
|
||||
foreach ( $this->cookies as $cookieKey => $cookieVal ) {
|
||||
$cookie_str .= $cookieKey."=".urlencode($cookieVal)."; ";
|
||||
}
|
||||
$headers[] = substr($cookie_str,0,-2);
|
||||
}
|
||||
}
|
||||
if(!empty($this->rawheaders))
|
||||
{
|
||||
if(!is_array($this->rawheaders))
|
||||
$this->rawheaders = (array)$this->rawheaders;
|
||||
while(list($headerKey,$headerVal) = each($this->rawheaders))
|
||||
$headers[] = $headerKey.": ".$headerVal;
|
||||
}
|
||||
if(!empty($content_type)) {
|
||||
if ($content_type == "multipart/form-data")
|
||||
$headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary;
|
||||
else
|
||||
$headers[] = "Content-type: $content_type";
|
||||
}
|
||||
if(!empty($body))
|
||||
$headers[] = "Content-length: ".strlen($body);
|
||||
if(!empty($this->user) || !empty($this->pass))
|
||||
$headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass);
|
||||
|
||||
for($curr_header = 0; $curr_header < count($headers); $curr_header++) {
|
||||
$cmdline_params .= " -H \"".$headers[$curr_header]."\"";
|
||||
}
|
||||
|
||||
if(!empty($body))
|
||||
$cmdline_params .= " -d \"$body\"";
|
||||
|
||||
if($this->read_timeout > 0)
|
||||
$cmdline_params .= " -m ".$this->read_timeout;
|
||||
|
||||
$headerfile = uniqid(time());
|
||||
|
||||
# accept self-signed certs
|
||||
$cmdline_params .= " -k";
|
||||
exec($this->curl_path." -D \"/tmp/$headerfile\"".escapeshellcmd($cmdline_params)." ".escapeshellcmd($URI),$results,$return);
|
||||
|
||||
if($return)
|
||||
{
|
||||
$this->error = "Error: cURL could not retrieve the document, error $return.";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$results = implode("\r\n",$results);
|
||||
|
||||
$result_headers = file("/tmp/$headerfile");
|
||||
|
||||
$this->_redirectaddr = false;
|
||||
unset($this->headers);
|
||||
|
||||
for($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++)
|
||||
{
|
||||
|
||||
// if a header begins with Location: or URI:, set the redirect
|
||||
if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader]))
|
||||
{
|
||||
// get URL portion of the redirect
|
||||
preg_match("/^(Location: |URI:)(.*)/",chop($result_headers[$currentHeader]),$matches);
|
||||
// look for :// in the Location header to see if hostname is included
|
||||
if(!preg_match("|\:\/\/|",$matches[2]))
|
||||
{
|
||||
// no host in the path, so prepend
|
||||
$this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
|
||||
// eliminate double slash
|
||||
if(!preg_match("|^/|",$matches[2]))
|
||||
$this->_redirectaddr .= "/".$matches[2];
|
||||
else
|
||||
$this->_redirectaddr .= $matches[2];
|
||||
}
|
||||
else
|
||||
$this->_redirectaddr = $matches[2];
|
||||
}
|
||||
|
||||
if(preg_match("|^HTTP/|",$result_headers[$currentHeader]))
|
||||
{
|
||||
$this->response_code = $result_headers[$currentHeader];
|
||||
if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$this->response_code, $match))
|
||||
{
|
||||
$this->status= $match[1];
|
||||
}
|
||||
}
|
||||
$this->headers[] = $result_headers[$currentHeader];
|
||||
}
|
||||
|
||||
// check if there is a a redirect meta tag
|
||||
|
||||
if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]+URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
|
||||
{
|
||||
$this->_redirectaddr = $this->_expandlinks($match[1],$URI);
|
||||
}
|
||||
|
||||
// have we hit our frame depth and is there frame src to fetch?
|
||||
if(($this->_framedepth < $this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
|
||||
{
|
||||
$this->results[] = $results;
|
||||
for($x=0; $x<count($match[1]); $x++)
|
||||
$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
|
||||
}
|
||||
// have we already fetched framed content?
|
||||
elseif(is_array($this->results))
|
||||
$this->results[] = $results;
|
||||
// no framed content
|
||||
else
|
||||
$this->results = $results;
|
||||
|
||||
unlink("/tmp/$headerfile");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: setcookies()
|
||||
Purpose: set cookies for a redirection
|
||||
\*======================================================================*/
|
||||
|
||||
function setcookies()
|
||||
{
|
||||
for($x=0; $x<count($this->headers); $x++)
|
||||
{
|
||||
if(preg_match("/^set-cookie:[\s]+([^=]+)=([^;]+)/i", $this->headers[$x],$match))
|
||||
$this->cookies[$match[1]] = $match[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _check_timeout
|
||||
Purpose: checks whether timeout has occurred
|
||||
Input: $fp file pointer
|
||||
\*======================================================================*/
|
||||
|
||||
function _check_timeout($fp)
|
||||
{
|
||||
if ($this->read_timeout > 0) {
|
||||
$fp_status = socket_get_status($fp);
|
||||
if ($fp_status["timed_out"]) {
|
||||
$this->timed_out = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _connect
|
||||
Purpose: make a socket connection
|
||||
Input: $fp file pointer
|
||||
\*======================================================================*/
|
||||
|
||||
function _connect(&$fp)
|
||||
{
|
||||
if(!empty($this->proxy_host) && !empty($this->proxy_port))
|
||||
{
|
||||
$this->_isproxy = true;
|
||||
$host = $this->proxy_host;
|
||||
$port = $this->proxy_port;
|
||||
}
|
||||
else
|
||||
{
|
||||
$host = $this->host;
|
||||
$port = $this->port;
|
||||
}
|
||||
|
||||
$this->status = 0;
|
||||
|
||||
if($fp = fsockopen(
|
||||
$host,
|
||||
$port,
|
||||
$errno,
|
||||
$errstr,
|
||||
$this->_fp_timeout
|
||||
))
|
||||
{
|
||||
// socket connection succeeded
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// socket connection failed
|
||||
$this->status = $errno;
|
||||
switch($errno)
|
||||
{
|
||||
case -3:
|
||||
$this->error="socket creation failed (-3)";
|
||||
case -4:
|
||||
$this->error="dns lookup failure (-4)";
|
||||
case -5:
|
||||
$this->error="connection refused or timed out (-5)";
|
||||
default:
|
||||
$this->error="connection failed (".$errno.")";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*======================================================================*\
|
||||
Function: _disconnect
|
||||
Purpose: disconnect a socket connection
|
||||
Input: $fp file pointer
|
||||
\*======================================================================*/
|
||||
|
||||
function _disconnect($fp)
|
||||
{
|
||||
return(fclose($fp));
|
||||
}
|
||||
|
||||
|
||||
/*======================================================================*\
|
||||
Function: _prepare_post_body
|
||||
Purpose: Prepare post body according to encoding type
|
||||
Input: $formvars - form variables
|
||||
$formfiles - form upload files
|
||||
Output: post body
|
||||
\*======================================================================*/
|
||||
|
||||
function _prepare_post_body($formvars, $formfiles)
|
||||
{
|
||||
settype($formvars, "array");
|
||||
settype($formfiles, "array");
|
||||
|
||||
if (count($formvars) == 0 && count($formfiles) == 0)
|
||||
return;
|
||||
|
||||
switch ($this->_submit_type) {
|
||||
case "application/x-www-form-urlencoded":
|
||||
reset($formvars);
|
||||
while(list($key,$val) = each($formvars)) {
|
||||
if (is_array($val) || is_object($val)) {
|
||||
while (list($cur_key, $cur_val) = each($val)) {
|
||||
$postdata .= urlencode($key)."[]=".urlencode($cur_val)."&";
|
||||
}
|
||||
} else
|
||||
$postdata .= urlencode($key)."=".urlencode($val)."&";
|
||||
}
|
||||
break;
|
||||
|
||||
case "multipart/form-data":
|
||||
$this->_mime_boundary = "Snoopy".md5(uniqid(microtime()));
|
||||
|
||||
reset($formvars);
|
||||
while(list($key,$val) = each($formvars)) {
|
||||
if (is_array($val) || is_object($val)) {
|
||||
while (list($cur_key, $cur_val) = each($val)) {
|
||||
$postdata .= "--".$this->_mime_boundary."\r\n";
|
||||
$postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
|
||||
$postdata .= "$cur_val\r\n";
|
||||
}
|
||||
} else {
|
||||
$postdata .= "--".$this->_mime_boundary."\r\n";
|
||||
$postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
|
||||
$postdata .= "$val\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
reset($formfiles);
|
||||
while (list($field_name, $file_names) = each($formfiles)) {
|
||||
settype($file_names, "array");
|
||||
while (list(, $file_name) = each($file_names)) {
|
||||
if (!is_readable($file_name)) continue;
|
||||
|
||||
$fp = fopen($file_name, "r");
|
||||
$file_content = fread($fp, filesize($file_name));
|
||||
fclose($fp);
|
||||
$base_name = basename($file_name);
|
||||
|
||||
$postdata .= "--".$this->_mime_boundary."\r\n";
|
||||
$postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";
|
||||
$postdata .= "$file_content\r\n";
|
||||
}
|
||||
}
|
||||
$postdata .= "--".$this->_mime_boundary."--\r\n";
|
||||
break;
|
||||
}
|
||||
|
||||
return $postdata;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
200
production/classes/magpie/rss_cache.inc
Normal file
200
production/classes/magpie/rss_cache.inc
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/*
|
||||
* Project: MagpieRSS: a simple RSS integration tool
|
||||
* File: rss_cache.inc, a simple, rolling(no GC), cache
|
||||
* for RSS objects, keyed on URL.
|
||||
* Author: Kellan Elliott-McCrea <kellan@protest.net>
|
||||
* Version: 0.51
|
||||
* License: GPL
|
||||
*
|
||||
* The lastest version of MagpieRSS can be obtained from:
|
||||
* http://magpierss.sourceforge.net
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Magpie mailing list:
|
||||
* http://lists.sourceforge.net/lists/listinfo/magpierss-general
|
||||
*
|
||||
*/
|
||||
|
||||
class RSSCache {
|
||||
var $BASE_CACHE = './cache'; // where the cache files are stored
|
||||
var $MAX_AGE = 3600; // when are files stale, default one hour
|
||||
var $ERROR = ""; // accumulate error messages
|
||||
|
||||
function RSSCache ($base='', $age='') {
|
||||
if ( $base ) {
|
||||
$this->BASE_CACHE = $base;
|
||||
}
|
||||
if ( $age ) {
|
||||
$this->MAX_AGE = $age;
|
||||
}
|
||||
|
||||
// attempt to make the cache directory
|
||||
if ( ! file_exists( $this->BASE_CACHE ) ) {
|
||||
$status = @mkdir( $this->BASE_CACHE, 0755 );
|
||||
|
||||
// if make failed
|
||||
if ( ! $status ) {
|
||||
$this->error(
|
||||
"Cache couldn't make dir '" . $this->BASE_CACHE . "'."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: set
|
||||
Purpose: add an item to the cache, keyed on url
|
||||
Input: url from wich the rss file was fetched
|
||||
Output: true on sucess
|
||||
\*=======================================================================*/
|
||||
function set ($url, $rss) {
|
||||
$this->ERROR = "";
|
||||
$cache_file = $this->file_name( $url );
|
||||
$fp = @fopen( $cache_file, 'w' );
|
||||
|
||||
if ( ! $fp ) {
|
||||
$this->error(
|
||||
"Cache unable to open file for writing: $cache_file"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
$data = $this->serialize( $rss );
|
||||
fwrite( $fp, $data );
|
||||
fclose( $fp );
|
||||
|
||||
return $cache_file;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: get
|
||||
Purpose: fetch an item from the cache
|
||||
Input: url from wich the rss file was fetched
|
||||
Output: cached object on HIT, false on MISS
|
||||
\*=======================================================================*/
|
||||
function get ($url) {
|
||||
$this->ERROR = "";
|
||||
$cache_file = $this->file_name( $url );
|
||||
|
||||
if ( ! file_exists( $cache_file ) ) {
|
||||
$this->debug(
|
||||
"Cache doesn't contain: $url (cache file: $cache_file)"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
$fp = @fopen($cache_file, 'r');
|
||||
if ( ! $fp ) {
|
||||
$this->error(
|
||||
"Failed to open cache file for reading: $cache_file"
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($filesize = filesize($cache_file) ) {
|
||||
$data = fread( $fp, filesize($cache_file) );
|
||||
$rss = $this->unserialize( $data );
|
||||
|
||||
return $rss;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: check_cache
|
||||
Purpose: check a url for membership in the cache
|
||||
and whether the object is older then MAX_AGE (ie. STALE)
|
||||
Input: url from wich the rss file was fetched
|
||||
Output: cached object on HIT, false on MISS
|
||||
\*=======================================================================*/
|
||||
function check_cache ( $url ) {
|
||||
$this->ERROR = "";
|
||||
$filename = $this->file_name( $url );
|
||||
|
||||
if ( file_exists( $filename ) ) {
|
||||
// find how long ago the file was added to the cache
|
||||
// and whether that is longer then MAX_AGE
|
||||
$mtime = filemtime( $filename );
|
||||
$age = time() - $mtime;
|
||||
if ( $this->MAX_AGE > $age ) {
|
||||
// object exists and is current
|
||||
return 'HIT';
|
||||
}
|
||||
else {
|
||||
// object exists but is old
|
||||
return 'STALE';
|
||||
}
|
||||
}
|
||||
else {
|
||||
// object does not exist
|
||||
return 'MISS';
|
||||
}
|
||||
}
|
||||
|
||||
function cache_age( $cache_key ) {
|
||||
$filename = $this->file_name( $url );
|
||||
if ( file_exists( $filename ) ) {
|
||||
$mtime = filemtime( $filename );
|
||||
$age = time() - $mtime;
|
||||
return $age;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: serialize
|
||||
\*=======================================================================*/
|
||||
function serialize ( $rss ) {
|
||||
return serialize( $rss );
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: unserialize
|
||||
\*=======================================================================*/
|
||||
function unserialize ( $data ) {
|
||||
return unserialize( $data );
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: file_name
|
||||
Purpose: map url to location in cache
|
||||
Input: url from wich the rss file was fetched
|
||||
Output: a file name
|
||||
\*=======================================================================*/
|
||||
function file_name ($url) {
|
||||
$filename = md5( $url );
|
||||
return join( DIRECTORY_SEPARATOR, array( $this->BASE_CACHE, $filename ) );
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: error
|
||||
Purpose: register error
|
||||
\*=======================================================================*/
|
||||
function error ($errormsg, $lvl=E_USER_WARNING) {
|
||||
// append PHP's error message if track_errors enabled
|
||||
if ( isset($php_errormsg) ) {
|
||||
$errormsg .= " ($php_errormsg)";
|
||||
}
|
||||
$this->ERROR = $errormsg;
|
||||
if ( MAGPIE_DEBUG ) {
|
||||
trigger_error( $errormsg, $lvl);
|
||||
}
|
||||
else {
|
||||
error_log( $errormsg, 0);
|
||||
}
|
||||
}
|
||||
|
||||
function debug ($debugmsg, $lvl=E_USER_NOTICE) {
|
||||
if ( MAGPIE_DEBUG ) {
|
||||
$this->error("MagpieRSS [debug] $debugmsg", $lvl);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
458
production/classes/magpie/rss_fetch.inc
Normal file
458
production/classes/magpie/rss_fetch.inc
Normal file
@@ -0,0 +1,458 @@
|
||||
<?php
|
||||
/*
|
||||
* Project: MagpieRSS: a simple RSS integration tool
|
||||
* File: rss_fetch.inc, a simple functional interface
|
||||
to fetching and parsing RSS files, via the
|
||||
function fetch_rss()
|
||||
* Author: Kellan Elliott-McCrea <kellan@protest.net>
|
||||
* License: GPL
|
||||
*
|
||||
* The lastest version of MagpieRSS can be obtained from:
|
||||
* http://magpierss.sourceforge.net
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Magpie mailing list:
|
||||
* magpierss-general@lists.sourceforge.net
|
||||
*
|
||||
*/
|
||||
|
||||
// Setup MAGPIE_DIR for use on hosts that don't include
|
||||
// the current path in include_path.
|
||||
// with thanks to rajiv and smarty
|
||||
if (!defined('DIRECTORY_SEPARATOR')) {
|
||||
define('DIRECTORY_SEPARATOR', DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
if (!defined('MAGPIE_DIR')) {
|
||||
define('MAGPIE_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR);
|
||||
}
|
||||
|
||||
require_once( MAGPIE_DIR . 'rss_parse.inc' );
|
||||
require_once( MAGPIE_DIR . 'rss_cache.inc' );
|
||||
|
||||
// for including 3rd party libraries
|
||||
define('MAGPIE_EXTLIB', MAGPIE_DIR . 'extlib' . DIRECTORY_SEPARATOR);
|
||||
require_once( MAGPIE_EXTLIB . 'Snoopy.class.inc');
|
||||
|
||||
|
||||
/*
|
||||
* CONSTANTS - redefine these in your script to change the
|
||||
* behaviour of fetch_rss() currently, most options effect the cache
|
||||
*
|
||||
* MAGPIE_CACHE_ON - Should Magpie cache parsed RSS objects?
|
||||
* For me a built in cache was essential to creating a "PHP-like"
|
||||
* feel to Magpie, see rss_cache.inc for rationale
|
||||
*
|
||||
*
|
||||
* MAGPIE_CACHE_DIR - Where should Magpie cache parsed RSS objects?
|
||||
* This should be a location that the webserver can write to. If this
|
||||
* directory does not already exist Mapie will try to be smart and create
|
||||
* it. This will often fail for permissions reasons.
|
||||
*
|
||||
*
|
||||
* MAGPIE_CACHE_AGE - How long to store cached RSS objects? In seconds.
|
||||
*
|
||||
*
|
||||
* MAGPIE_CACHE_FRESH_ONLY - If remote fetch fails, throw error
|
||||
* instead of returning stale object?
|
||||
*
|
||||
* MAGPIE_DEBUG - Display debugging notices?
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: fetch_rss:
|
||||
Purpose: return RSS object for the give url
|
||||
maintain the cache
|
||||
Input: url of RSS file
|
||||
Output: parsed RSS object (see rss_parse.inc)
|
||||
|
||||
NOTES ON CACHEING:
|
||||
If caching is on (MAGPIE_CACHE_ON) fetch_rss will first check the cache.
|
||||
|
||||
NOTES ON RETRIEVING REMOTE FILES:
|
||||
If conditional gets are on (MAGPIE_CONDITIONAL_GET_ON) fetch_rss will
|
||||
return a cached object, and touch the cache object upon recieving a
|
||||
304.
|
||||
|
||||
NOTES ON FAILED REQUESTS:
|
||||
If there is an HTTP error while fetching an RSS object, the cached
|
||||
version will be return, if it exists (and if MAGPIE_CACHE_FRESH_ONLY is off)
|
||||
\*=======================================================================*/
|
||||
|
||||
define('MAGPIE_VERSION', '0.72');
|
||||
|
||||
$MAGPIE_ERROR = "";
|
||||
|
||||
function fetch_rss ($url) {
|
||||
// initialize constants
|
||||
init();
|
||||
|
||||
if ( !isset($url) ) {
|
||||
error("fetch_rss called without a url");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if cache is disabled
|
||||
if ( !MAGPIE_CACHE_ON ) {
|
||||
// fetch file, and parse it
|
||||
$resp = _fetch_remote_file( $url );
|
||||
if ( is_success( $resp->status ) ) {
|
||||
return _response_to_rss( $resp );
|
||||
}
|
||||
else {
|
||||
error("Failed to fetch $url and cache is off");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// else cache is ON
|
||||
else {
|
||||
// Flow
|
||||
// 1. check cache
|
||||
// 2. if there is a hit, make sure its fresh
|
||||
// 3. if cached obj fails freshness check, fetch remote
|
||||
// 4. if remote fails, return stale object, or error
|
||||
|
||||
$cache = new RSSCache( MAGPIE_CACHE_DIR, MAGPIE_CACHE_AGE );
|
||||
|
||||
if (MAGPIE_DEBUG and $cache->ERROR) {
|
||||
debug($cache->ERROR, E_USER_WARNING);
|
||||
}
|
||||
|
||||
|
||||
$cache_status = 0; // response of check_cache
|
||||
$request_headers = array(); // HTTP headers to send with fetch
|
||||
$rss = 0; // parsed RSS object
|
||||
$errormsg = 0; // errors, if any
|
||||
|
||||
// store parsed XML by desired output encoding
|
||||
// as character munging happens at parse time
|
||||
$cache_key = $url . MAGPIE_OUTPUT_ENCODING;
|
||||
|
||||
if (!$cache->ERROR) {
|
||||
// return cache HIT, MISS, or STALE
|
||||
$cache_status = $cache->check_cache( $cache_key);
|
||||
}
|
||||
|
||||
// if object cached, and cache is fresh, return cached obj
|
||||
if ( $cache_status == 'HIT' ) {
|
||||
$rss = $cache->get( $cache_key );
|
||||
if ( isset($rss) and $rss ) {
|
||||
// should be cache age
|
||||
$rss->from_cache = 1;
|
||||
if ( MAGPIE_DEBUG > 1) {
|
||||
debug("MagpieRSS: Cache HIT", E_USER_NOTICE);
|
||||
}
|
||||
return $rss;
|
||||
}
|
||||
}
|
||||
|
||||
// else attempt a conditional get
|
||||
|
||||
// setup headers
|
||||
if ( $cache_status == 'STALE' ) {
|
||||
$rss = $cache->get( $cache_key );
|
||||
if ( $rss and $rss->etag and $rss->last_modified ) {
|
||||
$request_headers['If-None-Match'] = $rss->etag;
|
||||
$request_headers['If-Last-Modified'] = $rss->last_modified;
|
||||
}
|
||||
}
|
||||
|
||||
$resp = _fetch_remote_file( $url, $request_headers );
|
||||
|
||||
if (isset($resp) and $resp) {
|
||||
if ($resp->status == '304' ) {
|
||||
// we have the most current copy
|
||||
if ( MAGPIE_DEBUG > 1) {
|
||||
debug("Got 304 for $url");
|
||||
}
|
||||
// reset cache on 304 (at minutillo insistent prodding)
|
||||
$cache->set($cache_key, $rss);
|
||||
return $rss;
|
||||
}
|
||||
elseif ( is_success( $resp->status ) ) {
|
||||
$rss = _response_to_rss( $resp );
|
||||
if ( $rss ) {
|
||||
if (MAGPIE_DEBUG > 1) {
|
||||
debug("Fetch successful");
|
||||
}
|
||||
// add object to cache
|
||||
$cache->set( $cache_key, $rss );
|
||||
return $rss;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$errormsg = "Failed to fetch $url ";
|
||||
if ( $resp->status == '-100' ) {
|
||||
$errormsg .= "(Request timed out after " . MAGPIE_FETCH_TIME_OUT . " seconds)";
|
||||
}
|
||||
elseif ( $resp->error ) {
|
||||
# compensate for Snoopy's annoying habbit to tacking
|
||||
# on '\n'
|
||||
$http_error = substr($resp->error, 0, -2);
|
||||
$errormsg .= "(HTTP Error: $http_error)";
|
||||
}
|
||||
else {
|
||||
$errormsg .= "(HTTP Response: " . $resp->response_code .')';
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$errormsg = "Unable to retrieve RSS file for unknown reasons.";
|
||||
}
|
||||
|
||||
// else fetch failed
|
||||
|
||||
// attempt to return cached object
|
||||
if ($rss) {
|
||||
if ( MAGPIE_DEBUG ) {
|
||||
debug("Returning STALE object for $url");
|
||||
}
|
||||
return $rss;
|
||||
}
|
||||
|
||||
// else we totally failed
|
||||
error( $errormsg );
|
||||
|
||||
return false;
|
||||
|
||||
} // end if ( !MAGPIE_CACHE_ON ) {
|
||||
} // end fetch_rss()
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: error
|
||||
Purpose: set MAGPIE_ERROR, and trigger error
|
||||
\*=======================================================================*/
|
||||
|
||||
function error ($errormsg, $lvl=E_USER_WARNING) {
|
||||
global $MAGPIE_ERROR;
|
||||
|
||||
// append PHP's error message if track_errors enabled
|
||||
if ( isset($php_errormsg) ) {
|
||||
$errormsg .= " ($php_errormsg)";
|
||||
}
|
||||
if ( $errormsg ) {
|
||||
$errormsg = "MagpieRSS: $errormsg";
|
||||
$MAGPIE_ERROR = $errormsg;
|
||||
trigger_error( $errormsg, $lvl);
|
||||
}
|
||||
}
|
||||
|
||||
function debug ($debugmsg, $lvl=E_USER_NOTICE) {
|
||||
trigger_error("MagpieRSS [debug] $debugmsg", $lvl);
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: magpie_error
|
||||
Purpose: accessor for the magpie error variable
|
||||
\*=======================================================================*/
|
||||
function magpie_error ($errormsg="") {
|
||||
global $MAGPIE_ERROR;
|
||||
|
||||
if ( isset($errormsg) and $errormsg ) {
|
||||
$MAGPIE_ERROR = $errormsg;
|
||||
}
|
||||
|
||||
return $MAGPIE_ERROR;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: _fetch_remote_file
|
||||
Purpose: retrieve an arbitrary remote file
|
||||
Input: url of the remote file
|
||||
headers to send along with the request (optional)
|
||||
Output: an HTTP response object (see Snoopy.class.inc)
|
||||
\*=======================================================================*/
|
||||
function _fetch_remote_file ($url, $headers = "" ) {
|
||||
// Snoopy is an HTTP client in PHP
|
||||
$client = new Snoopy();
|
||||
$client->agent = MAGPIE_USER_AGENT;
|
||||
$client->read_timeout = MAGPIE_FETCH_TIME_OUT;
|
||||
$client->use_gzip = MAGPIE_USE_GZIP;
|
||||
if (is_array($headers) ) {
|
||||
$client->rawheaders = $headers;
|
||||
}
|
||||
|
||||
@$client->fetch($url);
|
||||
return $client;
|
||||
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: _response_to_rss
|
||||
Purpose: parse an HTTP response object into an RSS object
|
||||
Input: an HTTP response object (see Snoopy)
|
||||
Output: parsed RSS object (see rss_parse)
|
||||
\*=======================================================================*/
|
||||
function _response_to_rss ($resp) {
|
||||
$rss = new MagpieRSS( $resp->results, MAGPIE_OUTPUT_ENCODING, MAGPIE_INPUT_ENCODING, MAGPIE_DETECT_ENCODING );
|
||||
|
||||
// if RSS parsed successfully
|
||||
if ( $rss and !$rss->ERROR) {
|
||||
|
||||
// find Etag, and Last-Modified
|
||||
foreach($resp->headers as $h) {
|
||||
// 2003-03-02 - Nicola Asuni (www.tecnick.com) - fixed bug "Undefined offset: 1"
|
||||
if (strpos($h, ": ")) {
|
||||
list($field, $val) = explode(": ", $h, 2);
|
||||
}
|
||||
else {
|
||||
$field = $h;
|
||||
$val = "";
|
||||
}
|
||||
|
||||
if ( $field == 'ETag' ) {
|
||||
$rss->etag = $val;
|
||||
}
|
||||
|
||||
if ( $field == 'Last-Modified' ) {
|
||||
$rss->last_modified = $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $rss;
|
||||
} // else construct error message
|
||||
else {
|
||||
$errormsg = "Failed to parse RSS file.";
|
||||
|
||||
if ($rss) {
|
||||
$errormsg .= " (" . $rss->ERROR . ")";
|
||||
}
|
||||
error($errormsg);
|
||||
|
||||
return false;
|
||||
} // end if ($rss and !$rss->error)
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: init
|
||||
Purpose: setup constants with default values
|
||||
check for user overrides
|
||||
\*=======================================================================*/
|
||||
function init () {
|
||||
if ( defined('MAGPIE_INITALIZED') ) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
define('MAGPIE_INITALIZED', true);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_CACHE_ON') ) {
|
||||
define('MAGPIE_CACHE_ON', true);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_CACHE_DIR') ) {
|
||||
define('MAGPIE_CACHE_DIR', './cache');
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_CACHE_AGE') ) {
|
||||
define('MAGPIE_CACHE_AGE', 60*60); // one hour
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_CACHE_FRESH_ONLY') ) {
|
||||
define('MAGPIE_CACHE_FRESH_ONLY', false);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_OUTPUT_ENCODING') ) {
|
||||
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_INPUT_ENCODING') ) {
|
||||
define('MAGPIE_INPUT_ENCODING', null);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_DETECT_ENCODING') ) {
|
||||
define('MAGPIE_DETECT_ENCODING', true);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_DEBUG') ) {
|
||||
define('MAGPIE_DEBUG', 0);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_USER_AGENT') ) {
|
||||
$ua = 'MagpieRSS/'. MAGPIE_VERSION . ' (+http://magpierss.sf.net';
|
||||
|
||||
if ( MAGPIE_CACHE_ON ) {
|
||||
$ua = $ua . ')';
|
||||
}
|
||||
else {
|
||||
$ua = $ua . '; No cache)';
|
||||
}
|
||||
|
||||
define('MAGPIE_USER_AGENT', $ua);
|
||||
}
|
||||
|
||||
if ( !defined('MAGPIE_FETCH_TIME_OUT') ) {
|
||||
define('MAGPIE_FETCH_TIME_OUT', 5); // 5 second timeout
|
||||
}
|
||||
|
||||
// use gzip encoding to fetch rss files if supported?
|
||||
if ( !defined('MAGPIE_USE_GZIP') ) {
|
||||
define('MAGPIE_USE_GZIP', true);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: the following code should really be in Snoopy, or at least
|
||||
// somewhere other then rss_fetch!
|
||||
|
||||
/*=======================================================================*\
|
||||
HTTP STATUS CODE PREDICATES
|
||||
These functions attempt to classify an HTTP status code
|
||||
based on RFC 2616 and RFC 2518.
|
||||
|
||||
All of them take an HTTP status code as input, and return true or false
|
||||
|
||||
All this code is adapted from LWP's HTTP::Status.
|
||||
\*=======================================================================*/
|
||||
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: is_info
|
||||
Purpose: return true if Informational status code
|
||||
\*=======================================================================*/
|
||||
function is_info ($sc) {
|
||||
return $sc >= 100 && $sc < 200;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: is_success
|
||||
Purpose: return true if Successful status code
|
||||
\*=======================================================================*/
|
||||
function is_success ($sc) {
|
||||
return $sc >= 200 && $sc < 300;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: is_redirect
|
||||
Purpose: return true if Redirection status code
|
||||
\*=======================================================================*/
|
||||
function is_redirect ($sc) {
|
||||
return $sc >= 300 && $sc < 400;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: is_error
|
||||
Purpose: return true if Error status code
|
||||
\*=======================================================================*/
|
||||
function is_error ($sc) {
|
||||
return $sc >= 400 && $sc < 600;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: is_client_error
|
||||
Purpose: return true if Error status code, and its a client error
|
||||
\*=======================================================================*/
|
||||
function is_client_error ($sc) {
|
||||
return $sc >= 400 && $sc < 500;
|
||||
}
|
||||
|
||||
/*=======================================================================*\
|
||||
Function: is_client_error
|
||||
Purpose: return true if Error status code, and its a server error
|
||||
\*=======================================================================*/
|
||||
function is_server_error ($sc) {
|
||||
return $sc >= 500 && $sc < 600;
|
||||
}
|
||||
|
||||
?>
|
||||
605
production/classes/magpie/rss_parse.inc
Normal file
605
production/classes/magpie/rss_parse.inc
Normal file
@@ -0,0 +1,605 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Project: MagpieRSS: a simple RSS integration tool
|
||||
* File: rss_parse.inc - parse an RSS or Atom feed
|
||||
* return as a simple object.
|
||||
*
|
||||
* Handles RSS 0.9x, RSS 2.0, RSS 1.0, and Atom 0.3
|
||||
*
|
||||
* The lastest version of MagpieRSS can be obtained from:
|
||||
* http://magpierss.sourceforge.net
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Magpie mailing list:
|
||||
* magpierss-general@lists.sourceforge.net
|
||||
*
|
||||
* @author Kellan Elliott-McCrea <kellan@protest.net>
|
||||
* @version 0.7a
|
||||
* @license GPL
|
||||
*
|
||||
*/
|
||||
|
||||
define('RSS', 'RSS');
|
||||
define('ATOM', 'Atom');
|
||||
|
||||
require_once (MAGPIE_DIR . 'rss_utils.inc');
|
||||
|
||||
/**
|
||||
* Hybrid parser, and object, takes RSS as a string and returns a simple object.
|
||||
*
|
||||
* see: rss_fetch.inc for a simpler interface with integrated caching support
|
||||
*
|
||||
*/
|
||||
class MagpieRSS {
|
||||
var $parser;
|
||||
|
||||
var $current_item = array(); // item currently being parsed
|
||||
var $items = array(); // collection of parsed items
|
||||
var $channel = array(); // hash of channel fields
|
||||
var $textinput = array();
|
||||
var $image = array();
|
||||
var $feed_type;
|
||||
var $feed_version;
|
||||
var $encoding = ''; // output encoding of parsed rss
|
||||
|
||||
var $_source_encoding = ''; // only set if we have to parse xml prolog
|
||||
|
||||
var $ERROR = "";
|
||||
var $WARNING = "";
|
||||
|
||||
// define some constants
|
||||
|
||||
var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
|
||||
var $_KNOWN_ENCODINGS = array('UTF-8', 'US-ASCII', 'UTF-8');
|
||||
|
||||
// parser variables, useless if you're not a parser, treat as private
|
||||
var $stack = array(); // parser stack
|
||||
var $inchannel = false;
|
||||
var $initem = false;
|
||||
var $incontent = false; // if in Atom <content mode="xml"> field
|
||||
var $intextinput = false;
|
||||
var $inimage = false;
|
||||
var $current_namespace = false;
|
||||
|
||||
|
||||
/**
|
||||
* Set up XML parser, parse source, and return populated RSS object..
|
||||
*
|
||||
* @param string $source string containing the RSS to be parsed
|
||||
*
|
||||
* NOTE: Probably a good idea to leave the encoding options alone unless
|
||||
* you know what you're doing as PHP's character set support is
|
||||
* a little weird.
|
||||
*
|
||||
* NOTE: A lot of this is unnecessary but harmless with PHP5
|
||||
*
|
||||
*
|
||||
* @param string $output_encoding output the parsed RSS in this character
|
||||
* set defaults to ISO-8859-1 as this is PHP's
|
||||
* default.
|
||||
*
|
||||
* NOTE: might be changed to UTF-8 in future
|
||||
* versions.
|
||||
*
|
||||
* @param string $input_encoding the character set of the incoming RSS source.
|
||||
* Leave blank and Magpie will try to figure it
|
||||
* out.
|
||||
*
|
||||
*
|
||||
* @param bool $detect_encoding if false Magpie won't attempt to detect
|
||||
* source encoding. (caveat emptor)
|
||||
*
|
||||
*/
|
||||
function MagpieRSS ($source, $output_encoding='UTF-8',
|
||||
$input_encoding=null, $detect_encoding=true)
|
||||
{
|
||||
# if PHP xml isn't compiled in, die
|
||||
#
|
||||
if (!function_exists('xml_parser_create')) {
|
||||
$this->error( "Failed to load PHP's XML Extension. " .
|
||||
"http://www.php.net/manual/en/ref.xml.php",
|
||||
E_USER_ERROR );
|
||||
}
|
||||
|
||||
list($parser, $source) = $this->create_parser($source,
|
||||
$output_encoding, $input_encoding, $detect_encoding);
|
||||
|
||||
|
||||
if (!is_resource($parser)) {
|
||||
$this->error( "Failed to create an instance of PHP's XML parser. " .
|
||||
"http://www.php.net/manual/en/ref.xml.php",
|
||||
E_USER_ERROR );
|
||||
}
|
||||
|
||||
|
||||
$this->parser = $parser;
|
||||
|
||||
# pass in parser, and a reference to this object
|
||||
# setup handlers
|
||||
#
|
||||
xml_set_object( $this->parser, $this );
|
||||
xml_set_element_handler($this->parser,
|
||||
'feed_start_element', 'feed_end_element' );
|
||||
|
||||
xml_set_character_data_handler( $this->parser, 'feed_cdata' );
|
||||
|
||||
$status = xml_parse( $this->parser, $source );
|
||||
|
||||
if (! $status ) {
|
||||
$errorcode = xml_get_error_code( $this->parser );
|
||||
if ( $errorcode != XML_ERROR_NONE ) {
|
||||
$xml_error = xml_error_string( $errorcode );
|
||||
$error_line = xml_get_current_line_number($this->parser);
|
||||
$error_col = xml_get_current_column_number($this->parser);
|
||||
$errormsg = "$xml_error at line $error_line, column $error_col";
|
||||
|
||||
$this->error( $errormsg );
|
||||
}
|
||||
}
|
||||
|
||||
xml_parser_free( $this->parser );
|
||||
|
||||
$this->normalize();
|
||||
}
|
||||
|
||||
function feed_start_element($p, $element, &$attrs) {
|
||||
$el = $element = strtolower($element);
|
||||
$attrs = array_change_key_case($attrs, CASE_LOWER);
|
||||
|
||||
// check for a namespace, and split if found
|
||||
$ns = false;
|
||||
if ( strpos( $element, ':' ) ) {
|
||||
list($ns, $el) = split( ':', $element, 2);
|
||||
}
|
||||
if ( $ns and $ns != 'rdf' ) {
|
||||
$this->current_namespace = $ns;
|
||||
}
|
||||
|
||||
# if feed type isn't set, then this is first element of feed
|
||||
# identify feed from root element
|
||||
#
|
||||
if (!isset($this->feed_type) ) {
|
||||
if ( $el == 'rdf' ) {
|
||||
$this->feed_type = RSS;
|
||||
$this->feed_version = '1.0';
|
||||
}
|
||||
elseif ( $el == 'rss' ) {
|
||||
$this->feed_type = RSS;
|
||||
$this->feed_version = $attrs['version'];
|
||||
}
|
||||
elseif ( $el == 'feed' ) {
|
||||
$this->feed_type = ATOM;
|
||||
$this->feed_version = $attrs['version'];
|
||||
$this->inchannel = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $el == 'channel' )
|
||||
{
|
||||
$this->inchannel = true;
|
||||
}
|
||||
elseif ($el == 'item' or $el == 'entry' )
|
||||
{
|
||||
$this->initem = true;
|
||||
if ( isset($attrs['rdf:about']) ) {
|
||||
$this->current_item['about'] = $attrs['rdf:about'];
|
||||
}
|
||||
}
|
||||
|
||||
// if we're in the default namespace of an RSS feed,
|
||||
// record textinput or image fields
|
||||
elseif (
|
||||
$this->feed_type == RSS and
|
||||
$this->current_namespace == '' and
|
||||
$el == 'textinput' )
|
||||
{
|
||||
$this->intextinput = true;
|
||||
}
|
||||
|
||||
elseif (
|
||||
$this->feed_type == RSS and
|
||||
$this->current_namespace == '' and
|
||||
$el == 'image' )
|
||||
{
|
||||
$this->inimage = true;
|
||||
}
|
||||
|
||||
# handle atom content constructs
|
||||
elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
|
||||
{
|
||||
// avoid clashing w/ RSS mod_content
|
||||
if ($el == 'content' ) {
|
||||
$el = 'atom_content';
|
||||
}
|
||||
|
||||
$this->incontent = $el;
|
||||
|
||||
|
||||
}
|
||||
|
||||
// if inside an Atom content construct (e.g. content or summary) field treat tags as text
|
||||
elseif ($this->feed_type == ATOM and $this->incontent )
|
||||
{
|
||||
// if tags are inlined, then flatten
|
||||
$attrs_str = join(' ',
|
||||
array_map('map_attrs',
|
||||
array_keys($attrs),
|
||||
array_values($attrs) ) );
|
||||
|
||||
$this->append_content( "<$element $attrs_str>" );
|
||||
|
||||
array_unshift( $this->stack, $el );
|
||||
}
|
||||
|
||||
// Atom support many links per containging element.
|
||||
// Magpie treats link elements of type rel='alternate'
|
||||
// as being equivalent to RSS's simple link element.
|
||||
//
|
||||
elseif ($this->feed_type == ATOM and $el == 'link' )
|
||||
{
|
||||
if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
|
||||
{
|
||||
$link_el = 'link';
|
||||
}
|
||||
else {
|
||||
$link_el = 'link_' . $attrs['rel'];
|
||||
}
|
||||
|
||||
$this->append($link_el, $attrs['href']);
|
||||
}
|
||||
// set stack[0] to current element
|
||||
else {
|
||||
array_unshift($this->stack, $el);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function feed_cdata ($p, $text) {
|
||||
if ($this->feed_type == ATOM and $this->incontent)
|
||||
{
|
||||
$this->append_content( $text );
|
||||
}
|
||||
else {
|
||||
$current_el = join('_', array_reverse($this->stack));
|
||||
$this->append($current_el, $text);
|
||||
}
|
||||
}
|
||||
|
||||
function feed_end_element ($p, $el) {
|
||||
$el = strtolower($el);
|
||||
|
||||
if ( $el == 'item' or $el == 'entry' )
|
||||
{
|
||||
$this->items[] = $this->current_item;
|
||||
$this->current_item = array();
|
||||
$this->initem = false;
|
||||
}
|
||||
elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' )
|
||||
{
|
||||
$this->intextinput = false;
|
||||
}
|
||||
elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' )
|
||||
{
|
||||
$this->inimage = false;
|
||||
}
|
||||
elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
|
||||
{
|
||||
$this->incontent = false;
|
||||
}
|
||||
elseif ($el == 'channel' or $el == 'feed' )
|
||||
{
|
||||
$this->inchannel = false;
|
||||
}
|
||||
elseif ($this->feed_type == ATOM and $this->incontent ) {
|
||||
// balance tags properly
|
||||
// note: i don't think this is actually neccessary
|
||||
if ( $this->stack[0] == $el )
|
||||
{
|
||||
$this->append_content("</$el>");
|
||||
}
|
||||
else {
|
||||
$this->append_content("<$el />");
|
||||
}
|
||||
|
||||
array_shift( $this->stack );
|
||||
}
|
||||
else {
|
||||
array_shift( $this->stack );
|
||||
}
|
||||
|
||||
$this->current_namespace = false;
|
||||
}
|
||||
|
||||
function concat (&$str1, $str2="") {
|
||||
if (!isset($str1) ) {
|
||||
$str1="";
|
||||
}
|
||||
$str1 .= $str2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function append_content($text) {
|
||||
if ( $this->initem ) {
|
||||
$this->concat( $this->current_item[ $this->incontent ], $text );
|
||||
}
|
||||
elseif ( $this->inchannel ) {
|
||||
$this->concat( $this->channel[ $this->incontent ], $text );
|
||||
}
|
||||
}
|
||||
|
||||
// smart append - field and namespace aware
|
||||
function append($el, $text) {
|
||||
if (!$el) {
|
||||
return;
|
||||
}
|
||||
if ( $this->current_namespace )
|
||||
{
|
||||
if ( $this->initem ) {
|
||||
$this->concat(
|
||||
$this->current_item[ $this->current_namespace ][ $el ], $text);
|
||||
}
|
||||
elseif ($this->inchannel) {
|
||||
$this->concat(
|
||||
$this->channel[ $this->current_namespace][ $el ], $text );
|
||||
}
|
||||
elseif ($this->intextinput) {
|
||||
$this->concat(
|
||||
$this->textinput[ $this->current_namespace][ $el ], $text );
|
||||
}
|
||||
elseif ($this->inimage) {
|
||||
$this->concat(
|
||||
$this->image[ $this->current_namespace ][ $el ], $text );
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( $this->initem ) {
|
||||
$this->concat(
|
||||
$this->current_item[ $el ], $text);
|
||||
}
|
||||
elseif ($this->intextinput) {
|
||||
$this->concat(
|
||||
$this->textinput[ $el ], $text );
|
||||
}
|
||||
elseif ($this->inimage) {
|
||||
$this->concat(
|
||||
$this->image[ $el ], $text );
|
||||
}
|
||||
elseif ($this->inchannel) {
|
||||
$this->concat(
|
||||
$this->channel[ $el ], $text );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function normalize () {
|
||||
// if atom populate rss fields
|
||||
if ( $this->is_atom() ) {
|
||||
$this->channel['description'] = $this->channel['tagline'];
|
||||
for ( $i = 0; $i < count($this->items); $i++) {
|
||||
$item = $this->items[$i];
|
||||
if ( isset($item['summary']) )
|
||||
$item['description'] = $item['summary'];
|
||||
if ( isset($item['atom_content']))
|
||||
$item['content']['encoded'] = $item['atom_content'];
|
||||
|
||||
$atom_date = (isset($item['issued']) ) ? $item['issued'] : $item['modified'];
|
||||
if ( $atom_date ) {
|
||||
$epoch = @parse_w3cdtf($atom_date);
|
||||
if ($epoch and $epoch > 0) {
|
||||
$item['date_timestamp'] = $epoch;
|
||||
}
|
||||
}
|
||||
|
||||
$this->items[$i] = $item;
|
||||
}
|
||||
}
|
||||
elseif ( $this->is_rss() ) {
|
||||
$this->channel['tagline'] = $this->channel['description'];
|
||||
for ( $i = 0; $i < count($this->items); $i++) {
|
||||
$item = $this->items[$i];
|
||||
if ( isset($item['description']))
|
||||
$item['summary'] = $item['description'];
|
||||
if ( isset($item['content']['encoded'] ) )
|
||||
$item['atom_content'] = $item['content']['encoded'];
|
||||
|
||||
if ( $this->is_rss() == '1.0' and isset($item['dc']['date']) ) {
|
||||
$epoch = @parse_w3cdtf($item['dc']['date']);
|
||||
if ($epoch and $epoch > 0) {
|
||||
$item['date_timestamp'] = $epoch;
|
||||
}
|
||||
}
|
||||
elseif ( isset($item['pubdate']) ) {
|
||||
$epoch = @strtotime($item['pubdate']);
|
||||
if ($epoch > 0) {
|
||||
$item['date_timestamp'] = $epoch;
|
||||
}
|
||||
}
|
||||
|
||||
$this->items[$i] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function is_rss () {
|
||||
if ( $this->feed_type == RSS ) {
|
||||
return $this->feed_version;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function is_atom() {
|
||||
if ( $this->feed_type == ATOM ) {
|
||||
return $this->feed_version;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return XML parser, and possibly re-encoded source
|
||||
*
|
||||
*/
|
||||
function create_parser($source, $out_enc, $in_enc, $detect) {
|
||||
if ( substr(phpversion(),0,1) == 5) {
|
||||
$parser = $this->php5_create_parser($in_enc, $detect);
|
||||
}
|
||||
else {
|
||||
list($parser, $source) = $this->php4_create_parser($source, $in_enc, $detect);
|
||||
}
|
||||
if ($out_enc) {
|
||||
$this->encoding = $out_enc;
|
||||
xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, $out_enc);
|
||||
}
|
||||
|
||||
return array($parser, $source);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate an XML parser under PHP5
|
||||
*
|
||||
* PHP5 will do a fine job of detecting input encoding
|
||||
* if passed an empty string as the encoding.
|
||||
*
|
||||
* All hail libxml2!
|
||||
*
|
||||
*/
|
||||
function php5_create_parser($in_enc, $detect) {
|
||||
// by default php5 does a fine job of detecting input encodings
|
||||
if(!$detect && $in_enc) {
|
||||
return xml_parser_create($in_enc);
|
||||
}
|
||||
else {
|
||||
return xml_parser_create('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Instaniate an XML parser under PHP4
|
||||
*
|
||||
* Unfortunately PHP4's support for character encodings
|
||||
* and especially XML and character encodings sucks. As
|
||||
* long as the documents you parse only contain characters
|
||||
* from the ISO-8859-1 character set (a superset of ASCII,
|
||||
* and a subset of UTF-8) you're fine. However once you
|
||||
* step out of that comfy little world things get mad, bad,
|
||||
* and dangerous to know.
|
||||
*
|
||||
* The following code is based on SJM's work with FoF
|
||||
* @see http://minutillo.com/steve/weblog/2004/6/17/php-xml-and-character-encodings-a-tale-of-sadness-rage-and-data-loss
|
||||
*
|
||||
*/
|
||||
function php4_create_parser($source, $in_enc, $detect) {
|
||||
if ( !$detect ) {
|
||||
return array(xml_parser_create($in_enc), $source);
|
||||
}
|
||||
|
||||
if (!$in_enc) {
|
||||
if (preg_match('/<?xml.*encoding=[\'"](.*?)[\'"].*?>/m', $source, $m)) {
|
||||
$in_enc = strtoupper($m[1]);
|
||||
$this->source_encoding = $in_enc;
|
||||
}
|
||||
else {
|
||||
$in_enc = 'UTF-8';
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->known_encoding($in_enc)) {
|
||||
return array(xml_parser_create($in_enc), $source);
|
||||
}
|
||||
|
||||
// the dectected encoding is not one of the simple encodings PHP knows
|
||||
|
||||
// attempt to use the iconv extension to
|
||||
// cast the XML to a known encoding
|
||||
// @see http://php.net/iconv
|
||||
|
||||
if (function_exists('iconv')) {
|
||||
$encoded_source = iconv($in_enc,'UTF-8', $source);
|
||||
if ($encoded_source) {
|
||||
return array(xml_parser_create('UTF-8'), $encoded_source);
|
||||
}
|
||||
}
|
||||
|
||||
// iconv didn't work, try mb_convert_encoding
|
||||
// @see http://php.net/mbstring
|
||||
if(function_exists('mb_convert_encoding')) {
|
||||
$encoded_source = mb_convert_encoding($source, 'UTF-8', $in_enc );
|
||||
if ($encoded_source) {
|
||||
return array(xml_parser_create('UTF-8'), $encoded_source);
|
||||
}
|
||||
}
|
||||
|
||||
// else
|
||||
$this->error("Feed is in an unsupported character encoding. ($in_enc) " .
|
||||
"You may see strange artifacts, and mangled characters.",
|
||||
E_USER_NOTICE);
|
||||
|
||||
return array(xml_parser_create(), $source);
|
||||
}
|
||||
|
||||
function known_encoding($enc) {
|
||||
$enc = strtoupper($enc);
|
||||
if ( in_array($enc, $this->_KNOWN_ENCODINGS) ) {
|
||||
return $enc;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function error ($errormsg, $lvl=E_USER_WARNING) {
|
||||
// append PHP's error message if track_errors enabled
|
||||
if ( isset($php_errormsg) ) {
|
||||
$errormsg .= " ($php_errormsg)";
|
||||
}
|
||||
if ( MAGPIE_DEBUG ) {
|
||||
trigger_error( $errormsg, $lvl);
|
||||
}
|
||||
else {
|
||||
error_log( $errormsg, 0);
|
||||
}
|
||||
|
||||
$notices = E_USER_NOTICE|E_NOTICE;
|
||||
if ( $lvl&$notices ) {
|
||||
$this->WARNING = $errormsg;
|
||||
} else {
|
||||
$this->ERROR = $errormsg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end class RSS
|
||||
|
||||
function map_attrs($k, $v) {
|
||||
return "$k=\"$v\"";
|
||||
}
|
||||
|
||||
// patch to support medieval versions of PHP4.1.x,
|
||||
// courtesy, Ryan Currie, ryan@digibliss.com
|
||||
|
||||
if (!function_exists('array_change_key_case')) {
|
||||
define("CASE_UPPER",1);
|
||||
define("CASE_LOWER",0);
|
||||
|
||||
|
||||
function array_change_key_case($array,$case=CASE_LOWER) {
|
||||
if ($case=CASE_LOWER) $cmd=strtolower;
|
||||
elseif ($case=CASE_UPPER) $cmd=strtoupper;
|
||||
foreach($array as $key=>$value) {
|
||||
$output[$cmd($key)]=$value;
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
67
production/classes/magpie/rss_utils.inc
Normal file
67
production/classes/magpie/rss_utils.inc
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
/*
|
||||
* Project: MagpieRSS: a simple RSS integration tool
|
||||
* File: rss_utils.inc, utility methods for working with RSS
|
||||
* Author: Kellan Elliott-McCrea <kellan@protest.net>
|
||||
* Version: 0.51
|
||||
* License: GPL
|
||||
*
|
||||
* The lastest version of MagpieRSS can be obtained from:
|
||||
* http://magpierss.sourceforge.net
|
||||
*
|
||||
* For questions, help, comments, discussion, etc., please join the
|
||||
* Magpie mailing list:
|
||||
* magpierss-general@lists.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
/*======================================================================*\
|
||||
Function: parse_w3cdtf
|
||||
Purpose: parse a W3CDTF date into unix epoch
|
||||
|
||||
NOTE: http://www.w3.org/TR/NOTE-datetime
|
||||
\*======================================================================*/
|
||||
|
||||
function parse_w3cdtf ( $date_str ) {
|
||||
|
||||
# regex to match wc3dtf
|
||||
$pat = "/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(:(\d{2}))?(?:([-+])(\d{2}):?(\d{2})|(Z))?/";
|
||||
|
||||
if ( preg_match( $pat, $date_str, $match ) ) {
|
||||
list( $year, $month, $day, $hours, $minutes, $seconds) =
|
||||
array( $match[1], $match[2], $match[3], $match[4], $match[5], $match[6]);
|
||||
|
||||
# calc epoch for current date assuming GMT
|
||||
$epoch = gmmktime( $hours, $minutes, $seconds, $month, $day, $year);
|
||||
|
||||
$offset = 0;
|
||||
if ( $match[10] == 'Z' ) {
|
||||
# zulu time, aka GMT
|
||||
}
|
||||
else {
|
||||
list( $tz_mod, $tz_hour, $tz_min ) =
|
||||
array( $match[8], $match[9], $match[10]);
|
||||
|
||||
# zero out the variables
|
||||
if ( ! $tz_hour ) { $tz_hour = 0; }
|
||||
if ( ! $tz_min ) { $tz_min = 0; }
|
||||
|
||||
$offset_secs = (($tz_hour*60)+$tz_min)*60;
|
||||
|
||||
# is timezone ahead of GMT? then subtract offset
|
||||
#
|
||||
if ( $tz_mod == '+' ) {
|
||||
$offset_secs = $offset_secs * -1;
|
||||
}
|
||||
|
||||
$offset = $offset_secs;
|
||||
}
|
||||
$epoch = $epoch + $offset;
|
||||
return $epoch;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
80
production/classes/magpie/scripts/magpie_debug.php
Normal file
80
production/classes/magpie/scripts/magpie_debug.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('error_reporting', E_ALL);
|
||||
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8');
|
||||
define('MAGPIE_DIR', '..' . DIRECTORY_SEPARATOR);
|
||||
define('MAGPIE_DEBUG', 1);
|
||||
|
||||
// flush cache quickly for debugging purposes, don't do this on a live site
|
||||
define('MAGPIE_CACHE_AGE', 10);
|
||||
|
||||
require_once(MAGPIE_DIR.'rss_fetch.inc');
|
||||
|
||||
|
||||
if ( isset($_GET['url']) ) {
|
||||
$url = $_GET['url'];
|
||||
}
|
||||
else {
|
||||
$url = 'http://magpierss.sf.net/test.rss';
|
||||
}
|
||||
|
||||
|
||||
test_library_support();
|
||||
|
||||
$rss = fetch_rss( $url );
|
||||
|
||||
if ($rss) {
|
||||
echo "<h3>Example Output</h3>";
|
||||
echo "Channel: " . $rss->channel['title'] . "<p>";
|
||||
echo "<ul>";
|
||||
foreach ($rss->items as $item) {
|
||||
$href = $item['link'];
|
||||
$title = $item['title'];
|
||||
echo "<li><a href=$href>$title</a></li>";
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
else {
|
||||
echo "Error: " . magpie_error();
|
||||
}
|
||||
?>
|
||||
|
||||
<form>
|
||||
RSS URL: <input type="text" size="30" name="url" value="<?php echo $url ?>"><br />
|
||||
<input type="submit" value="Parse RSS">
|
||||
</form>
|
||||
|
||||
<h3>Parsed Results (var_dump'ed)</h3>
|
||||
<pre>
|
||||
<?php var_dump($rss); ?>
|
||||
</pre>
|
||||
|
||||
<?php
|
||||
|
||||
function test_library_support() {
|
||||
if (!function_exists('xml_parser_create')) {
|
||||
echo "<b>Error:</b> PHP compiled without XML support (--with-xml), Mapgie won't work without PHP support for XML.<br />\n";
|
||||
exit;
|
||||
}
|
||||
else {
|
||||
echo "<b>OK:</b> Found an XML parser. <br />\n";
|
||||
}
|
||||
|
||||
if ( ! function_exists('gzinflate') ) {
|
||||
echo "<b>Warning:</b> PHP compiled without Zlib support (--with-zlib). No support for GZIP encoding.<br />\n";
|
||||
}
|
||||
else {
|
||||
echo "<b>OK:</b> Support for GZIP encoding.<br />\n";
|
||||
}
|
||||
|
||||
if ( ! (function_exists('iconv') and function_exists('mb_convert_encoding') ) ) {
|
||||
echo "<b>Warning:</b> No support for iconv (--with-iconv) or multi-byte strings (--enable-mbstring)." .
|
||||
"No support character set munging.<br />\n";
|
||||
}
|
||||
else {
|
||||
echo "<b>OK:</b> Support for character munging.<br />\n";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
29
production/classes/magpie/scripts/magpie_simple.php
Normal file
29
production/classes/magpie/scripts/magpie_simple.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
define('MAGPIE_DIR', '..'.DIRECTORY_SEPARATOR);
|
||||
require_once(MAGPIE_DIR.'rss_fetch.inc');
|
||||
|
||||
$url = $_GET['url'];
|
||||
|
||||
if ( $url ) {
|
||||
$rss = fetch_rss( $url );
|
||||
echo "Channel: " . $rss->channel['title'] . "<p>";
|
||||
echo "<ul>";
|
||||
foreach ($rss->items as $item) {
|
||||
$href = $item['link'];
|
||||
$title = $item['title'];
|
||||
echo "<li><a href=$href>$title</a></li>";
|
||||
}
|
||||
echo "</ul>";
|
||||
}
|
||||
?>
|
||||
|
||||
<form>
|
||||
RSS URL: <input type="text" size="30" name="url" value="<?php echo $url ?>"><br />
|
||||
<input type="submit" value="Parse RSS">
|
||||
</form>
|
||||
|
||||
<p>
|
||||
<h2>Security Note:</h2>
|
||||
This is a simple <b>example</b> script. If this was a <b>real</b> script we probably wouldn't allow strangers to submit random URLs, and we certainly wouldn't simply echo anything passed in the URL. Additionally its a bad idea to leave this example script lying around.
|
||||
</p>
|
||||
66
production/classes/magpie/scripts/magpie_slashbox.php
Normal file
66
production/classes/magpie/scripts/magpie_slashbox.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
define('MAGPIE_DIR', '..'.DIRECTORY_SEPARATOR);
|
||||
require_once(MAGPIE_DIR.'rss_fetch.inc');
|
||||
|
||||
$url = $_GET['rss_url'];
|
||||
|
||||
?>
|
||||
|
||||
<html
|
||||
<body LINK="#999999" VLINK="#000000">
|
||||
|
||||
<form>
|
||||
<input type="text" name="rss_url" size="40" value="<?php echo $url ?>"><input type="Submit">
|
||||
</form>
|
||||
|
||||
<?php
|
||||
|
||||
if ( $url ) {
|
||||
echo "displaying: $url<p>";
|
||||
$rss = fetch_rss( $url );
|
||||
echo slashbox ($rss);
|
||||
}
|
||||
|
||||
echo "<pre>";
|
||||
print_r($rss);
|
||||
echo "</pre>";
|
||||
?>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
|
||||
# just some quick and ugly php to generate html
|
||||
#
|
||||
#
|
||||
function slashbox ($rss) {
|
||||
echo "<table cellpadding=2 cellspacing=0><tr>";
|
||||
echo "<td bgcolor=#006666>";
|
||||
|
||||
# get the channel title and link properties off of the rss object
|
||||
#
|
||||
$title = $rss->channel['title'];
|
||||
$link = $rss->channel['link'];
|
||||
|
||||
echo "<a href=$link><font color=#FFFFFF><b>$title</b></font></a>";
|
||||
echo "</td></tr>";
|
||||
|
||||
# foreach over each item in the array.
|
||||
# displaying simple links
|
||||
#
|
||||
# we could be doing all sorts of neat things with the dublin core
|
||||
# info, or the event info, or what not, but keeping it simple for now.
|
||||
#
|
||||
foreach ($rss->items as $item ) {
|
||||
echo "<tr><td bgcolor=#cccccc>";
|
||||
echo "<a href=$item[link]>";
|
||||
echo $item['title'];
|
||||
echo "</a></td></tr>";
|
||||
}
|
||||
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
?>
|
||||
58
production/classes/magpie/scripts/simple_smarty.php
Normal file
58
production/classes/magpie/scripts/simple_smarty.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
// Define path to Smarty files (don't forget trailing slash)
|
||||
// and load library. (you'll want to change this value)
|
||||
//
|
||||
// NOTE: you can also simply add Smarty to your include path
|
||||
define('SMARTY_DIR', '/home/kellan/projs/magpierss/scripts/Smarty/');
|
||||
require_once(SMARTY_DIR.'Smarty.class.php');
|
||||
|
||||
// define path to Magpie files and load library
|
||||
// (you'll want to change this value)
|
||||
//
|
||||
// NOTE: you can also simple add MagpieRSS to your include path
|
||||
define('MAGPIE_DIR', '/home/kellan/projs/magpierss/');
|
||||
require_once(MAGPIE_DIR.'rss_fetch.inc');
|
||||
require_once(MAGPIE_DIR.'rss_utils.inc');
|
||||
|
||||
|
||||
// optionally show lots of debugging info
|
||||
# define('MAGPIE_DEBUG', 2);
|
||||
|
||||
// optionally flush cache quickly for debugging purposes,
|
||||
// don't do this on a live site
|
||||
# define('MAGPIE_CACHE_AGE', 10);
|
||||
|
||||
// use cache? default is yes. see rss_fetch for other Magpie options
|
||||
# define('MAGPIE_CACHE_ON', 1)
|
||||
|
||||
// setup template object
|
||||
$smarty = new Smarty;
|
||||
$smarty->compile_check = true;
|
||||
|
||||
// url of an rss file
|
||||
$url = $_GET['rss_url'];
|
||||
|
||||
|
||||
if ( $url ) {
|
||||
// assign a variable to smarty for use in the template
|
||||
$smarty->assign('rss_url', $url);
|
||||
|
||||
// use MagpieRSS to fetch remote RSS file, and parse it
|
||||
$rss = fetch_rss( $url );
|
||||
|
||||
// if fetch_rss returned false, we encountered an error
|
||||
if ( !$rss ) {
|
||||
$smarty->assign( 'error', magpie_error() );
|
||||
}
|
||||
$smarty->assign('rss', $rss );
|
||||
|
||||
$item = $rss->items[0];
|
||||
$date = parse_w3cdtf( $item['dc']['date'] );
|
||||
$smarty->assign( 'date', $date );
|
||||
}
|
||||
|
||||
// parse smarty template, and display using the variables we assigned
|
||||
$smarty->display('simple.smarty');
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* Smarty plugin
|
||||
* -------------------------------------------------------------
|
||||
* Type: modifier
|
||||
* Name: rss_date_parse
|
||||
* Purpose: parse rss date into unix epoch
|
||||
* Input: string: rss date
|
||||
* default_date: default date if $rss_date is empty
|
||||
*
|
||||
* NOTE!!! parse_w3cdtf provided by MagpieRSS's rss_utils.inc
|
||||
* this file needs to be included somewhere in your script
|
||||
* -------------------------------------------------------------
|
||||
*/
|
||||
|
||||
function smarty_modifier_rss_date_parse ($rss_date, $default_date=null)
|
||||
{
|
||||
if($rss_date != '') {
|
||||
return parse_w3cdtf( $rss_date );
|
||||
} elseif (isset($default_date) && $default_date != '') {
|
||||
return parse_w3cdtf( $default_date );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
?>
|
||||
46
production/classes/magpie/scripts/templates/simple.smarty
Normal file
46
production/classes/magpie/scripts/templates/simple.smarty
Normal file
@@ -0,0 +1,46 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>A Simple RSS Box: I'm not a designer</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<form>
|
||||
<b>RSS File:</b>
|
||||
<input type=text" name="rss_url" value="{$rss_url}" size="50">
|
||||
<input type="submit">
|
||||
</form>
|
||||
|
||||
<b>Displaying:</b> {$rss_url}
|
||||
<p>
|
||||
|
||||
{* if $error display the error
|
||||
elseif parsed RSS object display the RSS
|
||||
else solicit user for a URL
|
||||
*}
|
||||
|
||||
{if $error }
|
||||
<b>Error:</b> {$error}
|
||||
{elseif $rss}
|
||||
<table border=1>
|
||||
<tr>
|
||||
<th colspan=2>
|
||||
<a href="{$rss->channel.link}">{$rss->channel.title}</a>
|
||||
</th>
|
||||
</tr>
|
||||
{foreach from=$rss->items item=item}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{$item.link}">{$item.title}</a>
|
||||
</td>
|
||||
<td>
|
||||
{$item.dc.date|rss_date_parse|date_format:"%A, %B %e, %Y"}
|
||||
</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
{else}
|
||||
Enter the URL of an RSS file to display.
|
||||
{/if}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
523
production/classes/misc/unzip.inc.php
Normal file
523
production/classes/misc/unzip.inc.php
Normal file
@@ -0,0 +1,523 @@
|
||||
<?php
|
||||
// 15/07/2006 (2.6)
|
||||
// - Changed the algorithm to parse the ZIP file.. Now, the script will try to mount the compressed
|
||||
// list, searching on the 'Central Dir' records. If it fails, the script will try to search by
|
||||
// checking every signature. Thanks to Jayson Cruz for pointing it.
|
||||
// 25/01/2006 (2.51)
|
||||
// - Fixed bug when calling 'unzip' without calling 'getList' first. Thanks to Bala Murthu for pointing it.
|
||||
// 01/12/2006 (2.5)
|
||||
// - Added optional parameter "applyChmod" for the "unzip()" method. It auto applies the given chmod for
|
||||
// extracted files.
|
||||
// - Permission 777 (all read-write-exec) is default. If you want to change it, you'll need to make it
|
||||
// explicit. (If you want the OS to determine, set "false" as "applyChmod" parameter)
|
||||
// 28/11/2005 (2.4)
|
||||
// - dUnzip2 is now compliant with old-style "Data Description", made by some compressors,
|
||||
// like the classes ZipLib and ZipLib2 by 'Hasin Hayder'. Thanks to Ricardo Parreno for pointing it.
|
||||
// 09/11/2005 (2.3)
|
||||
// - Added optional parameter '$stopOnFile' on method 'getList()'.
|
||||
// If given, file listing will stop when find given filename. (Useful to open and unzip an exact file)
|
||||
// 06/11/2005 (2.21)
|
||||
// - Added support to PK00 file format (Packed to Removable Disk) (thanks to Lito [PHPfileNavigator])
|
||||
// - Method 'getExtraInfo': If requested file doesn't exist, return FALSE instead of Array()
|
||||
// 31/10/2005 (2.2)
|
||||
// - Removed redundant 'file_name' on centralDirs declaration (thanks to Lito [PHPfileNavigator])
|
||||
// - Fixed redeclaration of file_put_contents when in PHP4 (not returning true)
|
||||
|
||||
##############################################################
|
||||
# Class dUnzip2 v2.6
|
||||
#
|
||||
# Author: Alexandre Tedeschi (d)
|
||||
# E-Mail: alexandrebr at gmail dot com
|
||||
# Londrina - PR / Brazil
|
||||
#
|
||||
# Objective:
|
||||
# This class allows programmer to easily unzip files on the fly.
|
||||
#
|
||||
# Requirements:
|
||||
# This class requires extension ZLib Enabled. It is default
|
||||
# for most site hosts around the world, and for the PHP Win32 dist.
|
||||
#
|
||||
# To do:
|
||||
# * Error handling
|
||||
# * Write a PHP-Side gzinflate, to completely avoid any external extensions
|
||||
# * Write other decompress algorithms
|
||||
#
|
||||
# If you modify this class, or have any ideas to improve it, please contact me!
|
||||
# You are allowed to redistribute this class, if you keep my name and contact e-mail on it.
|
||||
#
|
||||
# PLEASE! IF YOU USE THIS CLASS IN ANY OF YOUR PROJECTS, PLEASE LET ME KNOW!
|
||||
# If you have problems using it, don't think twice before contacting me!
|
||||
#
|
||||
##############################################################
|
||||
|
||||
if (!function_exists('file_put_contents')) {
|
||||
// If not PHP5, creates a compatible function
|
||||
function file_put_contents($file, $data) {
|
||||
if ($tmp = fopen($file, "w")) {
|
||||
fwrite($tmp, $data);
|
||||
fclose($tmp);
|
||||
return true;
|
||||
}
|
||||
echo "<b>file_put_contents:</b> Cannot create file $file<br>";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class dUnzip2{
|
||||
function getVersion() {
|
||||
return "2.6";
|
||||
}
|
||||
// Public
|
||||
var $fileName;
|
||||
var $compressedList; // You will problably use only this one!
|
||||
var $centralDirList; // Central dir list... It's a kind of 'extra attributes' for a set of files
|
||||
var $endOfCentral; // End of central dir, contains ZIP Comments
|
||||
var $debug;
|
||||
var $errors = false;
|
||||
|
||||
// Private
|
||||
var $fh;
|
||||
var $zipSignature = "\x50\x4b\x03\x04"; // local file header signature
|
||||
var $dirSignature = "\x50\x4b\x01\x02"; // central dir header signature
|
||||
var $dirSignatureE= "\x50\x4b\x05\x06"; // end of central dir signature
|
||||
|
||||
// Public
|
||||
function dUnzip2($fileName) {
|
||||
$this->fileName = $fileName;
|
||||
$this->compressedList =
|
||||
$this->centralDirList =
|
||||
$this->endOfCentral = Array();
|
||||
}
|
||||
|
||||
function getList($stopOnFile=false) {
|
||||
if(sizeof($this->compressedList)){
|
||||
$this->debugMsg(1, "Returning already loaded file list.");
|
||||
return $this->compressedList;
|
||||
}
|
||||
|
||||
// Open file, and set file handler
|
||||
$fh = fopen($this->fileName, "r");
|
||||
$this->fh = &$fh;
|
||||
if(!$fh){
|
||||
$this->debugMsg(2, "Failed to load file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->debugMsg(1, "Loading list from 'End of Central Dir' index list...");
|
||||
if(!$this->_loadFileListByEOF($fh, $stopOnFile)){
|
||||
$this->debugMsg(1, "Failed! Trying to load list looking for signatures...");
|
||||
if(!$this->_loadFileListBySignatures($fh, $stopOnFile)){
|
||||
$this->debugMsg(1, "Failed! Could not find any valid header.");
|
||||
$this->debugMsg(2, "ZIP File is corrupted or empty");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->debug) {
|
||||
#------- Debug compressedList
|
||||
$kkk = 0;
|
||||
echo "<table border='0' style='font: 11px Verdana; border: 1px solid #000'>";
|
||||
foreach($this->compressedList as $fileName=>$item){
|
||||
if(!$kkk && $kkk=1){
|
||||
echo "<tr style='background: #ADA'>";
|
||||
foreach($item as $fieldName=>$value)
|
||||
echo "<td>$fieldName</td>";
|
||||
echo '</tr>';
|
||||
}
|
||||
echo "<tr style='background: #CFC'>";
|
||||
foreach($item as $fieldName=>$value){
|
||||
if($fieldName == 'lastmod_datetime')
|
||||
echo "<td title='$fieldName' nowrap='nowrap'>".date("d/m/Y H:i:s", $value)."</td>";
|
||||
else
|
||||
echo "<td title='$fieldName' nowrap='nowrap'>$value</td>";
|
||||
}
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
|
||||
#------- Debug centralDirList
|
||||
$kkk = 0;
|
||||
if(sizeof($this->centralDirList)){
|
||||
echo "<table border='0' style='font: 11px Verdana; border: 1px solid #000'>";
|
||||
foreach($this->centralDirList as $fileName=>$item){
|
||||
if(!$kkk && $kkk=1){
|
||||
echo "<tr style='background: #AAD'>";
|
||||
foreach($item as $fieldName=>$value)
|
||||
echo "<td>$fieldName</td>";
|
||||
echo '</tr>';
|
||||
}
|
||||
echo "<tr style='background: #CCF'>";
|
||||
foreach($item as $fieldName=>$value){
|
||||
if($fieldName == 'lastmod_datetime')
|
||||
echo "<td title='$fieldName' nowrap='nowrap'>".date("d/m/Y H:i:s", $value)."</td>";
|
||||
else
|
||||
echo "<td title='$fieldName' nowrap='nowrap'>$value</td>";
|
||||
}
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
#------- Debug endOfCentral
|
||||
$kkk = 0;
|
||||
if(sizeof($this->endOfCentral)){
|
||||
echo "<table border='0' style='font: 11px Verdana' style='border: 1px solid #000'>";
|
||||
echo "<tr style='background: #DAA'><td colspan='2'>dUnzip - End of file</td></tr>";
|
||||
foreach($this->endOfCentral as $field=>$value){
|
||||
echo "<tr>";
|
||||
echo "<td style='background: #FCC'>$field</td>";
|
||||
echo "<td style='background: #FDD'>$value</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
}
|
||||
|
||||
return $this->compressedList;
|
||||
}
|
||||
|
||||
function getExtraInfo($compressedFileName){
|
||||
return isset($this->centralDirList[$compressedFileName]) ? $this->centralDirList[$compressedFileName] : false;
|
||||
}
|
||||
|
||||
function getZipInfo($detail=false){
|
||||
return $detail?
|
||||
$this->endOfCentral[$detail]:
|
||||
$this->endOfCentral;
|
||||
}
|
||||
|
||||
function unzip($compressedFileName, $targetFileName=false, $applyChmod=0777){
|
||||
if(!sizeof($this->compressedList)){
|
||||
$this->debugMsg(1, "Trying to unzip before loading file list... Loading it!");
|
||||
$this->getList(false, $compressedFileName);
|
||||
}
|
||||
|
||||
$fdetails = &$this->compressedList[$compressedFileName];
|
||||
if (!isset($this->compressedList[$compressedFileName])) {
|
||||
$this->debugMsg(2, "File '<b>$compressedFileName</b>' is not compressed in the zip.");
|
||||
return false;
|
||||
}
|
||||
if (substr($compressedFileName, -1) == "/") {
|
||||
$this->debugMsg(2, "Trying to unzip a folder name '<b>$compressedFileName</b>'.");
|
||||
return false;
|
||||
}
|
||||
if (!$fdetails['uncompressed_size']) {
|
||||
$this->debugMsg(1, "File '<b>$compressedFileName</b>' is empty.");
|
||||
return $targetFileName?
|
||||
file_put_contents($targetFileName, ""):
|
||||
"";
|
||||
}
|
||||
|
||||
fseek($this->fh, $fdetails['contents-startOffset']);
|
||||
|
||||
$ret = $this->uncompress(
|
||||
fread($this->fh, $fdetails['compressed_size']),
|
||||
$fdetails['compression_method'],
|
||||
$fdetails['uncompressed_size'],
|
||||
$targetFileName
|
||||
);
|
||||
|
||||
if ($applyChmod && $targetFileName) @chmod($targetFileName, 0777);
|
||||
|
||||
if ($ret === false) $this->errors[] = $targetFileName;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
function unzipAll($targetDir=false, $baseDir="", $maintainStructure=true, $applyChmod=0777){
|
||||
if ($targetDir === false) $targetDir = dirname(__FILE__)."/";
|
||||
|
||||
$lista = $this->getList();
|
||||
if (sizeof($lista)) {
|
||||
foreach($lista as $fileName=>$trash){
|
||||
$dirname = dirname($fileName);
|
||||
$outDN = "$targetDir/$dirname";
|
||||
|
||||
if (substr($dirname, 0, strlen($baseDir)) != $baseDir) continue;
|
||||
|
||||
if (!is_dir($outDN) && $maintainStructure) {
|
||||
$str = "";
|
||||
$folders = explode("/", $dirname);
|
||||
foreach ($folders as $folder) {
|
||||
$str = $str ? "$str/$folder" : $folder;
|
||||
if (!is_dir("$targetDir/$str")) {
|
||||
$this->debugMsg(1, "Creating folder: $targetDir/$str");
|
||||
mkdir("$targetDir/$str");
|
||||
if ($applyChmod) chmod("$targetDir/$str", $applyChmod);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (substr($fileName, -1, 1) == "/") continue;
|
||||
|
||||
$maintainStructure ?
|
||||
$this->unzip($fileName, "$targetDir/$fileName", $applyChmod) :
|
||||
$this->unzip($fileName, "$targetDir/".basename($fileName), $applyChmod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function close() { // Free the file resource
|
||||
if($this->fh)
|
||||
fclose($this->fh);
|
||||
}
|
||||
|
||||
function __destroy() {
|
||||
$this->close();
|
||||
}
|
||||
|
||||
function getErrors() {
|
||||
if (is_array($this->errors)) {
|
||||
return $this->errors;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Private (you should NOT call these methods):
|
||||
function uncompress($content, $mode, $uncompressedSize, $targetFileName=false){
|
||||
switch($mode){
|
||||
case 0:
|
||||
// Not compressed
|
||||
return $targetFileName?
|
||||
file_put_contents($targetFileName, $content):
|
||||
$content;
|
||||
case 1:
|
||||
$this->debugMsg(2, "Shrunk mode is not supported... yet?");
|
||||
return false;
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
$this->debugMsg(2, "Compression factor ".($mode-1)." is not supported... yet?");
|
||||
return false;
|
||||
case 6:
|
||||
$this->debugMsg(2, "Implode is not supported... yet?");
|
||||
return false;
|
||||
case 7:
|
||||
$this->debugMsg(2, "Tokenizing compression algorithm is not supported... yet?");
|
||||
return false;
|
||||
case 8:
|
||||
// Deflate
|
||||
return $targetFileName?
|
||||
file_put_contents($targetFileName, gzinflate($content, $uncompressedSize)):
|
||||
gzinflate($content, $uncompressedSize);
|
||||
case 9:
|
||||
$this->debugMsg(2, "Enhanced Deflating is not supported... yet?");
|
||||
return false;
|
||||
case 10:
|
||||
$this->debugMsg(2, "PKWARE Date Compression Library Impoloding is not supported... yet?");
|
||||
return false;
|
||||
case 12:
|
||||
// Bzip2
|
||||
return $targetFileName?
|
||||
file_put_contents($targetFileName, bzdecompress($content)):
|
||||
bzdecompress($content);
|
||||
case 18:
|
||||
$this->debugMsg(2, "IBM TERSE is not supported... yet?");
|
||||
return false;
|
||||
default:
|
||||
$this->debugMsg(2, "Unknown uncompress method: $mode");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
function debugMsg($level, $string){
|
||||
if($this->debug)
|
||||
if($level == 1)
|
||||
echo "<b style='color: #777'>dUnzip2:</b> $string<br>";
|
||||
if($level == 2)
|
||||
echo "<b style='color: #F00'>dUnzip2:</b> $string<br>";
|
||||
}
|
||||
|
||||
function _loadFileListByEOF(&$fh, $stopOnFile=false){
|
||||
// Check if there's a valid Central Dir signature.
|
||||
// Let's consider a file comment smaller than 1024 characters...
|
||||
// Actually, it length can be 65536.. But we're not going to support it.
|
||||
|
||||
for($x = 0; $x < 1024; $x++){
|
||||
fseek($fh, -22-$x, SEEK_END);
|
||||
|
||||
$signature = fread($fh, 4);
|
||||
if($signature == $this->dirSignatureE){
|
||||
// If found EOF Central Dir
|
||||
$eodir['disk_number_this'] = unpack("v", fread($fh, 2)); // number of this disk
|
||||
$eodir['disk_number'] = unpack("v", fread($fh, 2)); // number of the disk with the start of the central directory
|
||||
$eodir['total_entries_this'] = unpack("v", fread($fh, 2)); // total number of entries in the central dir on this disk
|
||||
$eodir['total_entries'] = unpack("v", fread($fh, 2)); // total number of entries in
|
||||
$eodir['size_of_cd'] = unpack("V", fread($fh, 4)); // size of the central directory
|
||||
$eodir['offset_start_cd'] = unpack("V", fread($fh, 4)); // offset of start of central directory with respect to the starting disk number
|
||||
$zipFileCommentLenght = unpack("v", fread($fh, 2)); // zipfile comment length
|
||||
$eodir['zipfile_comment'] = $zipFileCommentLenght[1]?fread($fh, $zipFileCommentLenght[1]):''; // zipfile comment
|
||||
$this->endOfCentral = Array(
|
||||
'disk_number_this'=>$eodir['disk_number_this'][1],
|
||||
'disk_number'=>$eodir['disk_number'][1],
|
||||
'total_entries_this'=>$eodir['total_entries_this'][1],
|
||||
'total_entries'=>$eodir['total_entries'][1],
|
||||
'size_of_cd'=>$eodir['size_of_cd'][1],
|
||||
'offset_start_cd'=>$eodir['offset_start_cd'][1],
|
||||
'zipfile_comment'=>$eodir['zipfile_comment'],
|
||||
);
|
||||
|
||||
// Then, load file list
|
||||
fseek($fh, $this->endOfCentral['offset_start_cd']);
|
||||
$signature = fread($fh, 4);
|
||||
|
||||
while($signature == $this->dirSignature){
|
||||
$dir['version_madeby'] = unpack("v", fread($fh, 2)); // version made by
|
||||
$dir['version_needed'] = unpack("v", fread($fh, 2)); // version needed to extract
|
||||
$dir['general_bit_flag'] = unpack("v", fread($fh, 2)); // general purpose bit flag
|
||||
$dir['compression_method'] = unpack("v", fread($fh, 2)); // compression method
|
||||
$dir['lastmod_time'] = unpack("v", fread($fh, 2)); // last mod file time
|
||||
$dir['lastmod_date'] = unpack("v", fread($fh, 2)); // last mod file date
|
||||
$dir['crc-32'] = fread($fh, 4); // crc-32
|
||||
$dir['compressed_size'] = unpack("V", fread($fh, 4)); // compressed size
|
||||
$dir['uncompressed_size'] = unpack("V", fread($fh, 4)); // uncompressed size
|
||||
$fileNameLength = unpack("v", fread($fh, 2)); // filename length
|
||||
$extraFieldLength = unpack("v", fread($fh, 2)); // extra field length
|
||||
$fileCommentLength = unpack("v", fread($fh, 2)); // file comment length
|
||||
$dir['disk_number_start'] = unpack("v", fread($fh, 2)); // disk number start
|
||||
$dir['internal_attributes'] = unpack("v", fread($fh, 2)); // internal file attributes-byte1
|
||||
$dir['external_attributes1']= unpack("v", fread($fh, 2)); // external file attributes-byte2
|
||||
$dir['external_attributes2']= unpack("v", fread($fh, 2)); // external file attributes
|
||||
$dir['relative_offset'] = unpack("V", fread($fh, 4)); // relative offset of local header
|
||||
$dir['file_name'] = fread($fh, $fileNameLength[1]); // filename
|
||||
$dir['extra_field'] = $extraFieldLength[1] ?fread($fh, $extraFieldLength[1]) :''; // extra field
|
||||
$dir['file_comment'] = $fileCommentLength[1]?fread($fh, $fileCommentLength[1]):''; // file comment
|
||||
|
||||
// Convert the date and time, from MS-DOS format to UNIX Timestamp
|
||||
$BINlastmod_date = str_pad(decbin($dir['lastmod_date'][1]), 16, '0', STR_PAD_LEFT);
|
||||
$BINlastmod_time = str_pad(decbin($dir['lastmod_time'][1]), 16, '0', STR_PAD_LEFT);
|
||||
$lastmod_dateY = bindec(substr($BINlastmod_date, 0, 7))+1980;
|
||||
$lastmod_dateM = bindec(substr($BINlastmod_date, 7, 4));
|
||||
$lastmod_dateD = bindec(substr($BINlastmod_date, 11, 5));
|
||||
$lastmod_timeH = bindec(substr($BINlastmod_time, 0, 5));
|
||||
$lastmod_timeM = bindec(substr($BINlastmod_time, 5, 6));
|
||||
$lastmod_timeS = bindec(substr($BINlastmod_time, 11, 5));
|
||||
|
||||
$this->centralDirList[$dir['file_name']] = Array(
|
||||
'version_madeby'=>$dir['version_madeby'][1],
|
||||
'version_needed'=>$dir['version_needed'][1],
|
||||
'general_bit_flag'=>str_pad(decbin($dir['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT),
|
||||
'compression_method'=>$dir['compression_method'][1],
|
||||
'lastmod_datetime' =>mktime($lastmod_timeH, $lastmod_timeM, $lastmod_timeS, $lastmod_dateM, $lastmod_dateD, $lastmod_dateY),
|
||||
'crc-32' =>str_pad(dechex(ord($dir['crc-32'][3])), 2, '0', STR_PAD_LEFT).
|
||||
str_pad(dechex(ord($dir['crc-32'][2])), 2, '0', STR_PAD_LEFT).
|
||||
str_pad(dechex(ord($dir['crc-32'][1])), 2, '0', STR_PAD_LEFT).
|
||||
str_pad(dechex(ord($dir['crc-32'][0])), 2, '0', STR_PAD_LEFT),
|
||||
'compressed_size'=>$dir['compressed_size'][1],
|
||||
'uncompressed_size'=>$dir['uncompressed_size'][1],
|
||||
'disk_number_start'=>$dir['disk_number_start'][1],
|
||||
'internal_attributes'=>$dir['internal_attributes'][1],
|
||||
'external_attributes1'=>$dir['external_attributes1'][1],
|
||||
'external_attributes2'=>$dir['external_attributes2'][1],
|
||||
'relative_offset'=>$dir['relative_offset'][1],
|
||||
'file_name'=>$dir['file_name'],
|
||||
'extra_field'=>$dir['extra_field'],
|
||||
'file_comment'=>$dir['file_comment'],
|
||||
);
|
||||
$signature = fread($fh, 4);
|
||||
}
|
||||
|
||||
// If loaded centralDirs, then try to identify the offsetPosition of the compressed data.
|
||||
if($this->centralDirList) foreach($this->centralDirList as $filename=>$details){
|
||||
$i = $this->_getFileHeaderInformation($fh, $details['relative_offset']);
|
||||
$this->compressedList[$filename]['file_name'] = $filename;
|
||||
$this->compressedList[$filename]['compression_method'] = $details['compression_method'];
|
||||
$this->compressedList[$filename]['version_needed'] = $details['version_needed'];
|
||||
$this->compressedList[$filename]['lastmod_datetime'] = $details['lastmod_datetime'];
|
||||
$this->compressedList[$filename]['crc-32'] = $details['crc-32'];
|
||||
$this->compressedList[$filename]['compressed_size'] = $details['compressed_size'];
|
||||
$this->compressedList[$filename]['uncompressed_size'] = $details['uncompressed_size'];
|
||||
$this->compressedList[$filename]['lastmod_datetime'] = $details['lastmod_datetime'];
|
||||
$this->compressedList[$filename]['extra_field'] = $i['extra_field'];
|
||||
$this->compressedList[$filename]['contents-startOffset']=$i['contents-startOffset'];
|
||||
if(strtolower($stopOnFile) == strtolower($filename))
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
function _loadFileListBySignatures(&$fh, $stopOnFile=false){
|
||||
fseek($fh, 0);
|
||||
|
||||
$return = false;
|
||||
for(;;){
|
||||
$details = $this->_getFileHeaderInformation($fh);
|
||||
if(!$details){
|
||||
$this->debugMsg(1, "Invalid signature. Trying to verify if is old style Data Descriptor...");
|
||||
fseek($fh, 12 - 4, SEEK_CUR); // 12: Data descriptor - 4: Signature (that will be read again)
|
||||
$details = $this->_getFileHeaderInformation($fh);
|
||||
}
|
||||
if(!$details){
|
||||
$this->debugMsg(1, "Still invalid signature. Probably reached the end of the file.");
|
||||
break;
|
||||
}
|
||||
$filename = $details['file_name'];
|
||||
$this->compressedList[$filename] = $details;
|
||||
$return = true;
|
||||
if(strtolower($stopOnFile) == strtolower($filename))
|
||||
break;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
function _getFileHeaderInformation(&$fh, $startOffset=false){
|
||||
if($startOffset !== false)
|
||||
fseek($fh, $startOffset);
|
||||
|
||||
$signature = fread($fh, 4);
|
||||
if($signature == $this->zipSignature){
|
||||
# $this->debugMsg(1, "Zip Signature!");
|
||||
|
||||
// Get information about the zipped file
|
||||
$file['version_needed'] = unpack("v", fread($fh, 2)); // version needed to extract
|
||||
$file['general_bit_flag'] = unpack("v", fread($fh, 2)); // general purpose bit flag
|
||||
$file['compression_method'] = unpack("v", fread($fh, 2)); // compression method
|
||||
$file['lastmod_time'] = unpack("v", fread($fh, 2)); // last mod file time
|
||||
$file['lastmod_date'] = unpack("v", fread($fh, 2)); // last mod file date
|
||||
$file['crc-32'] = fread($fh, 4); // crc-32
|
||||
$file['compressed_size'] = unpack("V", fread($fh, 4)); // compressed size
|
||||
$file['uncompressed_size'] = unpack("V", fread($fh, 4)); // uncompressed size
|
||||
$fileNameLength = unpack("v", fread($fh, 2)); // filename length
|
||||
$extraFieldLength = unpack("v", fread($fh, 2)); // extra field length
|
||||
$file['file_name'] = fread($fh, $fileNameLength[1]); // filename
|
||||
$file['extra_field'] = $extraFieldLength[1]?fread($fh, $extraFieldLength[1]):''; // extra field
|
||||
$file['contents-startOffset']= ftell($fh);
|
||||
|
||||
// Bypass the whole compressed contents, and look for the next file
|
||||
fseek($fh, $file['compressed_size'][1], SEEK_CUR);
|
||||
|
||||
// Convert the date and time, from MS-DOS format to UNIX Timestamp
|
||||
$BINlastmod_date = str_pad(decbin($file['lastmod_date'][1]), 16, '0', STR_PAD_LEFT);
|
||||
$BINlastmod_time = str_pad(decbin($file['lastmod_time'][1]), 16, '0', STR_PAD_LEFT);
|
||||
$lastmod_dateY = bindec(substr($BINlastmod_date, 0, 7))+1980;
|
||||
$lastmod_dateM = bindec(substr($BINlastmod_date, 7, 4));
|
||||
$lastmod_dateD = bindec(substr($BINlastmod_date, 11, 5));
|
||||
$lastmod_timeH = bindec(substr($BINlastmod_time, 0, 5));
|
||||
$lastmod_timeM = bindec(substr($BINlastmod_time, 5, 6));
|
||||
$lastmod_timeS = bindec(substr($BINlastmod_time, 11, 5));
|
||||
|
||||
// Mount file table
|
||||
$i = Array(
|
||||
'file_name' =>$file['file_name'],
|
||||
'compression_method'=>$file['compression_method'][1],
|
||||
'version_needed' =>$file['version_needed'][1],
|
||||
'lastmod_datetime' =>mktime($lastmod_timeH, $lastmod_timeM, $lastmod_timeS, $lastmod_dateM, $lastmod_dateD, $lastmod_dateY),
|
||||
'crc-32' =>str_pad(dechex(ord($file['crc-32'][3])), 2, '0', STR_PAD_LEFT).
|
||||
str_pad(dechex(ord($file['crc-32'][2])), 2, '0', STR_PAD_LEFT).
|
||||
str_pad(dechex(ord($file['crc-32'][1])), 2, '0', STR_PAD_LEFT).
|
||||
str_pad(dechex(ord($file['crc-32'][0])), 2, '0', STR_PAD_LEFT),
|
||||
'compressed_size' =>$file['compressed_size'][1],
|
||||
'uncompressed_size' =>$file['uncompressed_size'][1],
|
||||
'extra_field' =>$file['extra_field'],
|
||||
'general_bit_flag' =>str_pad(decbin($file['general_bit_flag'][1]), 8, '0', STR_PAD_LEFT),
|
||||
'contents-startOffset'=>$file['contents-startOffset']
|
||||
);
|
||||
return $i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
211
production/classes/misc/zip.inc.php
Normal file
211
production/classes/misc/zip.inc.php
Normal file
@@ -0,0 +1,211 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class to dynamically create a zip file (archive)
|
||||
*
|
||||
* @author Rochak Chauhan
|
||||
*/
|
||||
|
||||
class createZip {
|
||||
|
||||
public $compressedData = array();
|
||||
public $centralDirectory = array(); // central directory
|
||||
public $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
|
||||
public $oldOffset = 0;
|
||||
|
||||
/**
|
||||
* Function to create the directory where the file(s) will be unzipped
|
||||
*
|
||||
* @param $directoryName string
|
||||
*
|
||||
*/
|
||||
|
||||
public function addDirectory($directoryName = 'default/') {
|
||||
$directoryName = str_replace("\\", "/", $directoryName);
|
||||
|
||||
$feedArrayRow = "\x50\x4b\x03\x04";
|
||||
$feedArrayRow .= "\x0a\x00";
|
||||
$feedArrayRow .= "\x00\x00";
|
||||
$feedArrayRow .= "\x00\x00";
|
||||
$feedArrayRow .= "\x00\x00\x00\x00";
|
||||
|
||||
$feedArrayRow .= pack("V",0);
|
||||
$feedArrayRow .= pack("V",0);
|
||||
$feedArrayRow .= pack("V",0);
|
||||
$feedArrayRow .= pack("v", strlen($directoryName) );
|
||||
$feedArrayRow .= pack("v", 0 );
|
||||
$feedArrayRow .= $directoryName;
|
||||
|
||||
$feedArrayRow .= pack("V",0);
|
||||
$feedArrayRow .= pack("V",0);
|
||||
$feedArrayRow .= pack("V",0);
|
||||
|
||||
$this -> compressedData[] = $feedArrayRow;
|
||||
|
||||
$newOffset = strlen(implode("", $this->compressedData));
|
||||
|
||||
$addCentralRecord = "\x50\x4b\x01\x02";
|
||||
$addCentralRecord .="\x00\x00";
|
||||
$addCentralRecord .="\x0a\x00";
|
||||
$addCentralRecord .="\x00\x00";
|
||||
$addCentralRecord .="\x00\x00";
|
||||
$addCentralRecord .="\x00\x00\x00\x00";
|
||||
$addCentralRecord .= pack("V",0);
|
||||
$addCentralRecord .= pack("V",0);
|
||||
$addCentralRecord .= pack("V",0);
|
||||
$addCentralRecord .= pack("v", strlen($directoryName) );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$ext = "\x00\x00\x10\x00";
|
||||
$ext = "\xff\xff\xff\xff";
|
||||
$addCentralRecord .= pack("V", 16 );
|
||||
|
||||
$addCentralRecord .= pack("V", $this -> oldOffset );
|
||||
$this -> oldOffset = $newOffset;
|
||||
|
||||
$addCentralRecord .= $directoryName;
|
||||
|
||||
$this -> centralDirectory[] = $addCentralRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to add file(s) to the specified directory in the archive
|
||||
*
|
||||
* @param $directoryName string
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
function addFiles($array) {
|
||||
if (is_array($array)) {
|
||||
foreach ($array as $file) {
|
||||
$this->addFile($file);
|
||||
}
|
||||
} else {
|
||||
$fileContents = file_get_contents($array);
|
||||
$this->addFile($array);
|
||||
}
|
||||
}
|
||||
|
||||
public function addFile($data, $directoryName = 'default/') {
|
||||
|
||||
$directoryName = str_replace("\\", "/", $directoryName);
|
||||
|
||||
$feedArrayRow = "\x50\x4b\x03\x04";
|
||||
$feedArrayRow .= "\x14\x00";
|
||||
$feedArrayRow .= "\x00\x00";
|
||||
$feedArrayRow .= "\x08\x00";
|
||||
$feedArrayRow .= "\x00\x00\x00\x00";
|
||||
|
||||
$uncompressedLength = strlen($data);
|
||||
$compression = crc32($data);
|
||||
$gzCompressedData = gzcompress($data);
|
||||
$gzCompressedData = substr( substr($gzCompressedData, 0, strlen($gzCompressedData) - 4), 2);
|
||||
$compressedLength = strlen($gzCompressedData);
|
||||
$feedArrayRow .= pack("V",$compression);
|
||||
$feedArrayRow .= pack("V",$compressedLength);
|
||||
$feedArrayRow .= pack("V",$uncompressedLength);
|
||||
$feedArrayRow .= pack("v", strlen($directoryName) );
|
||||
$feedArrayRow .= pack("v", 0 );
|
||||
$feedArrayRow .= $directoryName;
|
||||
|
||||
$feedArrayRow .= $gzCompressedData;
|
||||
|
||||
$feedArrayRow .= pack("V",$compression);
|
||||
$feedArrayRow .= pack("V",$compressedLength);
|
||||
$feedArrayRow .= pack("V",$uncompressedLength);
|
||||
|
||||
$this -> compressedData[] = $feedArrayRow;
|
||||
|
||||
$newOffset = strlen(implode("", $this->compressedData));
|
||||
|
||||
$addCentralRecord = "\x50\x4b\x01\x02";
|
||||
$addCentralRecord .="\x00\x00";
|
||||
$addCentralRecord .="\x14\x00";
|
||||
$addCentralRecord .="\x00\x00";
|
||||
$addCentralRecord .="\x08\x00";
|
||||
$addCentralRecord .="\x00\x00\x00\x00";
|
||||
$addCentralRecord .= pack("V",$compression);
|
||||
$addCentralRecord .= pack("V",$compressedLength);
|
||||
$addCentralRecord .= pack("V",$uncompressedLength);
|
||||
$addCentralRecord .= pack("v", strlen($directoryName) );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("v", 0 );
|
||||
$addCentralRecord .= pack("V", 32 );
|
||||
|
||||
$addCentralRecord .= pack("V", $this -> oldOffset );
|
||||
$this -> oldOffset = $newOffset;
|
||||
|
||||
$addCentralRecord .= $directoryName;
|
||||
|
||||
$this -> centralDirectory[] = $addCentralRecord;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fucntion to return the zip file
|
||||
*
|
||||
* @return zipfile (archive)
|
||||
*/
|
||||
|
||||
public function getZippedfile() {
|
||||
|
||||
$data = implode("", $this -> compressedData);
|
||||
$controlDirectory = implode("", $this -> centralDirectory);
|
||||
|
||||
return
|
||||
$data.
|
||||
$controlDirectory.
|
||||
$this -> endOfCentralDirectory.
|
||||
pack("v", sizeof($this -> centralDirectory)).
|
||||
pack("v", sizeof($this -> centralDirectory)).
|
||||
pack("V", strlen($controlDirectory)).
|
||||
pack("V", strlen($data)).
|
||||
"\x00\x00";
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Function to force the download of the archive as soon as it is created
|
||||
*
|
||||
* @param archiveName string - name of the created archive file
|
||||
*/
|
||||
|
||||
public function forceDownload($archiveName) {
|
||||
$headerInfo = '';
|
||||
|
||||
if(ini_get('zlib.output_compression')) {
|
||||
ini_set('zlib.output_compression', 'Off');
|
||||
}
|
||||
|
||||
// Security checks
|
||||
if( $archiveName == "" ) {
|
||||
echo "<html><title>Public Photo Directory - Download </title><body><BR><B>ERROR:</B> The download file was NOT SPECIFIED.</body></html>";
|
||||
exit;
|
||||
}
|
||||
elseif ( ! file_exists( $archiveName ) ) {
|
||||
echo "<html><title>Public Photo Directory - Download </title><body><BR><B>ERROR:</B> File not found.</body></html>";
|
||||
exit;
|
||||
}
|
||||
|
||||
header("Pragma: public");
|
||||
header("Expires: 0");
|
||||
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
||||
header("Cache-Control: private",false);
|
||||
header("Content-Type: application/zip");
|
||||
header("Content-Disposition: attachment; filename=".basename($archiveName).";" );
|
||||
header("Content-Transfer-Encoding: binary");
|
||||
header("Content-Length: ".filesize($archiveName));
|
||||
readfile("$archiveName");
|
||||
|
||||
}
|
||||
function saveArchive($filename) {
|
||||
$fp = fopen($filename, 'wb');
|
||||
fwrite($fp, $this->getZippedFile());
|
||||
@fclose($fp);
|
||||
}
|
||||
}
|
||||
?>
|
||||
136
production/classes/session/cc_admin_session.php
Normal file
136
production/classes/session/cc_admin_session.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| cc_admin_session.php
|
||||
| ========================================
|
||||
| Admin Authentication and Permissions
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
class admin_session {
|
||||
|
||||
var $config;
|
||||
var $db;
|
||||
var $glob;
|
||||
var $ini;
|
||||
|
||||
function admin_session() {
|
||||
$this->__construct();
|
||||
}
|
||||
|
||||
function __construct() {
|
||||
global $config, $db, $glob, $ini;
|
||||
|
||||
$this->config = $config;
|
||||
$this->db = &$db;
|
||||
$this->glob = $glob;
|
||||
$this->ini = $ini;
|
||||
}
|
||||
|
||||
function get_session_data() {
|
||||
if (!isset($GLOBALS[CC_ADMIN_SESSION_NAME])) {
|
||||
## If no session redirect to login screen
|
||||
httpredir($GLOBALS['rootRel'].$this->glob['adminFile']."?_g=login&goto=".urlencode(currentPage()));
|
||||
} else {
|
||||
## Get session information as array
|
||||
$query = sprintf("SELECT * FROM ".$this->glob['dbprefix']."CubeCart_admin_users WHERE sessId = %s", $this->db->mySQLSafe($GLOBALS[CC_ADMIN_SESSION_NAME]));
|
||||
$ccAdminData = $this->db->select($query);
|
||||
|
||||
## Security checks
|
||||
//$client_ip = (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'];
|
||||
$client_ip = get_ip_address();
|
||||
|
||||
if ($ccAdminData[0]['sessIp'] !== $client_ip || $ccAdminData[0]['browser'] !== $_SERVER['HTTP_USER_AGENT']) {
|
||||
$this->logout();
|
||||
}
|
||||
|
||||
## Find permissions for those who are not super users
|
||||
if (!$ccAdminData[0]['isSuper']) {
|
||||
$query = sprintf("SELECT %1\$sCubeCart_admin_sections.sectId, name, `read`, `write`, `edit`, `delete` FROM %1\$sCubeCart_admin_sections LEFT JOIN %1\$sCubeCart_admin_permissions ON %1\$sCubeCart_admin_sections.sectId = %1\$sCubeCart_admin_permissions.sectId WHERE adminId = %2\$s", $this->glob['dbprefix'], $this->db->mySQLSafe($ccAdminData[0]['adminId']));
|
||||
$permissionArray = $this->db->select($query);
|
||||
|
||||
#print_r($permissionArray);
|
||||
#die;
|
||||
|
||||
if (is_array($permissionArray)) {
|
||||
for ($i=0; $i<count($permissionArray); $i++) {
|
||||
foreach ($permissionArray[$i] as $key => $value) {
|
||||
$masterKey = $permissionArray[$i]['name'];
|
||||
$ccAdminData[0][$masterKey][$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $ccAdminData[0];
|
||||
}
|
||||
}
|
||||
|
||||
function makeSessId() {
|
||||
session_start();
|
||||
session_regenerate_id(true);
|
||||
return session_id();
|
||||
}
|
||||
|
||||
function logout() {
|
||||
## reset session data
|
||||
$record['sessId'] = "''";
|
||||
$record['sessIp'] = "''";
|
||||
$record['browser'] = "''";
|
||||
|
||||
$this->db->update($this->glob['dbprefix']."CubeCart_admin_users", $record,"sessId = ".$this->db->MySQLSafe($GLOBALS[CC_ADMIN_SESSION_NAME]));
|
||||
|
||||
$this->set_cc_admin_cookie(CC_ADMIN_SESSION_NAME, '');
|
||||
httpredir($GLOBALS['rootRel'].$this->glob['adminFile']."?_g=login");
|
||||
}
|
||||
|
||||
function login($username, $password) {
|
||||
$query = sprintf("SELECT adminId FROM %sCubeCart_admin_users WHERE username = %s AND password = %s AND failLevel < %s AND blockTime < %s", $this->glob['dbprefix'], $this->db->mySQLSafe($username), $this->db->mySQLSafe(md5($password)), $this->ini['bfattempts'], time());
|
||||
$result = $this->db->select($query);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function createSession($admin_id) {
|
||||
$sessionId = $this->makeSessId();
|
||||
$this->set_cc_admin_cookie(CC_ADMIN_SESSION_NAME, $sessionId);
|
||||
|
||||
## set session global var because cookie won't show until next page load
|
||||
$GLOBALS[CC_ADMIN_SESSION_NAME] = $sessionId;
|
||||
|
||||
$record['sessId'] = "'".$sessionId."'";
|
||||
## log browser & ip for security purposes no session hijacking here :)
|
||||
$record['sessIp'] = $this->db->MySQLSafe(get_ip_address());
|
||||
$record['browser'] = $this->db->MySQLSafe($_SERVER['HTTP_USER_AGENT']);
|
||||
$this->db->update($this->glob['dbprefix']."CubeCart_admin_users", $record, "adminId = ".$admin_id);
|
||||
}
|
||||
|
||||
function get_cookie_domain($domain) {
|
||||
$cookie_domain = str_replace(array('http://', 'https://', 'www.'), '', strtolower($domain));
|
||||
$cookie_domain = explode("/",$cookie_domain);
|
||||
$cookie_domain = explode(":", $cookie_domain[0]);
|
||||
return '.'.$cookie_domain[0];
|
||||
}
|
||||
|
||||
function set_cc_admin_cookie($name, $value) {
|
||||
$expires = 0; ## remember session until browser is closed
|
||||
@setcookie($name, $value, $expires, $GLOBALS['rootRel']);
|
||||
}
|
||||
}
|
||||
?>
|
||||
210
production/classes/session/cc_session.php
Normal file
210
production/classes/session/cc_session.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| cc_session.php
|
||||
| ========================================
|
||||
| Front Session Class
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
class session {
|
||||
|
||||
var $ccUserData;
|
||||
var $ccUserBlocked = false;
|
||||
|
||||
var $config;
|
||||
var $db;
|
||||
var $glob;
|
||||
var $ini;
|
||||
|
||||
function session() {
|
||||
# $this->__construct();
|
||||
#}
|
||||
|
||||
#function __construct() {
|
||||
global $config, $db, $glob, $ini;
|
||||
|
||||
$this->config = $config;
|
||||
$this->db = $db;
|
||||
$this->glob = $glob;
|
||||
$this->ini = $ini;
|
||||
|
||||
if (isset($_GET[CC_SESSION_NAME])) {
|
||||
$this->set_cc_cookie(CC_SESSION_NAME, $_GET[CC_SESSION_NAME]);
|
||||
} else {
|
||||
## see if session is still in db
|
||||
$query = sprintf("SELECT sessId FROM %sCubeCart_sessions WHERE sessId=%s", $this->glob['dbprefix'], $this->db->mySQLSafe($GLOBALS[CC_SESSION_NAME]));
|
||||
|
||||
$results = $this->db->select($query);
|
||||
|
||||
## !empty($results[0]['sessId']) critical incase reuslts=true if session DB table has an empty sessionId!!
|
||||
if ($results && !empty($results[0]['sessId'])) {
|
||||
$data["timeLast"] = $this->db->mySQLSafe(time());
|
||||
$data["location"] = $this->db->mySQLSafe(currentPage());
|
||||
$update = $this->db->update($this->glob['dbprefix']."CubeCart_sessions", $data, "sessId=".$this->db->mySQLSafe($results[0]['sessId']));
|
||||
} else {
|
||||
$this->makeSession();
|
||||
}
|
||||
}
|
||||
|
||||
## get all session data and store as class array
|
||||
$query = sprintf("SELECT * FROM %1\$sCubeCart_sessions LEFT JOIN %1\$sCubeCart_customer ON %1\$sCubeCart_sessions.customer_id = %1\$sCubeCart_customer.customer_id WHERE sessId = %2\$s", $this->glob['dbprefix'], $this->db->mySQLSafe($GLOBALS[CC_SESSION_NAME]));
|
||||
$result = $this->db->select($query);
|
||||
// security checks
|
||||
|
||||
$client_ip = get_ip_address();
|
||||
|
||||
if (!empty($result[0]['ip']) && ($result[0]['ip'] !== $client_ip || $result[0]['browser'] !== $_SERVER['HTTP_USER_AGENT'])) {
|
||||
$this->destroySession($GLOBALS[CC_SESSION_NAME]);
|
||||
}
|
||||
$this->ccUserData = $result[0];
|
||||
|
||||
if (empty($result[0]['lang'])) {
|
||||
define("LANG_FOLDER", $this->config['defaultLang']);
|
||||
} else {
|
||||
define("LANG_FOLDER", $result[0]['lang']);
|
||||
}
|
||||
|
||||
if (empty($result[0]['skin'])) {
|
||||
define("SKIN_FOLDER", $this->config['skinDir']);
|
||||
} else {
|
||||
define("SKIN_FOLDER", $result[0]['skin']);
|
||||
}
|
||||
}
|
||||
|
||||
function destroySession($sessionId) {
|
||||
setcookie(CC_SESSION_NAME);
|
||||
$data["customer_id"] = '0';
|
||||
$update = $this->db->update($this->glob['dbprefix']."CubeCart_sessions", $data,"sessId=".$this->db->mySQLSafe($GLOBALS[CC_SESSION_NAME]));
|
||||
return ($update) ? true : false;
|
||||
}
|
||||
|
||||
function makeSession() {
|
||||
$sessionId = $this->makeSessId();
|
||||
$this->set_cc_cookie(CC_SESSION_NAME, $sessionId);
|
||||
|
||||
## set session global var because cookie won't show until next page load
|
||||
$GLOBALS[CC_SESSION_NAME] = $sessionId;
|
||||
|
||||
## insert sessionId into db
|
||||
$data["sessId"] = $this->db->mySQLSafe($sessionId);
|
||||
$timeNow = $this->db->mySQLSafe(time());
|
||||
$data["timeStart"] = $timeNow;
|
||||
$data["timeLast"] = $timeNow;
|
||||
$data["customer_id"] = 0;
|
||||
$data["ip"] = $this->db->mySQLSafe(get_ip_address());
|
||||
$data["browser"] = $this->db->mySQLSafe($_SERVER['HTTP_USER_AGENT']);
|
||||
|
||||
$insert = $this->db->insert($this->glob['dbprefix']."CubeCart_sessions", $data);
|
||||
$this->deleteOldSessions();
|
||||
}
|
||||
|
||||
function deleteOldSessions() {
|
||||
$expiredSessTime = time() - $this->config['sqlSessionExpiry'];
|
||||
/* Stock on add to basket possibly for future
|
||||
$this->reduce();
|
||||
*/
|
||||
## delete sessions older than time set in config file
|
||||
$delete = $this->db->delete($this->glob['dbprefix']."CubeCart_sessions", "timeLast<".$expiredSessTime);
|
||||
}
|
||||
|
||||
function authenticate($user, $pass, $remember = false) {
|
||||
$user = sanitizeVar($user);
|
||||
$pass = sanitizeVar($pass);
|
||||
$query = "SELECT customer_id FROM ".$this->glob['dbprefix']."CubeCart_customer WHERE email=".$this->db->mySQLSafe($user)." AND password = ".$this->db->mySQLSafe(md5($pass))." AND type>0";
|
||||
|
||||
$customer = $this->db->select($query);
|
||||
|
||||
if (!$customer) {
|
||||
if ($this->db->blocker($user, $this->ini['bfattempts'], $this->ini['bftime'], false, 'f')) {
|
||||
$this->ccUserBlocked = true;
|
||||
}
|
||||
} else if ($customer[0]['customer_id']>0) {
|
||||
|
||||
// remember user for as long as sessions are allowed in DB
|
||||
if ($remember == true) {
|
||||
$this->set_cc_cookie(CC_SESSION_NAME, $GLOBALS[CC_SESSION_NAME], $this->config['sqlSessionExpiry']);
|
||||
}
|
||||
|
||||
if ($this->db->blocker($user, $this->ini['bfattempts'], $this->ini['bftime'], true, 'f')) {
|
||||
$this->ccUserBlocked = true;
|
||||
} else {
|
||||
$data["customer_id"] = $customer[0]['customer_id'];
|
||||
$update = $this->db->update($this->glob['dbprefix']."CubeCart_sessions", $data,"sessId=".$this->db->mySQLSafe($GLOBALS[CC_SESSION_NAME]));
|
||||
|
||||
## "login","reg","unsubscribe","forgotPass" etc..
|
||||
$redir = sanitizeVar(urldecode($_GET['redir']));
|
||||
|
||||
## prevent phishing attacks
|
||||
if (eregi("^http://|^https://",$redir) && !eregi("^".$this->glob['storeURL']."|^".$this->config['storeURL_SSL'], $redir)) {
|
||||
die("Redirect URL not allowed!");
|
||||
}
|
||||
if (isset($_GET['redir']) && !empty($_GET['redir']) && !eregi("logout|login|forgotPass|changePass", $redir)) {
|
||||
httpredir($redir);
|
||||
} else {
|
||||
httpredir($GLOBALS['rootRel']."index.php");
|
||||
}
|
||||
}
|
||||
} else if (eregi("step1", urldecode($_GET['redir']))) {
|
||||
httpredir($GLOBALS['rootRel']."index.php?_g=co&_a=step1");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function makeSessId() {
|
||||
session_start();
|
||||
session_regenerate_id(true);
|
||||
return session_id();
|
||||
}
|
||||
|
||||
function get_cookie_domain($domain) {
|
||||
$cookie_domain = str_replace(array('http://', 'https://', 'www.'), '', strtolower($domain));
|
||||
$cookie_domain = explode("/", $cookie_domain);
|
||||
$cookie_domain = explode(":", $cookie_domain[0]);
|
||||
return '.'.$cookie_domain[0];
|
||||
}
|
||||
|
||||
function set_cc_cookie($name, $value, $length = '') {
|
||||
## only set the cookie if the visitor is not a spider or search engine system is off
|
||||
if (!$this->user_is_search_engine() || $this->config['sef'] == false) {
|
||||
$expires = ($length>0) ? (time()+$length) : 0;
|
||||
setcookie($name, $value, $expires, $GLOBALS['rootRel']);
|
||||
}
|
||||
}
|
||||
|
||||
function user_is_search_engine() {
|
||||
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
$spider_flag = false;
|
||||
if (($user_agent != '') && (strtolower($user_agent) != 'null') && (strlen(trim($user_agent)) > 0)) {
|
||||
$spiders = file(CC_ROOT_DIR.'/spiders.txt');
|
||||
foreach ($spiders as $spider) {
|
||||
if (($spider != '') && (strtolower($spider) != 'null') && (strlen(trim($spider)) > 0)) {
|
||||
if (strpos($user_agent, trim($spider)) !== false) {
|
||||
$spider_flag = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $spider_flag;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
296
production/classes/validate/validateCard.php
Normal file
296
production/classes/validate/validateCard.php
Normal file
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
/*
|
||||
+--------------------------------------------------------------------------
|
||||
| CubeCart 4
|
||||
| ========================================
|
||||
| CubeCart is a registered trade mark of Devellion Limited
|
||||
| Copyright Devellion Limited 2006. All rights reserved.
|
||||
| Devellion Limited,
|
||||
| 5 Bridge Street,
|
||||
| Bishops Stortford,
|
||||
| HERTFORDSHIRE.
|
||||
| CM23 2JU
|
||||
| UNITED KINGDOM
|
||||
| http://www.devellion.com
|
||||
| UK Private Limited Company No. 5323904
|
||||
| ========================================
|
||||
| Web: http://www.cubecart.com
|
||||
| Email: info (at) cubecart (dot) com
|
||||
| License Type: CubeCart is NOT Open Source Software and Limitations Apply
|
||||
| Licence Info: http://www.cubecart.com/site/faq/license.php
|
||||
+--------------------------------------------------------------------------
|
||||
| validateCard.php
|
||||
| ========================================
|
||||
| Class to Validate Credit Card
|
||||
+--------------------------------------------------------------------------
|
||||
*/
|
||||
class validateCard {
|
||||
|
||||
var $data;
|
||||
function check($cardNo, $issueNo='', $issueDate='', $issueFormat=4, $expireDate='', $expireFormat=4, $scReqd=false, $securityCode='') {
|
||||
|
||||
$cardNo = ereg_replace("[^0-9]", '', $cardNo);
|
||||
|
||||
## Assume success unless a rule is broken
|
||||
$this->data['response'] = "SUCCESS";
|
||||
|
||||
## check expire date (always required)
|
||||
$this->expireDate($expireDate,$expireFormat);
|
||||
|
||||
if ($scReqd == true) $this->securityCode($securityCode);
|
||||
|
||||
/************************************************
|
||||
* BEGIN: Regular Expressions to validate Certain Cards
|
||||
************************************************/
|
||||
|
||||
$mastercard = "^5[1-5][0-9]{14}$";
|
||||
$visa = "^4[0-9]{12}([0-9]{3})?$";
|
||||
// $americanExpress = "^3[47][0-9]{13}$"; old in 4.0.3
|
||||
//$americanExpress = "((^3[47])|(^3[34])|(^3[37]))((\d{11}$)|(\d{13}$))";
|
||||
$americanExpress = "^[34|37|47]([0-9]{14}|[0-9]{12})$";
|
||||
$diners = "^3(0[0-5]|[68][0-9])[0-9]{11}$";
|
||||
$discover = "^6011[0-9]{12}$";
|
||||
$jcb = "^(3[0-9]{4}|2131|1800)[0-9]{11}$";
|
||||
$australianBankCard = "^5610([0-9]{12})?$";
|
||||
$enRoute = "^(2014|2149)([0-9]{11})?$";
|
||||
$electron = "^(450875|48440[6-9]{1}|4844[1-4]{1}[0-9]{1}|48445[0-5]{1}|4917[3-5]{1}[0-9]{1}|491880|5[1-5]{1})([0-9]{10}|[0-9]{14})?$";//
|
||||
$delta = "^(41373[3-7]{1}|4462[0-9]{2}|45397[8-9]{1}|454313|45443[2-5]{1}|454742|45672[5-9]{1}|45673[0-9]{1}|45674[0-5]{1}|4658[3-7]{1}[0-9]{1}|4659[0-5]{1}[0-9]{1}|4609[6-7]{1}[0-9]{1}|49218[1-2]{1}|498824)([0-9]{10})?$";
|
||||
$solo = "^(6334[5-9]{1}[0-9]{1}|6767[0-9]{2}|3528[0-9]{2})([0-9]{10})?$";
|
||||
$maestro = "^(5000[0-9]{2}|5[6-8]{1}|6[0-9]{5})([0-9]{10}|[0-9]{14})?$";
|
||||
$switch = "^(49030[2-9]{1}|49033[5-9]{1}|49110[1-2]{1}|49117[4-9]{1}|49118[0-2]{1}|4936[0-9]{2}|564182|6333[1-4]{1}[0-9]{1}|6759[0-9]{2})([0-9]{10}|[0-9]{12}|[0-9]{13})?$";
|
||||
|
||||
/************************************************
|
||||
* END: Regular Expressions to validate Certain Cards
|
||||
************************************************/
|
||||
|
||||
if (empty($cardNo)) {
|
||||
$this->error(6);
|
||||
} elseif (ereg($mastercard, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "MASTERCARD";
|
||||
|
||||
} elseif (ereg($electron, $cardNo)) {
|
||||
$this->data['cardType'] = "ELECTRON";
|
||||
|
||||
} elseif(ereg($visa, $cardNo)) {
|
||||
## mod 10 fails on 13 length card nos :( Booooooooooooooooooooooooooooo
|
||||
if (strlen($cardNo) !== 13) $this->mod10($cardNo);
|
||||
$this->data['cardType'] = "VISA";
|
||||
|
||||
} elseif (ereg($americanExpress, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "AMERICAN EXPRESS";
|
||||
|
||||
} elseif (ereg($diners, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "DINERS";
|
||||
|
||||
} elseif (ereg($discover, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "DISCOVER";
|
||||
|
||||
} elseif (ereg($enRoute, $cardNo)) {
|
||||
$this->data['cardType'] = "ENROUTE";
|
||||
|
||||
} elseif (ereg($jcb, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "JCB";
|
||||
|
||||
} elseif (ereg($australianBankCard, $cardNo)) {
|
||||
$this->data['cardType'] = "AUSTRALIAN BANK CARD";
|
||||
|
||||
} elseif (ereg($delta, $cardNo)) {
|
||||
$this->data['cardType'] = "DELTA";
|
||||
|
||||
} elseif (ereg($switch, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "SWITCH";
|
||||
|
||||
## switch/maestro/solo requires an issue date or number
|
||||
if (!$this->issueDate($issueDate,$issueFormat) || !$this->issueNo($issueNo)) $this->error(3);
|
||||
|
||||
} elseif (ereg($solo, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "SOLO";
|
||||
|
||||
## switch/maestro/solo requires an issue date or number
|
||||
if (!$this->issueDate($issueDate,$issueFormat) || !$this->issueNo($issueNo)) $this->error(3);
|
||||
|
||||
} elseif (ereg($maestro, $cardNo)) {
|
||||
$this->mod10($cardNo);
|
||||
$this->data['cardType'] = "MAESTRO";
|
||||
|
||||
## switch/maestro/solo requires an issue date or number
|
||||
if (!$this->issueDate($issueDate,$issueFormat) || !$this->issueNo($issueNo)) $this->error(3);
|
||||
} else {
|
||||
$this->error(1);
|
||||
}
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
// LUHN formula
|
||||
function mod10($cardNo) {
|
||||
|
||||
$numSum = 0;
|
||||
|
||||
for($i = 0; $i < strlen($cardNo); $i++) {
|
||||
|
||||
$currentNum = substr($cardNo, $i, 1);
|
||||
|
||||
if($i % 2 == 1) {
|
||||
$currentNum *= 2;
|
||||
}
|
||||
|
||||
if($currentNum > 9) {
|
||||
$firstNum = $currentNum % 10;
|
||||
$secondNum = ($currentNum - $firstNum) / 10;
|
||||
$currentNum = $firstNum + $secondNum;
|
||||
}
|
||||
|
||||
$numSum += $currentNum;
|
||||
|
||||
}
|
||||
|
||||
$passCheck = ($numSum % 10 == 0);
|
||||
|
||||
if($passCheck == 0){
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
$this->error(5);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function expireDate($expireDate,$expireFormat){
|
||||
|
||||
if(strlen($expireDate) !== $expireFormat){
|
||||
|
||||
$this->error(2);
|
||||
return false;
|
||||
|
||||
} elseif($expireFormat == 4 && $expireDate<date("ym")) {
|
||||
|
||||
$this->error(2);
|
||||
return false;
|
||||
|
||||
} elseif($expireFormat == 6 && $expireDate<date("Ym")) {
|
||||
|
||||
$this->error(2);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function issueDate($issueDate,$issueFormat) {
|
||||
|
||||
|
||||
if(strlen($issueDate) !== $issueFormat){
|
||||
|
||||
$this->error(3);
|
||||
return false;
|
||||
|
||||
} elseif($issueFormat == 4 && $issueDate>date("ym")) {
|
||||
|
||||
$this->error(3);
|
||||
return false;
|
||||
|
||||
} elseif($issueFormat == 6 && $issueDate>date("Ym")) {
|
||||
|
||||
$this->error(3);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function issueNo($issueNo) {
|
||||
|
||||
if($issueNo>0){
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function securityCode($securityCode) {
|
||||
|
||||
if(($securityCode>0 && $securityCode<10000) && (strlen($securityCode)==3 || strlen($securityCode)==4)) {
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
$this->error(4);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function error($errorCode) {
|
||||
|
||||
global $lang;
|
||||
|
||||
$this->data['response'] = "FAIL";
|
||||
|
||||
switch($errorCode) {
|
||||
case(1):
|
||||
|
||||
$this->data['error'][1] = "Card not recognised!";
|
||||
|
||||
break;
|
||||
|
||||
case(2):
|
||||
|
||||
$this->data['error'][2] = "No expiry date was entered or it wasn't valid.";
|
||||
|
||||
break;
|
||||
|
||||
case(3):
|
||||
|
||||
$this->data['error'][3] = "Please enter a valid issue number or date.";
|
||||
|
||||
break;
|
||||
|
||||
case(4):
|
||||
|
||||
$this->data['error'][4] = "Please enter a valid security code.";
|
||||
|
||||
break;
|
||||
|
||||
case(5):
|
||||
|
||||
$this->data['error'][5] = "Credit card number is not valid.";
|
||||
|
||||
break;
|
||||
|
||||
case(6):
|
||||
|
||||
$this->data['error'][5] = "Please enter a card number.";
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
1018
production/classes/xtpl/xtpl.php
Normal file
1018
production/classes/xtpl/xtpl.php
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user