* @copyright 2007-2012 PrestaShop SA
* @version Release: $Revision: 1.4 $
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
/* Security */
if (!defined('_PS_VERSION_'))
exit;
if (file_exists(dirname(__FILE__).'/HelperFn.php'))
include(dirname(__FILE__).'/HelperFn.php');
elseif (file_exists(dirname(__FILE__).'/../modules/shipwire/HelperFn.php'))
include(dirname(__FILE__).'/../modules/shipwire/HelperFn.php');
$includeFiles = array(
'ShipwireApi.php',
'ShipwireInventoryUpdate.php',
'ShipwireOrder.php',
'ShipwireTracking.php',
'SWCurl.php',
);
foreach ($includeFiles as $file)
{
if (!HelperFn::safeFileName($file))
die();
if (file_exists(dirname(__FILE__).'/lib/'.$file))
require(dirname(__FILE__).'/lib/'.$file);
elseif (file_exists(dirname(__FILE__).'/../modules/shipwire/lib/'.$file))
require(dirname(__FILE__).'/../modules/shipwire/lib/'.$file);
}
class Shipwire extends Module
{
/** @var _cipherTool Helper Object to encrypt API KEY */
private $_cipherTool;
/** @var dParams Array replacing smarty (display parameters) */
private $dParams = array();
/** @const _SHIPWIRE_SERVER Shipwire server url */
private $_configVars = array(
'SHIPWIRE_API_SERVER' => '',
'SHIPWIRE_API_USER' => '',
'SHIPWIRE_API_PASSWD' => '',
'SHIPWIRE_API_CONNECTED' => '',
'SHIPWIRE_API_MODE' => '',
'SHIPWIRE_WAREHOUSE' => '',
'SHIPWIRE_ACCOUNT_NAME' => '',
'SHIPWIRE_TRACKING_LAST_DATE' => '',
'SHIPWIRE_COMMIT_ID' => '',
'SHIPWIRE_SENT_ID' => '',
'SHIPWIRE_DELIVERED_ID' => '',
);
/** @var _shipWireInventoryUpdate Shipwire Api Object */
private $_shipWireInventoryUpdate;
/******************************************************************/
/** Construct Method **********************************************/
/******************************************************************/
public function __construct()
{
$this->name = 'shipwire';
$this->tab = 'shipping_logistics';
$this->version = '1.1.5';
$this->author = 'PrestaShop';
$this->_initContext();
parent::__construct();
$this->displayName = $this->l('Shipwire');
$this->description = $this->l('Enterprise logistics for everyone.');
if (Configuration::get('PS_CIPHER_ALGORITHM'))
$this->_cipherTool = new Rijndael(_RIJNDAEL_KEY_, _RIJNDAEL_IV_);
else
$this->_cipherTool = new Blowfish(_COOKIE_KEY_, _COOKIE_IV_);
$this->_shipWireInventoryUpdate = new ShipwireInventoryUpdate(Configuration::get('SHIPWIRE_API_USER'), $this->_cipherTool->decrypt(Configuration::get('SHIPWIRE_API_PASSWD')));
$this->_shipWireOrder = new ShipwireOrder();
}
/**
* @brief Make the module compatible 1.4/1.5
*/
private function _initContext()
{
/* Backward compatibility */
require(_PS_MODULE_DIR_.$this->name.'/backward_compatibility/backward.php');
$this->context->smarty->assign('base_dir', __PS_BASE_URI__);
$this->dParams['base_dir'] = __PS_BASE_URI__;
if (class_exists('Context') && function_exists('getContent'))
$this->context = Context::getContent();
else
{
global $smarty, $cookie;
$this->context = new StdClass();
$this->context->smarty = $smarty;
$this->context->cookie = $cookie;
$this->context->shop = new StdClass();
$this->context->shop->id = 1;
$this->context->shop->id_group_shop = 1;
}
$this->_loadConfiguration();
}
private function _loadConfiguration()
{
foreach ($this->_configVars as $key => $v)
$this->_configVars[$key] = Configuration::get($key);
}
/**
* @brief Install/Uninstall Configuration variables
*
* @param install True for installation, false for uninstall
*
* @return Success or failure
*/
private function _setupConfigVariables($install = true)
{
$configVars = array(
'SHIPWIRE_API_SERVER' => '',
'SHIPWIRE_API_USER' => '',
'SHIPWIRE_API_PASSWD' => '',
'SHIPWIRE_API_CONNECTED' => 0,
'SHIPWIRE_ACCOUNT_NAME' => '',
'SHIPWIRE_API_MODE' => 'Test',
'SHIPWIRE_WAREHOUSE' => '00',
'SHIPWIRE_TRACKING_LAST_DATE' => 0,
'SHIPWIRE_COMMIT_ID' => 2,
'SHIPWIRE_SENT_ID' => 4,
'SHIPWIRE_DELIVERED_ID' => 5,
'SHIPWIRE_LOG_LIFE' => 10,
);
$error = 0;
foreach ($configVars as $varName => $value)
if ($install)
$error += Configuration::updateValue($varName, $value) ? 0 : 1;
else
$error += Configuration::deleteByName($varName) ? 0 : 1;
return !$error;
}
/******************************************************************/
/** Install / Uninstall Methods ***********************************/
/******************************************************************/
public function install()
{
// Setup config variable with 'install' flag on
if (!$this->_setupConfigVariables(true))
return false;
if (!parent::install() || !$this->registerHook('backOfficeTop') || !$this->registerHook('updateOrderStatus'))
return false;
// Perform the sql install
include(dirname(__FILE__).'/sql/sql-install.php');
foreach ($sql as $s)
if (!Db::getInstance()->Execute($s))
return false;
return true;
}
/**
* @brief Uninstall function
*
* @return Success or failure
*/
public function uninstall()
{
// Uninstall parent and unregister Configuration
if (!parent::uninstall())
return false;
// Unregister hook
if (!$this->unregisterHook('backOfficeTop') || !$this->unregisterHook('updateOrderStatus'))
return false;
// Remove configuration variable with 'install' flag off
if (!$this->_setupConfigVariables(false))
return false;
// Uninstall SQL
include(dirname(__FILE__).'/sql/sql-uninstall.php');
foreach ($sql as $s)
if (!Db::getInstance()->Execute($s))
return false;
return true;
}
/**
* @brief hookBackOfficeTop Implementation.
*
* Hook that allow to add script anywhere in the backoffice.
*
* @return Render to display
*/
public function hookBackOfficeTop()
{
$r = array();
if (isset($_GET['id_order']))
$r = Db::getInstance()->ExecuteS('SELECT `id_order`, `transaction_ref`, `order_ref`, `status`
FROM `'._DB_PREFIX_.'shipwire_order`
WHERE `id_order` = '.(int)$_GET['id_order'].'
AND `id_shop` = \''.(int)$this->context->shop->id.'\'');
$status = isset($r[0]['status']) && !empty($r[0]['status']) ? ucfirst($r[0]['status']) : $this->l('Not sent to Shipwire.');
$buffer = '
';
echo $buffer;
}
/**
* @brief hookUpdateOrderStatus Implementation.
*
* @return ?
*/
public function hookUpdateOrderStatus($params)
{
$orderStatusId = $params['newOrderStatus']->id;
// We check the orderstatus
if ($orderStatusId != $this->_configVars['SHIPWIRE_COMMIT_ID'])
return false;
// Check that the order was not already commited to Shipwire
$r = Db::getInstance()->ExecuteS('SELECT `id_order`, `transaction_ref`, `order_ref`, `status`
FROM `'._DB_PREFIX_.'shipwire_order`
WHERE `id_order` = '.(int)$params['id_order'].'
AND `id_shop` = \''.(int)$this->context->shop->id.'\'');
if (!(isset($r[0]['transaction_ref']) && !empty($r[0]['transaction_ref'])))
{
$this->updateOrderStatus($params['id_order']);
ShipwireTracking::updateTracking(true, (int)$this->context->shop->id, (int)$this->context->shop->id_group_shop);
}
return true;
}
public function updateOrderStatus($idOrder, $refresh = false)
{
$order = new Order($idOrder);
if (!$order->id)
return false;
$address = new Address($order->id_address_delivery);
$customer = new Customer($order->id_customer);
$carrier = new Carrier($order->id_carrier);
$cart = new Cart($order->id_cart);
$products = $cart->getProducts();
$packageList = array();
foreach ($products as $product)
{
$packageList[] = array(
'code' => (!empty($product['reference']) ? pSQL($product['reference']) : (int)$product['id_product_attribute']), // SKU
'quantity' => (int)$product['cart_quantity'],
);
}
switch ($order->id_carrier)
{
default:
case Configuration::get('SHIPWIRE_GD') :
$shippingType = 'GD';
break;
case Configuration::get('SHIPWIRE_1D') :
$shippingType = '1D';
break;
case Configuration::get('SHIPWIRE_2D') :
$shippingType = '2D';
break;
case Configuration::get('SHIPWIRE_INTL') :
$shippingType = 'INTL';
break;
}
$this->_shipWireOrder->addOrder(array(
'orderId' => $order->id,
'name' => $customer->firstname.'.'.$customer->lastname,
'address1' => $address->address1,
'address2' => $address->address2,
'city' => $address->city,
'country' => $address->country,
'zip' => $address->postcode,
'phone' => $address->phone,
'mail' => $customer->email,
'shippingType' => $shippingType,
'packageList' => $packageList,
), $refresh);
$r = $this->_shipWireOrder->sendData();
if ($r['Status'])
$this->_displayConfirmation($this->l('An error occured on the remote server: ').$r['ErrorMessage'], 'error');
if (isset($r['OrderInformation']))
foreach ($r['OrderInformation'] as $o)
{
if ($o['@attributes']['number'] != $order->id)
$this->_displayConfirmation($this->l('An unkown error occured with order Id.'), 'error');
//$val = Db::getInstance()->getValue('SELECT `transaction_ref` FROM `'._DB_PREFIX_.'shipwire_order`
// WHERE `id_order` = '.(int)$order->id);
$orderExists = Db::getInstance()->ExecuteS('SELECT `id_order` FROM `'._DB_PREFIX_.'shipwire_order`
WHERE `id_order` = '.(int)$order->id.' LIMIT 1');
if (isset($orderExists[0]['id_order']) && $orderExists[0]['id_order'])
{
Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'shipwire_order`
SET `transaction_ref` = \''.pSQL($o['@attributes']['id']).'\',
`order_ref` = \''.pSQL($o['@attributes']['number']).'\',
`status` = \''.pSQL($o['@attributes']['status']).'\'
WHERE `id_order` = '.(int)$order->id);
}
else
{
Db::getInstance()->Execute('INSERT INTO `'._DB_PREFIX_.'shipwire_order`
(`id_order`, `transaction_ref`, `status`, `id_shop`, `id_group_shop`)
VALUES (
\''.pSQL($order->id).'\''
.(isset($o['id']) ? ',\''.pSQL($o['id']).'\'' : ',\'\'')
.(isset($o['status']) ? ',\''.pSQL($o['status']).'\'' : ',\'\'')
.(isset($this->context->shop->id_group_shop) ? ',\''.(int)$this->context->shop->id_group_shop.'\'' : ',\'\'')
.(isset($this->context->shop->id) ? ',\''.(int)$this->context->shop->id.'\'' : ',\'\'').'
)');
}
$this->log((int)$order->id, $o['@attributes']['id']);
}
return true;
}
/**
* @brief Main Form Method
*
* @return Rendered form
*/
public function getContent()
{
$idShop = isset($this->context->shop->id) ? $this->context->shop->id : 1;
$idGroupShop = isset($this->context->shop->id_group_shop) ? $this->context->shop->id_group_shop : 1;
if (Tools::isSubmit('SubmitShipwireSettings'))
{
if (Validate::isEmail(Tools::getValue('shipwire_api_user')))
{
Configuration::updateValue('SHIPWIRE_API_CONNECTED', 0);
Configuration::updateValue('SHIPWIRE_API_USER',
Tools::getValue('shipwire_api_user'));
Configuration::updateValue('SHIPWIRE_API_PASSWD',
$this->_cipherTool->encrypt(Tools::getValue('shipwire_api_passwd')));
$this->dParams['confirmMessage'] = $this->_displayConfirmation();
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'shipwire_order` '.
(isset($this->context->shop->id) && isset($this->context->shop->id_group_shop) ?
'WHERE `id_shop` = '.(int)$this->context->shop->id.'
AND `id_group_shop` = '.(int)$this->context->shop->id_group_shop : ''));
Db::getInstance()->Execute('DELETE FROM `'._DB_PREFIX_.'shipwire_stock` '.
(isset($this->context->shop->id) && isset($this->context->shop->id_group_shop) ?
'WHERE `id_shop` = '.(int)$this->context->shop->id.'
AND `id_group_shop` = '.(int)$this->context->shop->id_group_shop : ''));
}
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Please enter a valid email address.'), 'error');
}
elseif (Tools::isSubmit('SubmitShipwireTestConnection'))
{
$connectionTestResult = $this->_testConnection();
}
elseif (Tools::isSubmit('SubmitShipwireOptions'))
{
$duplicates = 0;
Configuration::updateValue('SHIPWIRE_COMMIT_ID', (int)Tools::getValue('shipwire_commit_id'));
Configuration::updateValue('SHIPWIRE_SENT_ID', (int)Tools::getValue('shipwire_sent_id'));
Configuration::updateValue('SHIPWIRE_DELIVERED_ID', (int)Tools::getValue('shipwire_delivered_id'));
Configuration::updateValue('SHIPWIRE_LOG_LIFE', ((int)Tools::getValue('shipwire_log_life') < 1 ? 1 : (int)Tools::getValue('shipwire_log_life')));
// Carrier selection
//GD
if ((Tools::getValue('shipwire_gd') != Tools::getValue('shipwire_1d')
&& Tools::getValue('shipwire_gd') != Tools::getValue('shipwire_2d')
&& Tools::getValue('shipwire_gd') != Tools::getValue('shipwire_intl'))
|| Tools::getValue('shipwire_gd') == 0)
Configuration::updateValue('SHIPWIRE_GD', (int)Tools::getValue('shipwire_gd'));
else
$duplicates = 1;
//1d
if ((Tools::getValue('shipwire_1d') != Tools::getValue('shipwire_gd')
&& Tools::getValue('shipwire_1d') != Tools::getValue('shipwire_2d')
&& Tools::getValue('shipwire_1d') != Tools::getValue('shipwire_intl'))
|| Tools::getValue('shipwire_1d') == 0)
Configuration::updateValue('SHIPWIRE_1D', (int)Tools::getValue('shipwire_1d'));
else
$duplicates = 1;
//2d
if ((Tools::getValue('shipwire_2d') != Tools::getValue('shipwire_gd')
&& Tools::getValue('shipwire_2d') != Tools::getValue('shipwire_1d')
&& Tools::getValue('shipwire_2d') != Tools::getValue('shipwire_intl'))
|| Tools::getValue('shipwire_2d') == 0)
Configuration::updateValue('SHIPWIRE_2D', (int)Tools::getValue('shipwire_2d'));
else
$duplicates = 1;
//INTL
if ((Tools::getValue('shipwire_intl') != Tools::getValue('shipwire_gd')
&& Tools::getValue('shipwire_intl') != Tools::getValue('shipwire_1d')
&& Tools::getValue('shipwire_intl') != Tools::getValue('shipwire_2d'))
|| Tools::getValue('shipwire_intl') == 0)
Configuration::updateValue('SHIPWIRE_INTL', (int)Tools::getValue('shipwire_intl'));
else
$duplicates = 1;
//Check for errors
if ($duplicates)
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('The shipping methods were not saved
because duplicate values are not allowed.'), 'warn');
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation();
}
elseif (Tools::isSubmit('SubmitUpdateStock'))
{
if ($this->_shipWireInventoryUpdate->getInventory())
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Stock updated.'));
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Stock update failed'), 'error');
}
elseif (Tools::isSubmit('SubmitUpdateTracking'))
{
if (ShipwireTracking::updateTracking(true, $idShop, $idGroupShop))
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Transactions updated.'));
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Transactions update failed.'), 'error');
}
elseif (Tools::isSubmit('resend_id_order'))
{
if ($this->updateOrderStatus(Tools::getValue('resend_id_order')))
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Order successfully resent.'));
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Error while sending. Try again later.'), 'error');
}
elseif (Tools::isSubmit('SubmitResendFailedTransactions'))
{
$d = Db::getInstance()->ExecuteS('SELECT `id_order`
FROM `'._DB_PREFIX_.'shipwire_order`
WHERE `transaction_ref` IS NULL OR `transaction_ref` = \'\''
.(isset($this->context->shop->id) ? 'AND `id_shop` = \''.(int)$this->context->shop->id.'\'' : ''));
foreach ($d as $line)
$this->updateOrderStatus($line['id_order']);
if (ShipwireTracking::updateTracking(true, (int)$idShop, (int)$idGroupShop))
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Transactions successfully resent.'));
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Error resending transactions.'), 'error');
}
elseif (Tools::isSubmit('SubmitCleanLogs'))
{
if (Db::getInstance()->Execute('TRUNCATE `'._DB_PREFIX_.'shipwire_log`'))
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Logs empty.'));
else
$this->dParams['confirmMessage'] = $this->_displayConfirmation($this->l('Error deleting logs.'), 'error');
}
$confValues = Configuration::getMultiple(array(
'SHIPWIRE_API_USER',
'SHIPWIRE_API_PASSWD'));
/// @todo : check if these assigns are necessary
$this->dParams['defaultOriginServerURL'] = 'http://'.Tools::safeOutput(Configuration::get('PS_SHOP_DOMAIN')).__PS_BASE_URI__;
$this->dParams['serverRequestUri'] = Tools::safeOutput($_SERVER['REQUEST_URI']);
$this->dParams['displayName'] = Tools::safeOutput($this->displayName);
if (isset($connectionTestResult))
$this->dParams['connectionTestResult'] = $connectionTestResult;
if (isset($confValues['SHIPWIRE_API_USER']))
$this->dParams['apiEmail'] = Tools::safeOutput($confValues['SHIPWIRE_API_USER']);
if (isset($confValues['SHIPWIRE_API_PASSWD']))
$this->dParams['apiPasswd'] = Tools::safeOutput($this->_cipherTool->decrypt($confValues['SHIPWIRE_API_PASSWD']));
return $this->_displayContent();
}
/**
* @brief Test the conenction to Shipwire and the credentials.
*
* In order to test that, we just try to get the pullzones amd we check if
* the server reply the errorCode 0. If can't connect or other errorCode, then
* there is something wrong.
*
* @return True if the connection is OK, false otherwise
*/
private function _testConnection()
{
if ($this->_shipWireInventoryUpdate->getInventory('Status') == 'Error')
return array('
'.$this->l('Connection Test Failed.').'',
'#FFD8D8', false);
Configuration::updateValue('SHIPWIRE_API_CONNECTED', 1);
return array('
'.$this->l('Congratulations! Your store is now linked to Shipwire.').'
',
'#D6F5D6', true);
}
/*
** Display a custom message for settings update
** $text string Text to be displayed in the message
** $type string (confirm|warn|error) Decides what color will the
** message have (green|yellow)
*/
private function _displayConfirmation($text = '', $type = 'confirm')
{
switch ($type)
{
case 'confirm':
$img = 'ok.gif';
break ;
case 'warn':
$img = 'warn2.png';
break ;
case 'error':
$img = 'disabled.gif';
break ;
default:
die('Invalid type.');
}
return array(
'class' => Tools::safeOutput($type),
'img' => (version_compare(_PS_VERSION_, '1.5', '<') ? Tools::safeOutput($img) : false),
'text' => (empty($text) ? $this->l('Settings updated') : Tools::safeOutput($text))
);
}
/******************************************************************/
/** Web-service methods *******************************************/
/******************************************************************/
/******************************************************************/
/** Tools methods *************************************************/
/******************************************************************/
public function getCurrentURL($htmlEntities = false)
{
$url = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
return (!empty($_SERVER['HTTPS']) ? 'https' : 'http').
'://'.($htmlEntities ? preg_replace('/&/', '&', $url): $url);
}
public function log($orderId, $transactionId)
{
return Db::getInstance()->Execute('REPLACE INTO `'._DB_PREFIX_.'shipwire_log`
(`transaction_ref`, `id_order`, `date_added`, `id_shop`, `id_group_shop`)
VALUES (\''.pSQL($transactionId).'\',
'.(int)$orderId.'
,\''.date('Y-m-d H:i:s').'\'
,'.(isset($this->context->shop->id) ? '\''.(int)$this->context->shop->id.'\'' : '\'\'').'
,'.(isset($this->context->shop->id_group_shop) ? ',\''.(int)$this->context->shop->id_group_shop.'\'' : '\'\'').'
)');
}
/******************************************************************/
/** Display methods *************************************************/
/******************************************************************/
private function _displayContent()
{
$cookie = $this->context->cookie;
$buffer = '
';
if (isset($this->dParams['confirmMessage']))
$buffer .= '