- {$fields_value.image}
-
{l s='File size'} {$fields_value.size}kb
+ {$fields_value[$input.name].image}
+
{l s='File size'} {$fields_value[$input.name].size}kb
{l s='Delete'}
diff --git a/classes/CMS.php b/classes/CMS.php
index 176d3d61b..db9d69d52 100644
--- a/classes/CMS.php
+++ b/classes/CMS.php
@@ -53,7 +53,7 @@ class CMSCore extends ObjectModel
'meta_keywords' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 128),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
- 'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString', 'size' => 3999999999999),
+ 'content' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 3999999999999),
),
);
diff --git a/classes/CartRule.php b/classes/CartRule.php
index ab5cef179..001e8cd22 100644
--- a/classes/CartRule.php
+++ b/classes/CartRule.php
@@ -1104,29 +1104,30 @@ class CartRuleCore extends ObjectModel
'.($context->customer->id ? 'OR cr.id_customer = '.(int)$context->cart->id_customer : '').'
)
AND (
- cr.carrier_restriction = 0
+ cr.`carrier_restriction` = 0
'.($context->cart->id_carrier ? 'OR c.id_carrier = '.(int)$context->cart->id_carrier : '').'
)
AND (
- cr.shop_restriction = 0
+ cr.`shop_restriction` = 0
'.((Shop::isFeatureActive() && $context->shop->id) ? 'OR crs.id_shop = '.(int)$context->shop->id : '').'
)
AND (
- cr.group_restriction = 0
+ cr.`group_restriction` = 0
'.($context->customer->id ? 'OR 0 < (
- SELECT cg.id_group
- FROM '._DB_PREFIX_.'customer_group cg
- LEFT JOIN '._DB_PREFIX_.'cart_rule_group crg ON (cg.id_group = crg.id_group AND cg.id_group = '.(int)$context->customer->id_default_group.')
- WHERE cr.id_cart_rule = crg.id_cart_rule
- AND cg.id_customer = '.(int)$context->customer->id.' LIMIT 1
+ SELECT cg.`id_group`
+ FROM `'._DB_PREFIX_.'customer_group` cg
+ INNER JOIN `'._DB_PREFIX_.'cart_rule_group` crg ON cg.id_group = crg.id_group
+ WHERE cr.`id_cart_rule` = crg.`id_cart_rule`
+ AND cg.`id_customer` = '.(int)$context->customer->id.'
+ LIMIT 1
)' : '').'
)
AND (
- cr.reduction_product <= 0
- OR cr.reduction_product IN (
- SELECT id_product
- FROM '._DB_PREFIX_.'cart_product
- WHERE id_cart = '.(int)$context->cart->id.'
+ cr.`reduction_product` <= 0
+ OR cr.`reduction_product` IN (
+ SELECT `id_product`
+ FROM `'._DB_PREFIX_.'cart_product`
+ WHERE `id_cart` = '.(int)$context->cart->id.'
)
)
AND cr.id_cart_rule NOT IN (SELECT id_cart_rule FROM '._DB_PREFIX_.'cart_cart_rule WHERE id_cart = '.(int)$context->cart->id.')
diff --git a/classes/Category.php b/classes/Category.php
index 55982d2a2..35cbdb0f4 100644
--- a/classes/Category.php
+++ b/classes/Category.php
@@ -109,7 +109,7 @@ class CategoryCore extends ObjectModel
// Lang fields
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 64),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 64),
- 'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'),
+ 'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_keywords' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
diff --git a/classes/Connection.php b/classes/Connection.php
index b250e4ea5..4b171b1f0 100644
--- a/classes/Connection.php
+++ b/classes/Connection.php
@@ -82,8 +82,12 @@ class ConnectionCore extends ObjectModel
// The connection is created if it does not exist yet and we get the current page id
if (!isset($cookie->id_connections) || !strstr(isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', Tools::getHttpHost(false, false)))
$id_page = Connection::setNewConnection($cookie);
+ // If we do not track the pages, no need to get the page id
+ if (!Configuration::get('PS_STATSDATA_PAGESVIEWS') && !Configuration::get('PS_STATSDATA_CUSTOMER_PAGESVIEWS'))
+ return array();
if (!isset($id_page) || !$id_page)
$id_page = Page::getCurrentId();
+ // If we do not track the page views by customer, the id_page is the only information needed
if (!Configuration::get('PS_STATSDATA_CUSTOMER_PAGESVIEWS'))
return array('id_page' => $id_page);
diff --git a/classes/Group.php b/classes/Group.php
index aa7f6cccd..eb8b95e3d 100644
--- a/classes/Group.php
+++ b/classes/Group.php
@@ -70,6 +70,13 @@ class GroupCore extends ObjectModel
protected $webserviceParameters = array();
+ public function __construct($id = null, $id_lang = null, $id_shop = null)
+ {
+ parent::__construct($id, $id_lang, $id_shop);
+ if ($this->id && !isset(Group::$group_price_display_method[$this->id]))
+ self::$group_price_display_method[$this->id] = $this->price_display_method;
+ }
+
public static function getGroups($id_lang, $id_shop = false)
{
$shop_criteria = '';
diff --git a/classes/Hook.php b/classes/Hook.php
index 74d95142c..d9ba5f57e 100644
--- a/classes/Hook.php
+++ b/classes/Hook.php
@@ -64,10 +64,10 @@ class HookCore extends ObjectModel
'primary' => 'id_hook',
'fields' => array(
'name' => array('type' => self::TYPE_STRING, 'validate' => 'isHookName', 'required' => true, 'size' => 64),
- 'title' => array('type' => self::TYPE_STRING),
- 'description' => array('type' => self::TYPE_HTML),
- 'position' => array('type' => self::TYPE_BOOL),
- 'live_edit' => array('type' => self::TYPE_BOOL),
+ 'title' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName'),
+ 'description' => array('type' => self::TYPE_HTML, 'validate' => 'isCleanHtml'),
+ 'position' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
+ 'live_edit' => array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
),
);
@@ -83,7 +83,7 @@ class HookCore extends ObjectModel
public function add($autodate = true, $null_values = false)
{
- Cache::clean('hook_idbyname_'.$this->name);
+ Cache::clean('hook_idsbyname');
return parent::add($autodate, $null_values);
}
@@ -113,19 +113,26 @@ class HookCore extends ObjectModel
if (!Validate::isHookName($hook_name))
return false;
- $cache_id = 'hook_idbyname_'.$hook_name;
+ $cache_id = 'hook_idsbyname';
if (!Cache::isStored($cache_id))
{
- $retro_hook_name = Hook::getRetroHookName($hook_name);
- Cache::store($cache_id, Db::getInstance()->getValue('
- SELECT `id_hook`
- FROM `'._DB_PREFIX_.'hook`
- WHERE `name` = \''.pSQL($hook_name).'\'
- OR `name` = \''.pSQL($retro_hook_name).'\'
- '));
+ // Get all hook ID by name and alias
+ $hook_ids = array();
+ $result = Db::getInstance()->ExecuteS('
+ SELECT `id_hook`, `name`
+ FROM `'._DB_PREFIX_.'hook`
+ UNION
+ SELECT `id_hook`, ha.`alias` as name
+ FROM `ps_hook_alias` ha
+ INNER JOIN `ps_hook` h ON ha.name = h.name');
+ foreach ($result as $row)
+ $hook_ids[$row['name']] = $row['id_hook'];
+ Cache::store($cache_id, $hook_ids);
}
+ else
+ $hook_ids = Cache::retrieve($cache_id);
- return Cache::retrieve($cache_id);
+ return (isset($hook_ids[$hook_name]) ? $hook_ids[$hook_name] : false);
}
/**
diff --git a/classes/Language.php b/classes/Language.php
index 5b4659f70..0228a63ac 100644
--- a/classes/Language.php
+++ b/classes/Language.php
@@ -262,7 +262,7 @@ class LanguageCore extends ObjectModel
$mPath_to = _PS_MAIL_DIR_.(string)$iso_to.'/';
}
- $lFiles = array('admin.php', 'errors.php', 'fields.php', 'pdf.php', 'tabs.php', 'index.php');
+ $lFiles = array('admin.php', 'errors.php', 'fields.php', 'pdf.php', 'tabs.php');
// Added natives mails files
$mFiles = array(
@@ -297,7 +297,7 @@ class LanguageCore extends ObjectModel
'test.html', 'test.txt',
'voucher.html', 'voucher.txt',
'voucher_new.html', 'voucher_new.txt',
- 'order_changed.html', 'order_changed.txt', 'index.php'
+ 'order_changed.html', 'order_changed.txt'
);
$number = -1;
diff --git a/classes/Manufacturer.php b/classes/Manufacturer.php
index 285f802e1..8cc573bad 100644
--- a/classes/Manufacturer.php
+++ b/classes/Manufacturer.php
@@ -78,8 +78,8 @@ class ManufacturerCore extends ObjectModel
'date_upd' => array('type' => self::TYPE_DATE),
// Lang fields
- 'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'),
- 'short_description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString', 'size' => 254),
+ 'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
+ 'short_description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml', 'size' => 254),
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
'meta_description' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'meta_keywords' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName'),
@@ -198,6 +198,7 @@ class ManufacturerCore extends ObjectModel
LEFT JOIN `'._DB_PREFIX_.'manufacturer` as m ON (m.`id_manufacturer`= p.`id_manufacturer`)
WHERE m.`id_manufacturer` = '.(int)$manufacturer['id_manufacturer'].
($active ? ' AND product_shop.`active` = 1 ' : '').
+ ' AND product_shop.`visibility` NOT IN ("none")'.
($all_group ? '' : ' AND p.`id_product` IN (
SELECT cp.`id_product`
FROM `'._DB_PREFIX_.'category_group` cg
diff --git a/classes/ObjectModel.php b/classes/ObjectModel.php
index 27e1560db..d1cd8f5ad 100644
--- a/classes/ObjectModel.php
+++ b/classes/ObjectModel.php
@@ -242,16 +242,6 @@ abstract class ObjectModelCore
$this->{$key} = $value;
}
}
-
- if (!is_array(self::$fieldsRequiredDatabase))
- {
- $fields = $this->getfieldsRequiredDatabase(true);
- if ($fields)
- foreach ($fields as $row)
- self::$fieldsRequiredDatabase[$row['object_name']][(int)$row['id_required_field']] = pSQL($row['field_name']);
- else
- self::$fieldsRequiredDatabase = array();
- }
}
/**
@@ -901,6 +891,7 @@ abstract class ObjectModelCore
*/
public function validateField($field, $value, $id_lang = null)
{
+ $this->cacheFieldsRequiredDatabase();
$data = $this->def['fields'][$field];
// Check if field is required
@@ -939,8 +930,22 @@ abstract class ObjectModelCore
if (!method_exists('Validate', $data['validate']))
throw new PrestaShopException('Validation function not found. '.$data['validate']);
- if (!empty($value) && !call_user_func(array('Validate', $data['validate']), $value))
- return 'Property '.get_class($this).'->'.$field.' is not valid';
+ if (!empty($value))
+ {
+ $res = true;
+ if (Tools::strtolower($data['validate']) == 'iscleanhtml')
+ {
+ if (!call_user_func(array('Validate', $data['validate']), $value, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')))
+ $res = false;
+ }
+ else
+ {
+ if (!call_user_func(array('Validate', $data['validate']), $value))
+ $res = false;
+ }
+ if (!$res)
+ return 'Property '.get_class($this).'->'.$field.' is not valid';
+ }
}
return true;
@@ -969,6 +974,7 @@ abstract class ObjectModelCore
public function validateController($htmlentities = true)
{
+ $this->cacheFieldsRequiredDatabase();
$errors = array();
$required_fields_database = (isset(self::$fieldsRequiredDatabase[get_class($this)])) ? self::$fieldsRequiredDatabase[get_class($this)] : array();
foreach ($this->def['fields'] as $field => $data)
@@ -1015,6 +1021,7 @@ abstract class ObjectModelCore
public function getWebserviceParameters($ws_params_attribute_name = null)
{
+ $this->cacheFieldsRequiredDatabase();
$default_resource_parameters = array(
'objectSqlId' => $this->def['primary'],
'retrieveData' => array(
@@ -1125,6 +1132,7 @@ abstract class ObjectModelCore
public function validateFieldsRequiredDatabase($htmlentities = true)
{
+ $this->cacheFieldsRequiredDatabase();
$errors = array();
$required_fields = (isset(self::$fieldsRequiredDatabase[get_class($this)])) ? self::$fieldsRequiredDatabase[get_class($this)] : array();
@@ -1152,6 +1160,19 @@ abstract class ObjectModelCore
FROM '._DB_PREFIX_.'required_field
'.(!$all ? 'WHERE object_name = \''.pSQL(get_class($this)).'\'' : ''));
}
+
+ public function cacheFieldsRequiredDatabase()
+ {
+ if (!is_array(self::$fieldsRequiredDatabase))
+ {
+ $fields = $this->getfieldsRequiredDatabase(true);
+ if ($fields)
+ foreach ($fields as $row)
+ self::$fieldsRequiredDatabase[$row['object_name']][(int)$row['id_required_field']] = pSQL($row['field_name']);
+ else
+ self::$fieldsRequiredDatabase = array();
+ }
+ }
public function addFieldsRequiredDatabase($fields)
{
diff --git a/classes/PaymentModule.php b/classes/PaymentModule.php
index 561881c55..9b4994ee6 100644
--- a/classes/PaymentModule.php
+++ b/classes/PaymentModule.php
@@ -386,7 +386,7 @@ abstract class PaymentModuleCore extends Module
'
| '.$product['reference'].' |
'.$product['name'].(isset($product['attributes']) ? ' - '.$product['attributes'] : '').' |
- '.Tools::displayPrice(Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $this->context->currency, false).' |
+ '.Tools::displayPrice(Product::getTaxCalculationMethod((int)$this->context->customer->id) == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt, $this->context->currency, false).' |
'.((int)$product['cart_quantity'] - $customization_quantity).' |
'.Tools::displayPrice(((int)$product['cart_quantity'] - $customization_quantity) * (Product::getTaxCalculationMethod() == PS_TAX_EXC ? Tools::ps_round($price, 2) : $price_wt), $this->context->currency, false).' |
';
@@ -431,9 +431,9 @@ abstract class PaymentModuleCore extends Module
// Set the new voucher value
if ($voucher->reduction_tax)
- $voucher->reduction_amount = $values['tax_incl'] - $order->total_products_wt - $order->total_shipping_tax_incl;
+ $voucher->reduction_amount = $values['tax_incl'] - $order->total_products_wt - ($voucher->free_shipping == 1 ? $order->total_shipping_tax_incl : 0);
else
- $voucher->reduction_amount = $values['tax_excl'] - $order->total_products - $order->total_shipping_tax_excl;
+ $voucher->reduction_amount = $values['tax_excl'] - $order->total_products - ($voucher->free_shipping == 1 ? $order->total_shipping_tax_excl : 0);
$voucher->id_customer = $order->id_customer;
$voucher->quantity = 1;
diff --git a/classes/Product.php b/classes/Product.php
index 28189ded4..eefa229e1 100644
--- a/classes/Product.php
+++ b/classes/Product.php
@@ -297,8 +297,8 @@ class ProductCore extends ObjectModel
'meta_title' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 128),
'link_rewrite' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isLinkRewrite', 'required' => true, 'size' => 128),
'name' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isCatalogName', 'required' => true, 'size' => 128),
- 'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'),
- 'description_short' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isString'),
+ 'description' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
+ 'description_short' => array('type' => self::TYPE_HTML, 'lang' => true, 'validate' => 'isCleanHtml'),
'available_now' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'size' => 255),
'available_later' => array('type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'IsGenericName', 'size' => 255),
),
@@ -2699,8 +2699,10 @@ class ProductCore extends ObjectModel
// Group reduction
if ($use_group_reduction)
{
- if ($reduction_from_category = (float)GroupReduction::getValueForProduct($id_product, $id_group))
- $price -= $price * $reduction_from_category;
+ $reduction_from_category = GroupReduction::getValueForProduct($id_product, $id_group);
+
+ if (!empty($reduction_from_category) && (float)$reduction_from_category == 0)
+ $price -= $price * (float)$reduction_from_category;
else // apply group reduction if there is no group reduction for this category
$price *= ((100 - Group::getReductionByIdGroup($id_group)) / 100);
}
diff --git a/classes/Search.php b/classes/Search.php
index 3241c3476..1ab992005 100644
--- a/classes/Search.php
+++ b/classes/Search.php
@@ -571,6 +571,14 @@ class SearchCore
return true;
}
+ public static function removeProductsSearchIndex($products)
+ {
+ if (count($products)) {
+ Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'search_index WHERE id_product IN ('.implode(',', $products).')');
+ ObjectModel::updateMultishopTable('Product', array('indexed' => 0), 'a.id_product IN ('.implode(',', $products).')');
+ }
+ }
+
protected static function setProductsAsIndexed(&$products)
{
if (count($products))
diff --git a/classes/Supplier.php b/classes/Supplier.php
index c878257f0..7749fb6de 100644
--- a/classes/Supplier.php
+++ b/classes/Supplier.php
@@ -140,6 +140,7 @@ class SupplierCore extends ObjectModel
WHERE ps.`id_supplier` = '.(int)$supplier['id_supplier'].'
AND ps.id_product_attribute = 0'.
($active ? ' AND product_shop.`active` = 1' : '').
+ ' AND product_shop.`visibility` NOT IN ("none")'.
($all_groups ? '' :'
AND ps.`id_product` IN (
SELECT cp.`id_product`
diff --git a/classes/Tools.php b/classes/Tools.php
index 558f13c52..573ac1d40 100644
--- a/classes/Tools.php
+++ b/classes/Tools.php
@@ -2430,7 +2430,7 @@ exit;
return $pattern;
return preg_replace('/\\\[px]\{[a-z]\}{1,2}|(\/[a-z]*)u([a-z]*)$/i', "$1$2", $pattern);
}
-
+
public static function addonsRequest($request, $params = array())
{
$addons_url = 'api.addons.prestashop.com';
@@ -2516,6 +2516,21 @@ exit;
// No content, return false
return false;
}
+
+ public static function fileAttachment($input = 'fileUpload')
+ {
+ $fileAttachment = null;
+ if (isset($_FILES[$input]['name']) && !empty($_FILES[$input]['name']) && !empty($_FILES[$input]['tmp_name']))
+ {
+ $fileAttachment['rename'] = uniqid(). self::strtolower(substr($_FILES[$input]['name'], -5));
+ $fileAttachment['content'] = file_get_contents($_FILES[$input]['tmp_name']);
+ $fileAttachment['tmp_name'] = $_FILES[$input]['tmp_name'];
+ $fileAttachment['name'] = $_FILES[$input]['name'];
+ $fileAttachment['mime'] = $_FILES[$input]['type'];
+ $fileAttachment['error'] = $_FILES[$input]['error'];
+ }
+ return $fileAttachment;
+ }
}
/**
diff --git a/classes/Validate.php b/classes/Validate.php
index cee80bd01..02fbe77d1 100644
--- a/classes/Validate.php
+++ b/classes/Validate.php
@@ -380,7 +380,7 @@ class ValidateCore
*/
public static function isGenericName($name)
{
- return empty($name) || preg_match('/^[^<>=#{}]*$/u', $name);
+ return empty($name) || preg_match('/^[^<>={}]*$/u', $name);
}
/**
@@ -389,7 +389,7 @@ class ValidateCore
* @param string $html HTML field to validate
* @return boolean Validity is ok or not
*/
- public static function isCleanHtml($html)
+ public static function isCleanHtml($html, $allow_iframe = false)
{
$events = 'onmousedown|onmousemove|onmmouseup|onmouseover|onmouseout|onload|onunload|onfocus|onblur|onchange';
$events .= '|onsubmit|ondblclick|onclick|onkeydown|onkeyup|onkeypress|onmouseenter|onmouseleave|onerror|onselect|onreset|onabort|ondragdrop|onresize|onactivate|onafterprint|onmoveend';
@@ -398,7 +398,14 @@ class ValidateCore
$events .= '|ondragleave|ondragover|ondragstart|ondrop|onerrorupdate|onfilterchange|onfinish|onfocusin|onfocusout|onhashchange|onhelp|oninput|onlosecapture|onmessage|onmouseup|onmovestart';
$events .= '|onoffline|ononline|onpaste|onpropertychange|onreadystatechange|onresizeend|onresizestart|onrowenter|onrowexit|onrowsdelete|onrowsinserted|onscroll|onsearch|onselectionchange';
$events .= '|onselectstart|onstart|onstop';
- return (!preg_match('/<[ \t\n]*script/ims', $html) && !preg_match('/('.$events.')[ \t\n]*=/ims', $html) && !preg_match('/.*script\:/ims', $html) && !preg_match('/<[ \t\n]*i?frame/ims', $html));
+
+ if (preg_match('/<[ \t\n]*script/ims', $html) || preg_match('/('.$events.')[ \t\n]*=/ims', $html) || preg_match('/.*script\:/ims', $html))
+ return false;
+
+ if (!$allow_iframe && preg_match('/<[ \t\n]*(i?frame|form|input|embed|object)/ims', $html))
+ return false;
+
+ return true;
}
/**
diff --git a/classes/controller/AdminController.php b/classes/controller/AdminController.php
index 48366d2c4..967e5a8bf 100644
--- a/classes/controller/AdminController.php
+++ b/classes/controller/AdminController.php
@@ -803,7 +803,7 @@ class AdminControllerCore extends Controller
if (empty($this->redirect_after))
$this->redirect_after = self::$currentIndex.($parent_id ? '&'.$this->identifier.'='.$object->id : '').'&conf=4&token='.$this->token;
}
- Logger::addLog(sprintf($this->l('%s edition'), $this->className), 1, null, $this->className, (int)$this->object->id, true, (int)$this->context->employee->id);
+ Logger::addLog(sprintf($this->l('%s edition'), $this->className), 1, null, $this->className, (int)$object->id, true, (int)$this->context->employee->id);
}
else
$this->errors[] = Tools::displayError('An error occurred while updating an object.').
@@ -3013,4 +3013,4 @@ class AdminControllerCore extends Controller
return $return;
}
-}
\ No newline at end of file
+}
diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php
index 798446e34..52c090097 100755
--- a/classes/controller/FrontController.php
+++ b/classes/controller/FrontController.php
@@ -775,9 +775,11 @@ class FrontControllerCore extends Controller
public function checkLiveEditAccess()
{
- $live_token = Tools::getAdminToken('AdminModulesPositions'.(int)Tab::getIdFromClassName('AdminModulesPositions').(int)Tools::getValue('id_employee'));
- $ad = Tools::getValue('ad');
- return Tools::isSubmit('live_edit') && $ad && Tools::getValue('liveToken') == $live_token && is_dir(_PS_ROOT_DIR_.DIRECTORY_SEPARATOR.$ad);
+ if (!Tools::isSubmit('live_edit') || !Tools::getValue('ad') || !Tools::getValue('liveToken'))
+ return false;
+ if (Tools::getValue('liveToken') != Tools::getAdminToken('AdminModulesPositions'.(int)Tab::getIdFromClassName('AdminModulesPositions').(int)Tools::getValue('id_employee')))
+ return false;
+ return is_dir(_PS_ROOT_DIR_.DIRECTORY_SEPARATOR.Tools::getValue('ad'));
}
public function getLiveEditFooter()
@@ -847,8 +849,8 @@ class FrontControllerCore extends Controller
$range = 2; /* how many pages around page selected */
- if ($this->p < 0)
- $this->p = 0;
+ if ($this->p < 1)
+ $this->p = 1;
if (isset($this->context->cookie->nb_item_per_page) && $this->n != $this->context->cookie->nb_item_per_page && in_array($this->n, $nArray))
$this->context->cookie->nb_item_per_page = $this->n;
diff --git a/classes/db/DbPDO.php b/classes/db/DbPDO.php
index 2e267e0a4..ab5d1ede8 100644
--- a/classes/db/DbPDO.php
+++ b/classes/db/DbPDO.php
@@ -25,8 +25,6 @@
*/
/**
- * This class is currently only here for tests
- *
* @since 1.5.0
*/
class DbPDOCore extends Db
diff --git a/classes/helper/HelperList.php b/classes/helper/HelperList.php
index 6d4c3a023..bfc0077dd 100644
--- a/classes/helper/HelperList.php
+++ b/classes/helper/HelperList.php
@@ -456,7 +456,7 @@ class HelperListCore extends Helper
);
if ($this->specificConfirmDelete !== false)
- $data['confirm'] = !is_null($this->specificConfirmDelete) ? '\r'.$this->specificConfirmDelete : self::$cache_lang['DeleteItem'].$name;
+ $data['confirm'] = !is_null($this->specificConfirmDelete) ? '\r'.$this->specificConfirmDelete : addcslashes(Tools::htmlentitiesDecodeUTF8(self::$cache_lang['DeleteItem'].$name), '\'');
$tpl->assign(array_merge($this->tpl_delete_link_vars, $data));
diff --git a/classes/module/Module.php b/classes/module/Module.php
index 6067612b6..225f492bf 100644
--- a/classes/module/Module.php
+++ b/classes/module/Module.php
@@ -153,18 +153,22 @@ abstract class ModuleCore
// If cache is not generated, we generate it
if (self::$modules_cache == null && !is_array(self::$modules_cache))
{
- // Join clause is done to check if the module is activated in current shop context
- $sql_limit_shop = 'SELECT COUNT(*) FROM `'._DB_PREFIX_.'module_shop` ms WHERE m.`id_module` = ms.`id_module` AND ms.`id_shop` = '.((is_object(Context::getContext()->shop) && $id = (int)Context::getContext()->shop->id) ? $id : 1);
-
- $sql = 'SELECT m.`id_module`, m.`name`, ('.$sql_limit_shop.') as total FROM `'._DB_PREFIX_.'module` m';
-
- // Result is cached
+ $id_shop = (Validate::isLoadedObject($this->context->shop) ? $this->context->shop->id : 1);
self::$modules_cache = array();
- $result = Db::getInstance()->executeS($sql);
+ // Join clause is done to check if the module is activated in current shop context
+ $result = Db::getInstance()->executeS('
+ SELECT m.`id_module`, m.`name`, (
+ SELECT id_module
+ FROM `'._DB_PREFIX_.'module_shop` ms
+ WHERE m.`id_module` = ms.`id_module`
+ AND ms.`id_shop` = '.(int)$id_shop.'
+ LIMIT 1
+ ) as mshop
+ FROM `'._DB_PREFIX_.'module` m');
foreach ($result as $row)
{
self::$modules_cache[$row['name']] = $row;
- self::$modules_cache[$row['name']]['active'] = ($row['total'] > 0) ? 1 : 0;
+ self::$modules_cache[$row['name']]['active'] = ($row['mshop'] > 0) ? 1 : 0;
}
}
@@ -1350,7 +1354,7 @@ abstract class ModuleCore
elseif (isset($context->customer))
{
$groups = $context->customer->getGroups();
- if (empty($groups))
+ if (!count($groups))
$groups = array(Configuration::get('PS_UNIDENTIFIED_GROUP'));
}
@@ -1373,7 +1377,7 @@ abstract class ModuleCore
'.(isset($billing) && $frontend ? 'AND mc.id_country = '.(int)$billing->id_country : '').'
AND (SELECT COUNT(*) FROM '._DB_PREFIX_.'module_shop ms WHERE ms.id_module = m.id_module AND ms.id_shop IN('.implode(', ', $list).')) = '.count($list).'
AND hm.id_shop IN('.implode(', ', $list).')
- '.(count($groups) && $frontend ? 'AND (mg.`id_group` IN('.implode(', ', $groups).'))' : '').$paypal_condition.'
+ '.((count($groups) && $frontend) ? 'AND (mg.`id_group` IN ('.implode(', ', $groups).'))' : '').$paypal_condition.'
GROUP BY hm.id_hook, hm.id_module
ORDER BY hm.`position`, m.`name` DESC');
}
@@ -1511,12 +1515,12 @@ abstract class ModuleCore
* @param int $id_hook Hook ID
* @return array Exceptions
*/
- protected static $exceptionsCache = null;
- public function getExceptions($hookID, $dispatch = false)
+ public function getExceptions($id_hook, $dispatch = false)
{
- if (self::$exceptionsCache === null)
+ $cache_id = 'exceptionsCache';
+ if (!Cache::isStored($cache_id))
{
- self::$exceptionsCache = array();
+ $exceptionsCache = array();
$sql = 'SELECT * FROM `'._DB_PREFIX_.'hook_module_exceptions`
WHERE `id_shop` IN ('.implode(', ', Shop::getContextListShopID()).')';
$result = Db::getInstance()->executeS($sql);
@@ -1525,33 +1529,34 @@ abstract class ModuleCore
if (!$row['file_name'])
continue;
$key = $row['id_hook'].'-'.$row['id_module'];
- if (!isset(self::$exceptionsCache[$key]))
- self::$exceptionsCache[$key] = array();
- if (!isset(self::$exceptionsCache[$key][$row['id_shop']]))
- self::$exceptionsCache[$key][$row['id_shop']] = array();
- self::$exceptionsCache[$key][$row['id_shop']][] = $row['file_name'];
+ if (!isset($exceptionsCache[$key]))
+ $exceptionsCache[$key] = array();
+ if (!isset($exceptionsCache[$key][$row['id_shop']]))
+ $exceptionsCache[$key][$row['id_shop']] = array();
+ $exceptionsCache[$key][$row['id_shop']][] = $row['file_name'];
}
+ Cache::store($cache_id, $exceptionsCache);
}
+ else
+ $exceptionsCache = !Cache::retrieve($cache_id);
- $key = $hookID.'-'.$this->id;
- if (!$dispatch)
+ $key = $id_hook.'-'.$this->id;
+ $array_return = array();
+ if ($dispatch)
{
- $files = array();
foreach (Shop::getContextListShopID() as $shop_id)
- if (isset(self::$exceptionsCache[$key], self::$exceptionsCache[$key][$shop_id]))
- foreach (self::$exceptionsCache[$key][$shop_id] as $file)
- if (!in_array($file, $files))
- $files[] = $file;
- return $files;
+ if (isset($exceptionsCache[$key], $exceptionsCache[$key][$shop_id]))
+ $array_return[$shop_id] = $exceptionsCache[$key][$shop_id];
}
else
{
- $list = array();
foreach (Shop::getContextListShopID() as $shop_id)
- if (isset(self::$exceptionsCache[$key], self::$exceptionsCache[$key][$shop_id]))
- $list[$shop_id] = self::$exceptionsCache[$key][$shop_id];
- return $list;
+ if (isset($exceptionsCache[$key], $exceptionsCache[$key][$shop_id]))
+ foreach ($exceptionsCache[$key][$shop_id] as $file)
+ if (!in_array($file, $array_return))
+ $array_return[] = $file;
}
+ return $array_return;
}
public static function isInstalled($module_name)
diff --git a/classes/order/OrderHistory.php b/classes/order/OrderHistory.php
index d78c5318c..232dab50b 100644
--- a/classes/order/OrderHistory.php
+++ b/classes/order/OrderHistory.php
@@ -142,7 +142,7 @@ class OrderHistoryCore extends ObjectModel
$links .= ' '.Tools::htmlentitiesUTF8(sprintf(Tools::displayError('downloadable %d time(s)'), (int)$product['downloadable']));
$links .= '';
}
- $links .= '
';
$data = array(
'{lastname}' => $customer->lastname,
'{firstname}' => $customer->firstname,
diff --git a/classes/shop/ShopUrl.php b/classes/shop/ShopUrl.php
index c8e4b6074..e1594c86b 100644
--- a/classes/shop/ShopUrl.php
+++ b/classes/shop/ShopUrl.php
@@ -143,22 +143,21 @@ class ShopUrlCore extends ObjectModel
return Db::getInstance()->getValue($sql);
}
- public static function getMainShopDomain($id_shop = null)
- {
- if (!self::$main_domain || $id_shop !== null)
- self::$main_domain = Db::getInstance()->getValue('SELECT domain
- FROM '._DB_PREFIX_.'shop_url
- WHERE main=1 AND id_shop = '.($id_shop !== null ? (int)$id_shop : Context::getContext()->shop->id));
- return self::$main_domain;
- }
-
public static function cacheMainDomainForShop($id_shop)
{
if (!Validate::isUnsignedId($id_shop))
return false;
- ShopUrl::getMainShopDomain($id_shop);
- ShopUrl::getMainShopDomainSSL($id_shop);
+ if (!self::$main_domain_ssl || !self::$main_domain || $id_shop !== null)
+ {
+ $row = Db::getInstance()->getRow('
+ SELECT domain, domain_ssl
+ FROM '._DB_PREFIX_.'shop_url
+ WHERE main = 1
+ AND id_shop = '.($id_shop !== null ? (int)$id_shop : Context::getContext()->shop->id));
+ self::$main_domain = $row['domain'];
+ self::$main_domain_ssl = $row['domain_ssl'];
+ }
}
public static function resetMainDomainCache()
@@ -167,17 +166,15 @@ class ShopUrlCore extends ObjectModel
self::$main_domain_ssl = null;
}
+ public static function getMainShopDomain($id_shop = null)
+ {
+ ShopUrl::cacheMainDomainForShop($id_shop);
+ return self::$main_domain;
+ }
public static function getMainShopDomainSSL($id_shop = null)
{
- if (!self::$main_domain_ssl || $id_shop !== null)
- {
- $sql = 'SELECT domain_ssl
- FROM '._DB_PREFIX_.'shop_url
- WHERE main = 1
- AND id_shop = '.($id_shop !== null ? (int)$id_shop : Context::getContext()->shop->id);
- self::$main_domain_ssl = Db::getInstance()->getValue($sql);
- }
+ ShopUrl::cacheMainDomainForShop($id_shop);
return self::$main_domain_ssl;
}
}
\ No newline at end of file
diff --git a/classes/tax/TaxRulesGroup.php b/classes/tax/TaxRulesGroup.php
index 1ef0dac0f..ea597bab7 100644
--- a/classes/tax/TaxRulesGroup.php
+++ b/classes/tax/TaxRulesGroup.php
@@ -53,13 +53,22 @@ class TaxRulesGroupCore extends ObjectModel
protected static $_taxes = array();
- public static function getTaxRulesGroups($only_active = true)
+ public static function getTaxRulesGroups($only_active = true, $multiShop = false)
{
- return Db::getInstance()->executeS('
- SELECT *
- FROM `'._DB_PREFIX_.'tax_rules_group` g'
- .($only_active ? ' WHERE g.`active` = 1' : '').'
- ORDER BY name ASC');
+ if ((bool)$multiShop) {
+ return Db::getInstance()->executeS('
+ SELECT *
+ FROM `'._DB_PREFIX_.'tax_rules_group` g'
+ .Shop::addSqlAssociation('tax_rules_group', 'g')
+ .($only_active ? ' WHERE g.`active` = 1' : '').'
+ ORDER BY name ASC');
+ } else {
+ return Db::getInstance()->executeS('
+ SELECT *
+ FROM `'._DB_PREFIX_.'tax_rules_group` g'
+ .($only_active ? ' WHERE g.`active` = 1' : '').'
+ ORDER BY name ASC');
+ }
}
/**
diff --git a/config/config.inc.php b/config/config.inc.php
index 637089c22..21fb9b780 100644
--- a/config/config.inc.php
+++ b/config/config.inc.php
@@ -90,7 +90,21 @@ if (!isset($_SERVER['HTTP_HOST']) || empty($_SERVER['HTTP_HOST']))
$context = Context::getContext();
/* Initialize the current Shop */
-$context->shop = Shop::initialize();
+try
+{
+ $context->shop = Shop::initialize();
+}
+catch(Exception $e)
+{
+ header('HTTP/1.1 503 temporarily overloaded');
+
+ define('_PS_SMARTY_DIR_', _PS_TOOL_DIR_.'smarty/');
+ require_once(_PS_SMARTY_DIR_.'Smarty.class.php');
+ $context->smarty = new Smarty();
+ $context->smarty->display('error500.html');
+
+ exit;
+}
define('_THEME_NAME_', $context->shop->getTheme());
define('__PS_BASE_URI__', $context->shop->getBaseURI());
diff --git a/controllers/admin/AdminCategoriesController.php b/controllers/admin/AdminCategoriesController.php
index 4d48eb608..46e80f515 100644
--- a/controllers/admin/AdminCategoriesController.php
+++ b/controllers/admin/AdminCategoriesController.php
@@ -231,7 +231,7 @@ class AdminCategoriesControllerCore extends AdminController
{
if (empty($this->display))
{
- if (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE'))
+ if (Configuration::get('PS_MULTISHOP_FEATURE_ACTIVE') && count(Shop::getShops()) > 1)
$this->toolbar_btn['new-url'] = array(
'href' => self::$currentIndex.'&add'.$this->table.'root&token='.$this->token,
'desc' => $this->l('Add new root category')
diff --git a/controllers/admin/AdminCountriesController.php b/controllers/admin/AdminCountriesController.php
index 6d5638b31..dcd4f7c0a 100644
--- a/controllers/admin/AdminCountriesController.php
+++ b/controllers/admin/AdminCountriesController.php
@@ -433,10 +433,10 @@ class AdminCountriesControllerCore extends AdminController
public function processStatus()
{
- $return = parent::processStatus();
+ parent::processStatus();
if (Validate::isLoadedObject($object = $this->loadObject()) && $object->active == 1)
- $return &= Country::addModuleRestrictions(array(), array(array('id_country' => $object->id)), array());
- return $return;
+ return Country::addModuleRestrictions(array(), array(array('id_country' => $object->id)), array());
+ return false;
}
public function processBulkStatusSelection($way)
diff --git a/controllers/admin/AdminCurrenciesController.php b/controllers/admin/AdminCurrenciesController.php
index c5d719483..bf8690b64 100644
--- a/controllers/admin/AdminCurrenciesController.php
+++ b/controllers/admin/AdminCurrenciesController.php
@@ -38,7 +38,7 @@ class AdminCurrenciesControllerCore extends AdminController
'iso_code' => array('title' => $this->l('ISO code'), 'align' => 'center', 'width' => 80),
'iso_code_num' => array('title' => $this->l('ISO code number'), 'align' => 'center', 'width' => 120),
'sign' => array('title' => $this->l('Symbol'), 'width' => 20, 'align' => 'center', 'orderby' => false, 'search' => false),
- 'conversion_rate' => array('title' => $this->l('Exchange rate'), 'type' => 'float', 'align' => 'center', 'width' => 130, 'search' => false),
+ 'conversion_rate' => array('title' => $this->l('Exchange rate'), 'type' => 'float', 'align' => 'center', 'width' => 130, 'search' => false, 'filter_key' => 'currency_shop!conversion_rate'),
'active' => array('title' => $this->l('Enabled'), 'width' => 25, 'align' => 'center', 'active' => 'status', 'type' => 'bool', 'orderby' => false),
);
diff --git a/controllers/admin/AdminHomeController.php b/controllers/admin/AdminHomeController.php
index 03f2fbed6..67ff97695 100644
--- a/controllers/admin/AdminHomeController.php
+++ b/controllers/admin/AdminHomeController.php
@@ -377,12 +377,13 @@ class AdminHomeControllerCore extends AdminController
$chart = new Chart();
$chart->getCurve(1)->setType('bars');
$result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
- SELECT total_paid / conversion_rate as total_converted, left(invoice_date, 10) as invoice_date
+ SELECT SUM(total_paid / conversion_rate) as total_converted, left(invoice_date, 10) as invoice_date
FROM '._DB_PREFIX_.'orders o
WHERE valid = 1
AND total_paid > 0
AND invoice_date BETWEEN \''.date('Y-m-d', strtotime('-7 DAYS', time())).' 00:00:00\' AND \''.date('Y-m-d H:i:s').'\'
- '.Shop::addSqlRestriction(Shop::SHARE_ORDER).'
+ '.Shop::addSqlRestriction(Shop::SHARE_ORDER).'
+ GROUP BY DATE(invoice_date)
');
foreach ($result as $row)
$chart->getCurve(1)->setPoint(strtotime($row['invoice_date'].' 02:00:00'), $row['total_converted']);
diff --git a/controllers/admin/AdminImagesController.php b/controllers/admin/AdminImagesController.php
index 22694773d..8791cd27f 100644
--- a/controllers/admin/AdminImagesController.php
+++ b/controllers/admin/AdminImagesController.php
@@ -375,6 +375,7 @@ class AdminImagesControllerCore extends AdminController
|| !Configuration::updateValue('PS_PNG_QUALITY', Tools::getValue('PS_PNG_QUALITY')))
$this->errors[] = Tools::displayError('Unknown error.');
else
+ $this->confirmations[] = $this->_conf[6];
return parent::postProcess();
}
else
diff --git a/controllers/admin/AdminManufacturersController.php b/controllers/admin/AdminManufacturersController.php
index b1e630bc1..0f23f90d3 100644
--- a/controllers/admin/AdminManufacturersController.php
+++ b/controllers/admin/AdminManufacturersController.php
@@ -511,7 +511,7 @@ class AdminManufacturersControllerCore extends AdminController
$this->fields_value = array(
'name' => Manufacturer::getNameById($address->id_manufacturer),
'alias' => 'manufacturer',
- 'id_country' => Configuration::get('PS_COUNTRY_DEFAULT')
+ 'id_country' => $address->id_country
);
$this->initToolbar();
@@ -671,6 +671,8 @@ class AdminManufacturersControllerCore extends AdminController
if (Tools::isSubmit('editaddresses'))
$this->display = 'editaddresses';
+ else if (Tools::isSubmit('updateaddress'))
+ $this->display = 'editaddresses';
else if (Tools::isSubmit('addaddress'))
$this->display = 'addaddress';
else if (Tools::isSubmit('submitAddaddress'))
diff --git a/controllers/admin/AdminPreferencesController.php b/controllers/admin/AdminPreferencesController.php
index 5df23eae9..f878f69fc 100644
--- a/controllers/admin/AdminPreferencesController.php
+++ b/controllers/admin/AdminPreferencesController.php
@@ -95,6 +95,14 @@ class AdminPreferencesControllerCore extends AdminController
'default' => '0',
'visibility' => Shop::CONTEXT_ALL
),
+ 'PS_ALLOW_HTML_IFRAME' => array(
+ 'title' => $this->l('Allow iframes on html fields'),
+ 'desc' => $this->l('Allow iframes on fields like product description. We recommend that you leave this option disabled'),
+ 'validation' => 'isBool',
+ 'cast' => 'intval',
+ 'type' => 'bool',
+ 'default' => '0'
+ ),
'PS_PRICE_ROUND_MODE' => array(
'title' => $this->l('Round mode'),
'desc' => $this->l('You can choose how to round prices: Always round superior, always round inferior or classic rounding.'),
diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php
index 9ca3c4fba..91aac1d37 100644
--- a/controllers/admin/AdminProductsController.php
+++ b/controllers/admin/AdminProductsController.php
@@ -2058,17 +2058,28 @@ class AdminProductsControllerCore extends AdminController
// Check fields validity
foreach ($rules['validate'] as $field => $function)
if ($this->isProductFieldUpdated($field) && ($value = Tools::getValue($field)))
- if (!Validate::$function($value))
+ {
+ $res = true;
+ if (Tools::strtolower($function) == 'iscleanhtml')
+ {
+ if (!Validate::$function($value, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')))
+ $res = false;
+ }
+ else
+ if (!Validate::$function($value))
+ $res = false;
+
+ if (!$res)
$this->errors[] = sprintf(
Tools::displayError('The %s field is invalid.'),
call_user_func(array($className, 'displayFieldName'), $field, $className)
);
-
+ }
// Check multilingual fields validity
foreach ($rules['validateLang'] as $fieldLang => $function)
foreach ($languages as $language)
if ($this->isProductFieldUpdated('description_short', $language['id_lang']) && ($value = Tools::getValue($fieldLang.'_'.$language['id_lang'])))
- if (!Validate::$function($value))
+ if (!Validate::$function($value, (int)Configuration::get('PS_ALLOW_HTML_IFRAME')))
$this->errors[] = sprintf(
Tools::displayError('The %1$s field (%2$s) is invalid.'),
call_user_func(array($className, 'displayFieldName'), $fieldLang, $className),
@@ -2543,7 +2554,7 @@ class AdminProductsControllerCore extends AdminController
$this->tpl_form_vars['currentIndex'] = self::$currentIndex;
$this->tpl_form_vars['display_multishop_checkboxes'] = (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_SHOP && $this->display == 'edit');
$this->fields_form = array('');
- $this->display = 'edit';
+
$this->tpl_form_vars['token'] = $this->token;
$this->tpl_form_vars['combinationImagesJs'] = $this->getCombinationImagesJs();
$this->tpl_form_vars['PS_ALLOW_ACCENTED_CHARS_URL'] = (int)Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL');
@@ -2573,8 +2584,8 @@ class AdminProductsControllerCore extends AdminController
$this->tpl_form_vars['upload_max_filesize'] = $upload_max_filesize;
$this->tpl_form_vars['country_display_tax_label'] = $this->context->country->display_tax_label;
$this->tpl_form_vars['has_combinations'] = $this->object->hasAttributes();
-
$this->product_exists_in_shop = true;
+
if ($this->display == 'edit' && Validate::isLoadedObject($product) && Shop::isFeatureActive() && Shop::getContext() == Shop::CONTEXT_SHOP && !$product->isAssociatedToShop($this->context->shop->id))
{
$this->product_exists_in_shop = false;
@@ -2602,12 +2613,14 @@ class AdminProductsControllerCore extends AdminController
$this->initPack($this->object);
$this->{'initForm'.$this->tab_display}($this->object);
$this->tpl_form_vars['product'] = $this->object;
+
if ($this->ajax)
if (!isset($this->tpl_form_vars['custom_form']))
throw new PrestaShopException('custom_form empty for action '.$this->tab_display);
else
return $this->tpl_form_vars['custom_form'];
}
+
$parent = parent::renderForm();
$this->addJqueryPlugin(array('autocomplete', 'fancybox', 'typewatch'));
return $parent;
@@ -2999,7 +3012,7 @@ class AdminProductsControllerCore extends AdminController
$data->assign(array(
'link' => $this->context->link,
'currency' => $currency = $this->context->currency,
- 'tax_rules_groups' => TaxRulesGroup::getTaxRulesGroups(true),
+ 'tax_rules_groups' => TaxRulesGroup::getTaxRulesGroups(true, true),
'taxesRatesByGroup' => TaxRulesGroup::getAssociatedTaxRatesByIdCountry($this->context->country->id),
'ecotaxTaxRate' => Tax::getProductEcotaxRate(),
'tax_exclude_taxe_option' => Tax::excludeTaxeOption(),
@@ -3490,7 +3503,7 @@ class AdminProductsControllerCore extends AdminController
$data->assign('languages', $this->_languages);
$data->assign('currency', $currency);
$this->object = $product;
- $this->display = 'edit';
+ //$this->display = 'edit';
$data->assign('product_name_redirected', Product::getProductName((int)$product->id_product_redirected, null, (int)$this->context->language->id));
/*
* Form for adding a virtual product like software, mp3, etc...
@@ -3646,12 +3659,15 @@ class AdminProductsControllerCore extends AdminController
$current_shop_id = (int)$this->context->shop->id;
else
$current_shop_id = 0;
+
+ $languages = Language::getLanguages(true);
$data->assign(array(
'countImages' => $count_images,
'id_product' => (int)Tools::getValue('id_product'),
'id_category_default' => (int)$this->_category->id,
'images' => $images,
+ 'iso_lang' => $languages[0]['iso_code'],
'token' => $this->token,
'table' => $this->table,
'max_image_size' => $this->max_image_size / 1024 / 1024,
diff --git a/controllers/admin/AdminStockInstantStateController.php b/controllers/admin/AdminStockInstantStateController.php
index 04079c882..a3db14452 100644
--- a/controllers/admin/AdminStockInstantStateController.php
+++ b/controllers/admin/AdminStockInstantStateController.php
@@ -181,11 +181,13 @@ class AdminStockInstantStateControllerCore extends AdminController
*/
public function getList($id_lang, $order_by = null, $order_way = null, $start = 0, $limit = null, $id_lang_shop = false)
{
- if (Tools::isSubmit('csv') && (int)Tools::getValue('id_warehouse') != -1)
+ if ((Tools::isSubmit('csv_quantities') || Tools::isSubmit('csv_prices')) &&
+ (int)Tools::getValue('id_warehouse') != -1)
$limit = false;
$order_by_valuation = false;
$order_by_real_quantity = false;
+
if ($this->context->cookie->{$this->table.'Orderby'} == 'valuation')
{
unset($this->context->cookie->{$this->table.'Orderby'});
@@ -200,6 +202,7 @@ class AdminStockInstantStateControllerCore extends AdminController
parent::getList($id_lang, $order_by, $order_way, $start, $limit, $id_lang_shop);
$nb_items = count($this->_list);
+
for ($i = 0; $i < $nb_items; ++$i)
{
$item = &$this->_list[$i];
diff --git a/controllers/admin/AdminStoresController.php b/controllers/admin/AdminStoresController.php
index 03a001d34..ec9175901 100644
--- a/controllers/admin/AdminStoresController.php
+++ b/controllers/admin/AdminStoresController.php
@@ -296,8 +296,12 @@ class AdminStoresControllerCore extends AdminController
if (!($obj = $this->loadObject(true)))
return;
+
+ if (file_exists(_PS_TMP_IMG_DIR_.$this->table.'_'.(int)$obj->id.'.'.$this->imageType)) {
+ @unlink(_PS_TMP_IMG_DIR_.$this->table.'_'.(int)$obj->id.'.'.$this->imageType);
+ }
- $image = ImageManager::thumbnail(_PS_STORE_IMG_DIR_.'/'.$obj->id.'.jpg', $this->table.'_'.(int)$obj->id.'.'.$this->imageType, 350, $this->imageType, true);
+ $image = ImageManager::thumbnail(_PS_STORE_IMG_DIR_.DIRECTORY_SEPARATOR.$obj->id.'.jpg', $this->table.'_'.(int)$obj->id.'.'.$this->imageType, 350, $this->imageType, true, true);
$days = array();
$days[1] = $this->l('Monday');
@@ -316,7 +320,7 @@ class AdminStoresControllerCore extends AdminController
'latitude' => $this->getFieldValue($obj, 'latitude') ? $this->getFieldValue($obj, 'latitude') : Configuration::get('PS_STORES_CENTER_LAT'),
'longitude' => $this->getFieldValue($obj, 'longitude') ? $this->getFieldValue($obj, 'longitude') : Configuration::get('PS_STORES_CENTER_LONG'),
'image' => $image ? $image : false,
- 'size' => $image ? filesize(_PS_STORE_IMG_DIR_.'/'.$obj->id.'.jpg') / 1000 : false,
+ 'size' => $image ? filesize(_PS_STORE_IMG_DIR_.DIRECTORY_SEPARATOR.$obj->id.'.jpg') / 1000 : false,
'days' => $days,
'hours' => isset($hours_unserialized) ? $hours_unserialized : false
);
diff --git a/controllers/admin/AdminTagsController.php b/controllers/admin/AdminTagsController.php
index 7e7ffcf41..57a158d37 100644
--- a/controllers/admin/AdminTagsController.php
+++ b/controllers/admin/AdminTagsController.php
@@ -77,8 +77,23 @@ class AdminTagsControllerCore extends AdminController
public function postProcess()
{
if ($this->tabAccess['edit'] === '1' && Tools::getValue('submitAdd'.$this->table))
+ {
if (($id = (int)Tools::getValue($this->identifier)) && ($obj = new $this->className($id)) && Validate::isLoadedObject($obj))
+ {
+ $previousProducts = $obj->getProducts();
+ $removedProducts = array();
+
+ foreach ($previousProducts as $product)
+ if (!in_array($product['id_product'], $_POST['products']))
+ $removedProducts[] = $product['id_product'];
+
+ if (Configuration::get('PS_SEARCH_INDEXATION'))
+ Search::removeProductsSearchIndex($removedProducts);
+
$obj->setProducts($_POST['products']);
+ }
+ }
+
return parent::postProcess();
}
diff --git a/controllers/admin/AdminThemesController.php b/controllers/admin/AdminThemesController.php
index dcf849a53..2d0c63706 100644
--- a/controllers/admin/AdminThemesController.php
+++ b/controllers/admin/AdminThemesController.php
@@ -614,7 +614,7 @@ class AdminThemesControllerCore extends AdminController
$ext = ($field_name == 'PS_STORES_ICON') ? '.gif' : '.jpg';
$logo_name = $logo_prefix.'-'.(int)$id_shop.$ext;
- if (Context::getContext()->shop->getContext() == Shop::CONTEXT_ALL || $id_shop == 0 || Shop::isFeatureActive()==false)
+ if (Context::getContext()->shop->getContext() == Shop::CONTEXT_ALL || $id_shop == 0 || Shop::isFeatureActive() == false)
$logo_name = $logo_prefix.$ext;
if ($field_name == 'PS_STORES_ICON')
diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php
index 36dbaa061..784f15c59 100644
--- a/controllers/admin/AdminTranslationsController.php
+++ b/controllers/admin/AdminTranslationsController.php
@@ -353,13 +353,15 @@ class AdminTranslationsControllerCore extends AdminController
$items = Language::getFilesList($from_lang, $from_theme, $to_lang, $to_theme, false, false, true);
foreach ($items as $source => $dest)
{
- $bool &= $this->checkDirAndCreate($dest);
- $bool &= @copy($source, $dest);
-
- if (strpos($dest, 'modules') && basename($source) === $from_lang.'.php' && $bool !== false)
- $bool &= $this->changeModulesKeyTranslation($dest, $from_theme, $to_theme);
+ if (!$this->checkDirAndCreate($dest))
+ $this->errors[] = sprintf($this->l('Impossible to create the directory "%s".'), $dest);
+ elseif (!copy($source, $dest))
+ $this->errors[] = sprintf($this->l('Impossible to copy "%s" to "%s".'), $source, $dest);
+ elseif (strpos($dest, 'modules') && basename($source) === $from_lang.'.php' && $bool !== false)
+ if (!$this->changeModulesKeyTranslation($dest, $from_theme, $to_theme))
+ $this->errors[] = sprintf($this->l('Impossible to translate "$dest".'), $dest);
}
- if ($bool)
+ if (!count($this->errors))
$this->redirect(false, 14);
$this->errors[] = $this->l('A part of the data has been copied but some of the language files could not be found.');
}
@@ -1072,7 +1074,7 @@ class AdminTranslationsControllerCore extends AdminController
if ($type_file == 'php')
$regex = '/this->l\(\''._PS_TRANS_PATTERN_.'\'[\)|\,]/U';
else if ($type_file == 'specific')
- $regex = '/translate\(\''._PS_TRANS_PATTERN_.'\'\)/U';
+ $regex = '/Translate::getAdminTranslation\(\''._PS_TRANS_PATTERN_.'\'\)/U';
else
$regex = '/\{l\s*s\s*=[\'\"]'._PS_TRANS_PATTERN_.'[\'\"](\s*sprintf=.*)?(\s*js=1)?(\s*slashes=1)?\s*\}/U';
break;
diff --git a/controllers/front/ContactController.php b/controllers/front/ContactController.php
index d5a136ae3..01941bf4d 100644
--- a/controllers/front/ContactController.php
+++ b/controllers/front/ContactController.php
@@ -37,15 +37,8 @@ class ContactControllerCore extends FrontController
{
if (Tools::isSubmit('submitMessage'))
{
- $fileAttachment = null;
- if (isset($_FILES['fileUpload']['name']) && !empty($_FILES['fileUpload']['name']) && !empty($_FILES['fileUpload']['tmp_name']))
- {
- $extension = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
- $filename = uniqid().substr($_FILES['fileUpload']['name'], -5);
- $fileAttachment['content'] = file_get_contents($_FILES['fileUpload']['tmp_name']);
- $fileAttachment['name'] = $_FILES['fileUpload']['name'];
- $fileAttachment['mime'] = $_FILES['fileUpload']['type'];
- }
+ $extension = array('.txt', '.rtf', '.doc', '.docx', '.pdf', '.zip', '.png', '.jpeg', '.gif', '.jpg');
+ $fileAttachment = Tools::fileAttachment('fileUpload');
$message = Tools::getValue('message'); // Html entities is not usefull, iscleanHtml check there is no bad html tags.
if (!($from = trim(Tools::getValue('from'))) || !Validate::isEmail($from))
$this->errors[] = Tools::displayError('Invalid email address.');
@@ -55,9 +48,9 @@ class ContactControllerCore extends FrontController
$this->errors[] = Tools::displayError('Invalid message');
else if (!($id_contact = (int)(Tools::getValue('id_contact'))) || !(Validate::isLoadedObject($contact = new Contact($id_contact, $this->context->language->id))))
$this->errors[] = Tools::displayError('Please select a subject from the list provided. ');
- else if (!empty($_FILES['fileUpload']['name']) && $_FILES['fileUpload']['error'] != 0)
+ else if (!empty($fileAttachment['name']) && $fileAttachment['error'] != 0)
$this->errors[] = Tools::displayError('An error occurred during the file-upload process.');
- else if (!empty($_FILES['fileUpload']['name']) && !in_array(substr(Tools::strtolower($_FILES['fileUpload']['name']), -4), $extension) && !in_array(substr(Tools::strtolower($_FILES['fileUpload']['name']), -5), $extension))
+ else if (!empty($fileAttachment['name']) && !in_array( Tools::strtolower(substr($fileAttachment['name'], -4)), $extension) && !in_array( Tools::strtolower(substr($fileAttachment['name'], -5)), $extension))
$this->errors[] = Tools::displayError('Bad file extension');
else
{
@@ -152,8 +145,8 @@ class ContactControllerCore extends FrontController
$cm = new CustomerMessage();
$cm->id_customer_thread = $ct->id;
$cm->message = Tools::htmlentitiesUTF8($message);
- if (isset($filename) && rename($_FILES['fileUpload']['tmp_name'], _PS_MODULE_DIR_.'../upload/'.$filename))
- $cm->file_name = $filename;
+ if (isset($fileAttachment['rename']) && !empty($fileAttachment['rename']) && rename($fileAttachment['tmp_name'], _PS_MODULE_DIR_.'../upload/'.basename($fileAttachment['rename'])))
+ $cm->file_name = $fileAttachment['rename'];
$cm->ip_address = ip2long($_SERVER['REMOTE_ADDR']);
$cm->user_agent = $_SERVER['HTTP_USER_AGENT'];
if (!$cm->add())
@@ -173,8 +166,8 @@ class ContactControllerCore extends FrontController
'{product_name}' => '',
);
- if (isset($filename))
- $var_list['{attached_file}'] = $_FILES['fileUpload']['name'];
+ if (isset($fileAttachment['name']))
+ $var_list['{attached_file}'] = $fileAttachment['name'];
$id_order = (int)Tools::getValue('id_order');
@@ -197,10 +190,6 @@ class ContactControllerCore extends FrontController
$var_list['{product_name}'] = $product->name[Context::getContext()->language->id];
}
-
-
-
-
if (empty($contact->email))
Mail::Send($this->context->language->id, 'contact_form', ((isset($ct) && Validate::isLoadedObject($ct)) ? sprintf(Mail::l('Your message has been correctly sent #ct%1$s #tc%2$s'), $ct->id, $ct->token) : Mail::l('Your message has been correctly sent')), $var_list, $from, null, null, null, $fileAttachment);
else
@@ -296,5 +285,4 @@ class ContactControllerCore extends FrontController
$this->context->smarty->assign('orderedProductList', $products);
}
}
-}
-
+}
\ No newline at end of file
diff --git a/controllers/front/ManufacturerController.php b/controllers/front/ManufacturerController.php
index 1aa4ae22e..096b2e4c9 100644
--- a/controllers/front/ManufacturerController.php
+++ b/controllers/front/ManufacturerController.php
@@ -113,6 +113,9 @@ class ManufacturerControllerCore extends FrontController
{
$data = Manufacturer::getManufacturers(true, $this->context->language->id, true, false, false, false);
$nbProducts = count($data);
+ $this->n = abs((int)(Tools::getValue('n', Configuration::get('PS_PRODUCTS_PER_PAGE'))));
+ $this->p = abs((int)(Tools::getValue('p', 1)));
+ $data = Manufacturer::getManufacturers(true, $this->context->language->id, true, $this->p, $this->n, false);
$this->pagination($nbProducts);
foreach ($data as &$item)
@@ -129,4 +132,4 @@ class ManufacturerControllerCore extends FrontController
else
$this->context->smarty->assign('nbManufacturers', 0);
}
-}
+}
\ No newline at end of file
diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php
index d55dc92b9..46aa593c9 100644
--- a/controllers/front/ProductController.php
+++ b/controllers/front/ProductController.php
@@ -158,7 +158,7 @@ class ProductControllerCore extends FrontController
$this->category = new Category($regs[5], (int)$this->context->cookie->id_lang);
}
}
- else
+ if ( ! isset($this->category))
// Set default product category
$this->category = new Category($this->product->id_category_default, (int)$this->context->cookie->id_lang);
}
diff --git a/css/admin.css b/css/admin.css
index f5201ec60..69431a489 100644
--- a/css/admin.css
+++ b/css/admin.css
@@ -567,6 +567,12 @@ select optgroup option {
background: url(../img/admin/warning.gif) no-repeat 0 0;
}
+#blockNewVersionCheck .warn h3 {
+ padding: 0 0 0 5px;
+ margin: 0px;
+ background: none;
+}
+
#content .error h3 {
padding: 0 0 0 20px;
background: url(../img/admin/warning.gif) no-repeat 0 0;
diff --git a/install-dev/data/xml/hook.xml b/install-dev/data/xml/hook.xml
index 1139431f2..005284227 100644
--- a/install-dev/data/xml/hook.xml
+++ b/install-dev/data/xml/hook.xml
@@ -86,7 +86,7 @@
displayCustomerAccountCustomer account displayed in Front OfficeThis hook displays new elements on the customer account page
- actionOrderSlipAddOrder slip creationThis hook is called when a product's quantity is modified
+ actionOrderSlipAddOrder slip creationThis hook is called when a new credit slip is added regarding client order
displayProductTabTabs on product pageThis hook is called on the product page's tab
diff --git a/install-dev/upgrade/sql/1.5.5.0.sql b/install-dev/upgrade/sql/1.5.5.0.sql
index 934492867..152e75ea9 100644
--- a/install-dev/upgrade/sql/1.5.5.0.sql
+++ b/install-dev/upgrade/sql/1.5.5.0.sql
@@ -24,3 +24,5 @@ ALTER TABLE `PREFIX_log` ADD `id_employee` INT(10) UNSIGNED NULL AFTER `object_i
SET @id_parent = (SELECT IFNULL(id_tab, 1) FROM `PREFIX_tab` WHERE `class_name` = 'AdminPriceRule' LIMIT 1);
UPDATE `PREFIX_tab` SET id_parent = @id_parent WHERE `id_parent` = 1 AND `class_name` = 'AdminMarketing' LIMIT 1;
+
+UPDATE `PREFIX_hook` SET `description` = 'This hook is called when a new credit slip is added regarding client order' WHERE `name` = 'actionOrderSlipAdd';
\ No newline at end of file
diff --git a/js/jquery/plugins/tagify/jquery.tagify.js b/js/jquery/plugins/tagify/jquery.tagify.js
index 87eea42b0..7ba821de5 100755
--- a/js/jquery/plugins/tagify/jquery.tagify.js
+++ b/js/jquery/plugins/tagify/jquery.tagify.js
@@ -40,10 +40,6 @@
// if backspace is hit with no input, remove the last tag
if (pressed == 8) { // backspace
- if ( $this.val() == "" ) {
- self.remove();
- return false;
- }
return;
}
});
diff --git a/mails/en/contact.html b/mails/en/contact.html
index 62ab2c9ab..a122cab61 100644
--- a/mails/en/contact.html
+++ b/mails/en/contact.html
@@ -20,7 +20,11 @@
|
-Customer e-mail address: {email}
Customer message: {message} |
+Customer e-mail address: {email}
+
Customer message: {message}
+
Order ID : {order_name}
+
Attached file : {attached_file}
+ |
| |
diff --git a/mails/en/contact.txt b/mails/en/contact.txt
index 2e1bc5eb7..d97039345 100644
--- a/mails/en/contact.txt
+++ b/mails/en/contact.txt
@@ -8,4 +8,8 @@ Customer message:
{message}
+Order reference : {order_name}
+
+Attached file : {attached_file}
+
{shop_url} powered by PrestaShop™
\ No newline at end of file
diff --git a/modules/blockmyaccountfooter/config.xml b/modules/blockmyaccountfooter/config.xml
index 0266fa7ae..aa3e350ae 100644
--- a/modules/blockmyaccountfooter/config.xml
+++ b/modules/blockmyaccountfooter/config.xml
@@ -2,7 +2,7 @@
blockmyaccountfooter
-
+
diff --git a/modules/cheque/config.xml b/modules/cheque/config.xml
index dd5655265..e49cd3934 100755
--- a/modules/cheque/config.xml
+++ b/modules/cheque/config.xml
@@ -1,7 +1,7 @@
cheque
-
+
diff --git a/modules/loyalty/controllers/front/default.php b/modules/loyalty/controllers/front/default.php
index 64e152db0..e28f5b7a6 100644
--- a/modules/loyalty/controllers/front/default.php
+++ b/modules/loyalty/controllers/front/default.php
@@ -89,6 +89,7 @@ class LoyaltyDefaultModuleFrontController extends ModuleFrontController
$cart_rule->date_to = date('Y-m-d H:i:s', strtotime($cart_rule->date_from.' +1 year'));
$cart_rule->minimum_amount = (float)Configuration::get('PS_LOYALTY_MINIMAL');
+ $cart_rule->minimum_amount_currency = (int)$this->context->currency->id;
$cart_rule->active = 1;
$categories = Configuration::get('PS_LOYALTY_VOUCHER_CATEGORY');
diff --git a/modules/mailalerts/mailalerts.php b/modules/mailalerts/mailalerts.php
index 82e9da99a..1516c0de5 100644
--- a/modules/mailalerts/mailalerts.php
+++ b/modules/mailalerts/mailalerts.php
@@ -540,8 +540,7 @@ class MailAlerts extends Module
$coverage = StockManagerFactory::getManager()->getProductCoverage($id_product, $id_product_attribute, $warning_coverage, $id_warehouse);
// if we need to send a notification
- if ($product->active == 1 &&
- ($coverage < $warning_coverage) && !empty($this->_merchant_mails) &&
+ if ($product->active == 1 && $coverage !== -1 && ($coverage < $warning_coverage) && !empty($this->_merchant_mails) &&
Configuration::getGlobalValue('MA_MERCHANT_COVERAGE'))
{
$id_lang = (int)Context::getContext()->language->id;
diff --git a/modules/pscleaner/pscleaner.php b/modules/pscleaner/pscleaner.php
index 67ea6595c..9f7215a5f 100644
--- a/modules/pscleaner/pscleaner.php
+++ b/modules/pscleaner/pscleaner.php
@@ -131,6 +131,31 @@ class PSCleaner extends Module
$db = Db::getInstance();
$logs = array();
+ // Remove doubles in the configuration
+ $filtered_configuration = array();
+ $result = $db->ExecuteS('SELECT * FROM '._DB_PREFIX_.'configuration');
+ foreach ($result as $row)
+ {
+ $key = $row['id_shop_group'].'-|-'.$row['id_shop'].'-|-'.$row['name'];
+ if (in_array($key, $filtered_configuration))
+ {
+ $query = 'DELETE FROM '._DB_PREFIX_.'configuration WHERE id_configuration = '.(int)$row['id_configuration'];
+ $db->Execute($query);
+ $logs[$query] = 1;
+ }
+ else
+ $filtered_configuration[] = $key;
+ }
+ unset($filtered_configuration);
+
+ // Remove inexisting or monolanguage configuration value from configuration_lang
+ $query = 'DELETE FROM `'._DB_PREFIX_.'configuration_lang`
+ WHERE `id_configuration` NOT IN (SELECT `id_configuration` FROM `'._DB_PREFIX_.'configuration`)
+ OR `id_configuration` IN (SELECT `id_configuration` FROM `'._DB_PREFIX_.'configuration` WHERE name IS NOT NULL AND name != "")';
+ if ($db->Execute($query))
+ if ($affected_rows = $db->Affected_Rows())
+ $logs[$query] = $affected_rows;
+
// Simple Cascade Delete
$queries = array(
// 0 => DELETE FROM __table__, 1 => WHERE __id__ NOT IN, 2 => NOT IN __table__, 3 => __id__ used in the "NOT IN" table, 4 => module_name
@@ -347,6 +372,7 @@ class PSCleaner extends Module
// @Todo: Remove attachment files, images...
Image::clearTmpDir();
+ $this->clearAllCaches();
return $logs;
}
@@ -534,6 +560,9 @@ class PSCleaner extends Module
protected function clearAllCaches()
{
+ $index = file_get_contents(_PS_TMP_IMG_DIR_.'index.php');
+ Tools::deleteDirectory(_PS_TMP_IMG_DIR_, false);
+ file_put_contents(_PS_TMP_IMG_DIR_.'index.php', $index);
Context::getContext()->smarty->clearAllCache();
}
}
diff --git a/modules/referralprogram/referralprogram.php b/modules/referralprogram/referralprogram.php
index 697824fa7..0d497e619 100644
--- a/modules/referralprogram/referralprogram.php
+++ b/modules/referralprogram/referralprogram.php
@@ -649,8 +649,7 @@ class ReferralProgram extends Module
{
$cartRule = new CartRule((int)$referralprogram->id_cart_rule_sponsor);
$currency = new Currency((int)$order->id_currency);
- $discount_display = ReferralProgram::displayDiscount($cartRule->reduction_percent ? $cartRule->reduction_percent : $cartRule->reduction_amount, $cartRule->reduction_percent ? 1 : 2, $currency);
- $data = array('{sponsored_firstname}' => $customer->firstname, '{sponsored_lastname}' => $customer->lastname, '{discount_display}' => $discount_display, '{discount_name}' => $cartRule->code);
+ $discount_display = ReferralProgram::displayDiscount( (float) $cartRule->reduction_percent ? (float) $cartRule->reduction_percent : (int) $cartRule->reduction_amount, (float) $cartRule->reduction_percent ? 1 : 2, $currency); $data = array('{sponsored_firstname}' => $customer->firstname, '{sponsored_lastname}' => $customer->lastname, '{discount_display}' => $discount_display, '{discount_name}' => $cartRule->code);
Mail::Send((int)$order->id_lang, 'referralprogram-congratulations', Mail::l('Congratulations!', (int)$order->id_lang), $data, $sponsor->email, $sponsor->firstname.' '.$sponsor->lastname, strval(Configuration::get('PS_SHOP_EMAIL')), strval(Configuration::get('PS_SHOP_NAME')), NULL, NULL, dirname(__FILE__).'/mails/');
return true;
}
diff --git a/modules/statsforecast/statsforecast.php b/modules/statsforecast/statsforecast.php
index 23b3f4c52..ddd93c921 100644
--- a/modules/statsforecast/statsforecast.php
+++ b/modules/statsforecast/statsforecast.php
@@ -470,7 +470,7 @@ class StatsForecast extends Module
$where = ' AND co.id_zone = '.(int)$this->context->cookie->stats_id_zone.' ';
}
- $sql = 'SELECT SUM(od.`product_price` * od.`product_quantity` / o.conversion_rate) as orderSum, COUNT(*) AS orderQty, cl.name, AVG(od.`product_price` / o.conversion_rate) as priveAvg
+ $sql = 'SELECT SUM(od.`product_price` * od.`product_quantity` / o.conversion_rate) as orderSum, SUM(od.product_quantity) as orderQty, cl.name, AVG(od.`product_price` / o.conversion_rate) as priveAvg
FROM `'._DB_PREFIX_.'orders` o
LEFT JOIN `'._DB_PREFIX_.'order_detail` od ON o.id_order = od.id_order
LEFT JOIN `'._DB_PREFIX_.'product` p ON p.id_product = od.product_id
diff --git a/override/readme_override.txt b/override/readme_override.txt
new file mode 100644
index 000000000..9a39204fb
--- /dev/null
+++ b/override/readme_override.txt
@@ -0,0 +1,9 @@
+Hello,
+
+Please read the documentation before trying to override something here.
+http://doc.prestashop.com/display/PS15/Overriding+default+behaviors
+
+Frequently Asked Questions
+
+Q: I added an override file but it seems to be ignored by PrestaShop
+A: You need to trigger the regeneration of the /cache/class_index.php file. This is done simply by deleting the file. It is the same when manually removing an override: in order to reinstate the default behavior, you must delete the /cache/class_index.php file.
diff --git a/themes/default/contact-form.tpl b/themes/default/contact-form.tpl
index dcd5d252f..ad1185cd0 100644
--- a/themes/default/contact-form.tpl
+++ b/themes/default/contact-form.tpl
@@ -89,8 +89,8 @@
{/foreach}
{elseif !isset($customerThread.id_order) && !isset($isLogged)}
-
- {elseif $customerThread.id_order > 0}
+
+ {elseif $customerThread.id_order|intval > 0}
{/if}
diff --git a/themes/default/pagination.tpl b/themes/default/pagination.tpl
index 070ab7e9b..fa806db11 100644
--- a/themes/default/pagination.tpl
+++ b/themes/default/pagination.tpl
@@ -53,42 +53,42 @@