* @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__).'/lib/CloudCacheApi.php'))
require(dirname(__FILE__).'/lib/CloudCacheApi.php');
elseif (file_exists(dirname(__FILE__).'/../modules/cloudcache/lib/CloudCacheApi.php'))
require(dirname(__FILE__).'/../modules/cloudcache/lib/CloudCacheApi.php');
define('CLOUDCACHE_API_PORT', 80);
define('CLOUDCACHE_API_HTTP_METHOD', 'http11');
define('CLOUDCACHE_API_URI', '/xmlrpc/');
define('CLOUDCACHE_API_URL', 'api.netdna.com');
define('CLOUDCACHE_API_ZONE_URL', 'netdna-cdn.com');
define('CLOUDCACHE_API_HASH_TYPE', 'sha256');
define('CLOUDCACHE_API_PULL_ZONE_TYPE', 1);
class CloudCache extends Module
{
/** @var _cipherTool Helper Object to encrypt API KEY */
private $_cipherTool;
/** @var _api Cloudcache Api Object */
private $_api;
/******************************************************************/
/** Construct Method **********************************************/
/******************************************************************/
public function __construct()
{
$this->name = 'cloudcache';
$this->tab = 'administration';
$this->version = '1.2';
$this->author = 'PrestaShop';
parent::__construct();
$this->displayName = $this->l('CloudCache');
$this->description = $this->l('Supercharge your Shop with the CloudCache.com Content Delivery Network (CDN).');
/* Backward compatibility */
require(_PS_MODULE_DIR_.$this->name.'/backward_compatibility/backward.php');
$this->context->smarty->assign('base_dir', __PS_BASE_URI__);
if (Configuration::get('PS_CIPHER_ALGORITHM'))
$this->_cipherTool = new Rijndael(_RIJNDAEL_KEY_, _RIJNDAEL_IV_);
else
$this->_cipherTool = new Blowfish(_COOKIE_KEY_, _COOKIE_IV_);
$this->_api = new CloudcacheApi();
}
/**
* @brief Install/Uninstall Configuration variables
*
* @param install True for installation, false for uninstall
*
* @return Success or failure
*/
private function _setupConfigVariables($install = true)
{
$configVars = array(
'CLOUDCACHE_API_USER' => '',
'CLOUDCACHE_API_KEY' => '',
'CLOUDCACHE_API_COMPANY_ID' => '',
'CLOUDCACHE_API_ACTIVE' => 0,
);
$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 > 0 ? false : true;
}
private function _installOverride()
{
// Hash of the empty file in 1.5 => file name
$files = array('810f3fa83a88b5019be31d7b80db460d' => 'classes/Tools.php');
if (_PS_VERSION_ > '1.5')
$files['5b917f57038acb75714cf144c9043bb4'] = 'classes/controller/FrontController.php';
// Make sure the environment is OK
if (!is_dir(dirname(__FILE__).'/../../override/classes/'))
mkdir(dirname(__FILE__).'/../../override/classes/', 0777, true);
if (_PS_VERSION_ > '1.5' && !is_dir(dirname(__FILE__).'/../../override/classes/controller/'))
mkdir(dirname(__FILE__).'/../../override/classes/controller/', 0777);
$errors = array();
foreach ($files as $hash => $path)
{
if (file_exists(dirname(__FILE__).'/../../override/'.$path))
{
if (md5_file(dirname(__FILE__).'/../../override/'.$path) == $hash)
rename(dirname(__FILE__).'/../../override/'.$path, dirname(__FILE__).'/../../override/'.$path.'.origin.php');
elseif (md5_file(dirname(__FILE__).'/../../override/'.$path) == md5_file(dirname(__FILE__).'/override/'.$path))
continue ;
else
{
$errors[] = '/override/'.$path;
continue ;
}
}
if (!copy(dirname(__FILE__).'/override/'.$path, dirname(__FILE__).'/../../override/'.$path))
$errors[] = '/override/'.$path;
}
if (count($errors))
die('

'.
$this->l('The module was successfully installed (').
'
'.$this->l('configure').''.
$this->l(') but the following file already exist. Please, merge the file manually.').'
'.
implode('
', $errors).
'
');
return true;
}
/******************************************************************/
/** 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'))
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 $this->_installOverride();
}
/**
* @brief Uninstall function
*
* @return Success or failure
*/
public function uninstall()
{
// Uninstall parent and unregister Configuration
if (!parent::uninstall())
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 Check that everything is alright for Cloudcache usage.
*
* @return Array empty on success, filled with error messages on failure.
*/
private function _compatibilityCheck()
{
// Compatibility check
$messages = array();
if (Configuration::get('PS_CSS_THEME_CACHE') ||
Configuration::get('PS_JS_THEME_CACHE') ||
Configuration::get('PS_HTML_THEME_COMPRESSION') ||
Configuration::get('PS_JS_HTML_THEME_COMPRESSION') ||
Configuration::get('PS_HIGH_HTML_THEME_COMPRESSION'))
$messages[] = $this->l('In order to succesfully use Cloudcache, please fix the following:');
if (Configuration::get('PS_CSS_THEME_CACHE'))
$messages[] = $this->l('Make sure you check "Keep CSS as original"');
if (Configuration::get('PS_JS_THEME_CACHE'))
$messages[] = $this->l('Make sure you check "Keep JavaScript as original"');
if (Configuration::get('PS_HTML_THEME_COMPRESSION'))
$messages[] = $this->l('Make sure you check "Keep HTML as original"');
if (Configuration::get('PS_JS_HTML_THEME_COMPRESSION'))
$messages[] = $this->l('Make sure you check "Keep inline JavaScript in HTML as original"');
if (Configuration::get('PS_HIGH_HTML_THEME_COMPRESSION'))
$messages[] = $this->l('Make sure you check "Keep W3C validation"');
if (!extension_loaded('curl'))
$messages[] = $this->l('You should ask your hosting provider to enable CURL extension in PHP (php.ini) for Cloudcache module to work.');
// If there is any compatibility issue, just deactivate everything
if (count($messages))
Configuration::updateValue('CLOUDCACHE_API_ACTIVE', 0);
return $messages;
}
/**
* @brief hookBackOfficeTop Implementation.
*
* Hook that allow to add script anywhere in the backoffice.
*
* @return Render to display
*/
public function hookBackOfficeTop()
{
$this->context->smarty->assign('isModuleActive', $this->active);
$this->context->smarty->assign('adminToken', Tools::getAdminTokenLite('AdminModules'));
$messages = $this->_compatibilityCheck();
if (count($messages))
$this->context->smarty->assign('compatibilityIssues', $messages);
return $this->display(__FILE__, 'views/backOfficeTop.tpl');
}
/**
* @brief Empty all tables of the module.
*/
private function _clearTables()
{
Db::getInstance()->execute('DELETE FROM `'._DB_PREFIX_.'cloudcache_zone` WHERE `id_shop` = '.(int)$this->context->shop->id);
}
private function _getCouponUrl()
{
$curLang = $this->context->cookie->id_lang;
$prestaBaseUrl = __PS_BASE_URI__.'modules/cloudcache/coupon.php?lang='.$curLang.'&source='.urlencode($_SERVER['HTTP_HOST']);
if (Configuration::get('CLOUDCACHE_API_ACTIVE'))
return $prestaBaseUrl.'&userId='.((int)Configuration::get('CLOUDCACHE_API_USER')).
'&companyId='.urlencode(Configuration::get('CLOUDCACHE_API_COMPANY_ID'));
return $prestaBaseUrl;
}
/**
* @brief Main Form Method
*
* @return Rendered form
*/
public function getContent()
{
if (Tools::isSubmit('SubmitCloudcacheSettings'))
{
// If we change the credentials, we deactivate the module
Configuration::updateValue('CLOUDCACHE_API_ACTIVE', 0);
// And clear the local cache for the zones
$this->_clearTables();
Configuration::updateValue('CLOUDCACHE_API_USER',
trim(Tools::getValue('cloudcache_api_user')));
Configuration::updateValue('CLOUDCACHE_API_COMPANY_ID',
trim(Tools::getValue('cloudcache_api_company_id')));
Configuration::updateValue('CLOUDCACHE_API_KEY',
$this->_cipherTool->encrypt(trim(Tools::getValue('cloudcache_api_key'))));
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation());
}
elseif (Tools::isSubmit('SubmitCloudcacheTestConnection'))
$connectionTestResult = $this->_testConnection();
elseif (Tools::isSubmit('SubmitCloudcacheAdd_zone'))
{
// Check http[s]
if (substr(Tools::getValue('origin'), 0, 7) != 'http://' &&
substr(Tools::getValue('origin'), 0, 8) != 'https://')
$origin = 'http://'.Tools::getValue('origin');
else
$origin = Tools::getValue('origin');
if (substr(Tools::getValue('vanity_domain'), 0, 7) == 'http://' ||
substr(Tools::getValue('vanity_domain'), 0, 8) == 'https://')
$vanity = substr(Tools::getValue('vanity_domain'), strpos(':') + 3);
else
$vanity = Tools::getValue('vanity_domain');
$zone_info = array(
'name' => Tools::getValue('name'),
'origin' => $origin,
'vanity_domain' => $vanity,
'label' => Tools::getValue('label'),
'compress' => Tools::getValue('compress'),
);
$action = $this->createZone(Tools::getValue('type'), $zone_info);
if (is_array($action))
{
Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'cloudcache_zone` SET
`name` = \''.pSQL($_POST['name']).'\',
`origin` = \''.pSQL($_POST['origin']).'\',
`compress` = \''.(isset($_POST['compress']) ? 1 : 0).'\',
`label` = \''.pSQL($_POST['label']).'\',
`file_type` = \''.pSQL(CLOUDCACHE_FILE_TYPE_ALL).'\',
`cdn_url` = \''.($_POST['vanity_domain'] ? pSQL($_POST['vanity_domain']) : pSQL($_POST['name'].'.'.Configuration::get('CLOUDCACHE_API_COMPANY_ID').'.'.CLOUDCACHE_API_ZONE_URL)).'\'
WHERE `id_zone` = '.(int)$action['id']);
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Zone added.')));
}
else
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Error adding the zone: ').' '.pSQL($action), 'error'));
}
elseif (Tools::isSubmit('SubmitCloudcacheSync'))
{
$action = $this->_syncZonesWithServer('all');
if (is_array($action))
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('All zones were synced.')));
else
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Error syncing zones.'), 'error'));
}
elseif (Tools::isSubmit('SubmitCloudcacheClearAllCache'))
{
$error = false;
foreach (Db::getInstance()->ExecuteS('SELECT `id_zone`, `zone_type`, `name` FROM `'._DB_PREFIX_.'cloudcache_zone` WHERE `id_shop` = '.(int)$this->context->shop->id) as $zone)
if (!$this->_api->cachePurgeAll('cache', $zone['id_zone']))
{
$error = true;
break;
}
if (!$error)
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('The cache was purged for all zones.')));
else
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Error purging cache for all zones.'), 'error'));
}
elseif (Tools::isSubmit('SubmitCloudcacheClearZoneCache'))
{
$zoneName = Db::getInstance()->getValue('SELECT `name` FROM '._DB_PREFIX_.'cloudcache_zone
WHERE `id_zone` = '.(int)Tools::getValue('id_zone').' AND `id_shop` = '.(int)$this->context->shop->id);
if ($this->_api->cachePurgeAll('cache', Tools::getValue('id_zone')))
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('The cache was purged for zone:').' '.Tools::safeOutput($zoneName)));
else
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Error purging cache for zone:').' '.Tools::safeOutput($zoneName), 'error'));
}
elseif (Tools::isSubmit('SubmitCloudcacheEditZoneAction')) // display the form to edit the zone
{
// Get info for current zone
$zone_info = Db::getInstance()->getRow('SELECT `id_zone`, `name`, `origin`, `compress`, `label`,
`cdn_url`, `bw_yesterday`, `bw_last_week`, `bw_last_month`,
`file_type`, `zone_type`
FROM `'._DB_PREFIX_.'cloudcache_zone`
WHERE `id_zone` = '.(int)Tools::getValue('id_zone').' AND `id_shop` = '.(int)$this->context->shop->id);
// Clean $zone_info before sending to smarty
$zone_info_clean = array();
foreach ($zone_info as $key => $z)
$zone_info_clean[$key] = Tools::safeOutput($z);
$this->context->smarty->assign('edit_zone_info', $zone_info_clean);
}
elseif (Tools::isSubmit('SubmitCloudcacheEdit_zone')) // save the changes on the edited zone
{
Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'cloudcache_zone` SET
`name` = \''.pSQL($_POST['name']).'\',
`origin` = \''.pSQL($_POST['origin']).'\',
`compress` = \''.(isset($_POST['compress']) ? 1 : 0).'\',
`label` = \''.pSQL($_POST['label']).'\',
`cdn_url` = \''.pSQL($_POST['vanity_domain']).'\',
`file_type` = \''.pSQL($_POST['file_type']).'\'
WHERE `id_zone` = '.(int)Tools::getValue('id_zone'));
$zone_info = array('id_zone' => (int)Tools::getValue('id_zone'),
'name' => Tools::getValue('name'),
'origin' => Tools::getValue('origin'),
'vanity_domain' => Tools::getValue('vanity_domain'),
'label' => Tools::getValue('label'),
'compress' => (bool)Tools::getValue('compress'),
'file_type' => Tools::getValue('file_type'));
if (!$this->updateZone(Tools::getValue('type'), $zone_info)) // 0 : good | 1 : bad
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('The following zone was updated:').' '.Tools::safeOutput(Tools::getValue('name'))));
else
$this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Error updating zone:').' '.Tools::safeOutput(Tools::getValue('name')), 'error'));
}
$confValues = Configuration::getMultiple(array(
'CLOUDCACHE_API_USER',
'CLOUDCACHE_API_KEY',
'CLOUDCACHE_API_COMPANY_ID'));
// Set the smarty env
$this->context->smarty->assign('serverRequestUri',
Tools::safeOutput($_SERVER['REQUEST_URI']));
$this->context->smarty->assign('displayName',
Tools::safeOutput($this->displayName));
if (isset($connectionTestResult))
$this->context->smarty->assign('connectionTestResult',
$connectionTestResult);
if (isset($confValues['CLOUDCACHE_API_COMPANY_ID']))
$this->context->smarty->assign('companyId',
$confValues['CLOUDCACHE_API_COMPANY_ID']);
if (isset($confValues['CLOUDCACHE_API_USER']))
$this->context->smarty->assign('apiUser',
$confValues['CLOUDCACHE_API_USER']);
$this->context->smarty->assign('apiKey',
$this->_cipherTool->decrypt($confValues['CLOUDCACHE_API_KEY']));
$messages = $this->_compatibilityCheck();
if (count($messages))
$this->context->smarty->assign('compatibilityIssues', $messages);
$this->context->smarty->assign('allAvailableZones', $this->_api->getAvailableNamespaces(true));
$this->context->smarty->assign('prepaidBandwith', $this->getPrepaidBandwidth());
// Get the zones
$zones = array();
if (Configuration::get('CLOUDCACHE_API_USER'))
$zones = $this->getZones('pullzone');
// display the form
$this->context->smarty->assign('apiActive', Configuration::get('CLOUDCACHE_API_ACTIVE'));
$this->context->smarty->assign('zones', $zones);
$this->context->smarty->assign('couponUrl', $this->_getCouponUrl());
$this->context->smarty->assign('defaultOriginServerURL', (Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://').Configuration::get('PS_SHOP_DOMAIN'));
if (isset($_GET['id_tab']))
$this->context->smarty->assign('cloudcache_id_tab', (int)$_GET['id_tab']);
$this->context->smarty->assign('cloudcache_tracking', 'http://www.prestashop.com/modules/'.$this->name.'.png?url_site='.Tools::safeOutput($_SERVER['SERVER_NAME']).'&id_lang='.(int)$this->context->cookie->id_lang);
return $this->display(__FILE__, 'views/content2.tpl');
}
/**
* @brief Test the conenction to Cloudcache 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()
{
set_time_limit(300);
if (count($this->_compatibilityCheck()))
return array('
'.
$this->l('You have compatibility issues, please fix them before using the module.').'',
'#FFD8D8');
$zones = $this->_api->listZones('pullzone');
if ($this->_api->getLastFaultCode())
{
$ret = array('
'.$this->l('Connection Test Failed.').'',
'#FFD8D8', false);
Configuration::updateValue('CLOUDCACHE_API_ACTIVE', 0);
return $ret;
}
$defaultName = $this->l('prestashop');
// Check if default zone exists
for ($i = 0; $i < count($zones); $i++)
if ($zones[$i]['name'] == $defaultName)
{
$defaultName .= rand(1, 999);
$i = 0;
}
$newZone = false;
// If there is no zones, then create the default one
if (!count($zones) || !Configuration::get('CLOUDCACHE_API_COMPANY_ID'))
{
$origin = (Configuration::get('PS_SSL_ENABLED') ? 'https://' : 'http://').Configuration::get('PS_SHOP_DOMAIN');
$r = $this->createZone('pullzone', array(
'name' => $defaultName,
'origin' => $origin,
'compress' => 1,
));
if (is_array($r))
{
Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'cloudcache_zone` SET `name` = \''.pSQL($defaultName).'\', `origin` = \''.pSQL($origin).'\', `compress` = \'1\', `file_type` = \''.pSQL(CLOUDCACHE_FILE_TYPE_ALL).'\', `cdn_url` = \''.pSQL($r['cdn_url']).'\' WHERE `id_zone` = '.(int)$r['id']);
$tmp = substr($r['cdn_url'], strlen($defaultName) + 1);
$companyId = substr($tmp, 0, strlen('netdna-cdn.com') * -1 - 1);
Configuration::updateValue('CLOUDCACHE_API_COMPANY_ID', $companyId);
}
else // If failure, the zonename has probably been taken
{
$defaultName .= rand(1, 999);
$r = $this->createZone('pullzone', array(
'name' => $defaultName,
'origin' => $origin,
'compress' => 1,
));
if (is_array($r))
{
Db::getInstance()->Execute('UPDATE `'._DB_PREFIX_.'cloudcache_zone` SET `name` = \''.pSQL($defaultName).'\', `origin` = \''.pSQL($origin).'\', `compress` = \'1\', `file_type` = \''.pSQL(CLOUDCACHE_FILE_TYPE_ALL).'\', `cdn_url` = \''.pSQL($r['cdn_url']).'\' WHERE `id_zone` = '.(int)$r['id']);
$tmp = substr($r['cdn_url'], strlen($defaultName) + 1);
$companyId = substr($tmp, 0, strlen('netdna-cdn.com') * -1 - 1);
Configuration::updateValue('CLOUDCACHE_API_COMPANY_ID', $companyId);
}
else
return array('
'.$this->l('An error occured, impossible to create a default zone.').'', '#FFD8D8', true);
}
$newZone = $tmp;
}
Configuration::updateValue('CLOUDCACHE_API_ACTIVE', 1);
$ret = array('
'.$this->l('Register').' '.
Configuration::get('PS_SHOP_DOMAIN').' '.
$this->l('on Cloudcache').'
', '#D6F5D6', true);
if ($newZone)
$ret['newZone'] = $origin;
return $ret;
}
/*
** 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' => Tools::safeOutput($img),
'text' => (empty($text) ? $this->l('Settings updated') : $text)
);
}
/******************************************************************/
/** Tools methods *************************************************/
/******************************************************************/
function getCurrentURL($htmlEntities = false)
{
$url = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
return (!empty($_SERVER['HTTPS']) ? 'https' : 'http').
'://'.($htmlEntities ? preg_replace('/&/', '&', $url): $url);
}
/**
* @brief Retrieve the bandwith from the selected zone and date range.
*
* @param zoneId Zone Id from which we want to retrieve data
* @param range Range to retrieve (daily, weekly, monthly)
*
* @return Bandwith spent by the selecte zone between the wanted date range.
*/
private function _getZoneTransfer($zoneId, $range)
{
// Associate a range with real date
$allowedRange = array(
'daily' => date('Y-m-d',
mktime(0, 0, 0, date('n'), date('j') - 1, date('Y'))),
'weekly' => date('Y-m-d',
mktime(0, 0, 0, date('n'), date('j') - 7, date('Y'))),
'monthly' => date('Y-m-d',
mktime(0, 0, 0, date('n') - 1, date('j'), date('Y'))),
);
// Retrieve today's date
$today = date('Y-m-d');
// We check the range is correct
if (!array_key_exists($range, $allowedRange))
return -1;
$companyId = Configuration::get('CLOUDCACHE_API_COMPANY_ID');
// Retrieve the data from the server
$r = $this->_api->getTotalTransferStats('report', $companyId, $zoneId,
$allowedRange[$range], $today);
// Check if the transaction went well
if ($this->_api->getLastFaultCode())
return -1;
return 0;
}
/**
* @brief Retrieves Zones from Cloudcache Server and sync with local data
*
* @param type Namespace of the zones to retrieve (pullzone, pushzone, etc)
*
* @return Array describing the zones.
*/
private function _syncZonesWithServer($type)
{
// Send the request to the API server
$cdnZones = array();
if ($type == 'all')
foreach ($this->_api->getAvailableNamespaces() as $namespace)
$cdnZones[$namespace] = $this->_api->listZones($namespace);
else
$cdnZones[$type] = $this->_api->listZones($type);
$zones = array();
// Check if the transaction went well
if (!$this->_api->getLastFaultCode())
{
// Build our custom array from the retieved data
foreach ($cdnZones as $namespace => $cdnZone)
{
foreach ($cdnZone as $zone)
{
$exists = false;
$row = Db::getInstance()->getRow('SELECT `id_zone`, `id_shop`, `origin`, `cdn_url`, `file_type` FROM `'._DB_PREFIX_.'cloudcache_zone` WHERE `id_zone` = '.(int)$zone['id']);
if ($row['id_zone'])
$exists = true;
if ($exists && $row['id_shop'] != $this->context->shop->id)
continue ;
$zones[(int)$zone['id']] = array(
'id_zone' => (int)$zone['id'],
'name' => pSQL($zone['name']),
'origin' => pSQL($exists ? $row['origin'] : $this->l('no data')),
'cdn_url' => pSQL($exists ? $row['cdn_url'] : $this->l('no data')),
'bw_yesterday' => (int)$this->_getZoneTransfer($zone['id'], 'daily'),
'bw_last_week' => (int)$this->_getZoneTransfer($zone['id'], 'weekly'),
'bw_last_month' => (int)$this->_getZoneTransfer($zone['id'], 'monthly'),
'file_type' => pSQL($exists ? $row['file_type'] : 'none'),
'zone_type' => pSQL($namespace),
'id_shop' => (int)$this->context->shop->id,
'id_group_shop' => (int)$this->context->shop->id_group_shop,
);
}
}
// For each zone, update or insert the new data in the database
foreach ($zones as $id_zone => $zone_data)
if ($zone_data['zone_type'] != 'all')
Db::getInstance()->Execute('REPLACE INTO `'._DB_PREFIX_.'cloudcache_zone`
(`'.implode('`,`', array_keys($zone_data)).'`)
VALUES (\''.implode('\', \'', $zone_data).'\')');
return $zones;
}
return false;
}
/**
* @brief Get Zones from the selected zone type.
*
* If the sync flag is setted to true, then retrieve data from Cloudcache servers.
*
* @note Function call thru ajax
*
* @param type Type of zone (Cloudcache namespace)
* @param sync Flag to know if we should ask the Cloudcache servers.
*
* @return Array describing the zones
*/
public function getZones($type, $sync = false)
{
// Check that the $type is correct an harmless for the database
if (!in_array($type, $this->_api->getAvailableNamespaces()))
return $this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Invalid zone type.'), 'error'));
// Check on the database if $sync is false (cache)
$zones = array();
if (!$sync)
{
$d = Db::getInstance()->ExecuteS('
SELECT `id_zone`, `id_shop`, `name`, `origin`, `compress`, `label`, `cdn_url`,
`bw_yesterday`, `bw_last_week`, `bw_last_month`, `file_type`, `zone_type`
FROM `'._DB_PREFIX_.'cloudcache_zone`
WHERE `zone_type` = \''.pSQL($type).'\' AND `id_shop` = '.(int)$this->context->shop->id);
foreach ($d as $line)
$zones[$line['id_zone']] = $line;
}
// if no result or if $sync, load data from API server
if (($sync || !count($zones)) && Configuration::get('CLOUDCACHE_API_ACTIVE'))
$zones = $this->_syncZonesWithServer($type);
// Return the data array
return $zones;
}
/**
* @brief Create a Zone on the Cloudcache Server.
*
* First create the zone thru the API then call the sync function in order to
* update the local data.
*
* @param type Type of the zone (pullzone, pushzone, etc)
* @param values Array describing the zone.
*
* @return True if everything went well, False otherwise
*/
public function createZone($type, $values)
{
// Check that the $type is correct an harmless for the database
if (!in_array($type, $this->_api->getAvailableNamespaces()))
return $this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Invalid zone type.'), 'error'));
// Create the basic zone data
$zone = array(
'name' => pSQL($values['name']),
'origin' => pSQL($values['origin']),
);
// If an optional field is set, add it to the zone
$optionalFields = array('vanity_domain', 'vhost',
'ip', 'compress', 'label');
foreach ($optionalFields as $field)
if (isset($values[$field]) && !empty($values[$field]))
$zone[$field] = pSQL($values[$field]);
// Then send the request to the server
// The server return an array with the new id, vanity_ip and cdn_url
$r = $this->_api->createZone($type, $zone);
// Check if the transaction went well and return result
if ($this->_api->getLastFaultCode())
return $this->_api->getLastFaultString();
/* // Insert the new zone in database */
/* if ($this->_updateZoneSql($r, 'CRE)) */
/* return $this->context->smarty->assign('confirmMessage', */
/* $this->_displayConfirmation($this->l('Unknown internal error.'), 'error')); */
// Sync
$this->_syncZonesWithServer($type);
return $r;
}
/**
* @brief Update the selected zone.
*
* @param type Type of the zone (namespace)
* @param values Values of the updated zone
*
* @return True if OK, false otherwise.
*/
public function updateZone($type, $values)
{
// Check that the $type is correct an harmless for the database
if (!in_array($type, $this->_api->getAvailableNamespaces()))
return $this->context->smarty->assign('confirmMessage',
$this->_displayConfirmation($this->l('Invalid zone type.'), 'error'));
// Create the basic zone data
$zone = array(
'id' => (int)$values['id_zone'],
);
$optionalFields = array('name', 'origin', 'vhost', 'ip', 'compress', 'label');
foreach ($optionalFields as $field)
if (isset($values[$field]) && !empty($values[$field]))
$zone[$field] = pSQL($values[$field]);
// The updateZone return a bool success/error
$r = $this->_api->updateZone($type, (int)$values['id_zone'], $zone);
// Check if the transaction went well
if ($this->_api->getLastFaultCode())
return ; //die('KO '.pSQL($this->_api->getLastFaultString())); // pSQL for XSS
return $r;
}
/**
* @brief Retrieve the paid Bandwith left
*
* @return The bandwith left.
*/
public function getPrepaidBandwidth()
{
// The namespace need to retrieve the bandwith is 'account'
// The server reply the amount of bandwith left
$r = $this->_api->getBandwidth('account');
// Check if the transaction went well
if ($this->_api->getLastFaultCode())
return $this->l('N/A');
// $r /= (1024 * 1024 * 1024 * 1024);
$r /= (1000 * 1000 * 1000 * 1000);
return round($r, 2);
}
}