diff --git a/admin-dev/themes/default/css/admin.css b/admin-dev/themes/default/css/admin.css index daff50b7d..ea6d4c7a7 100644 --- a/admin-dev/themes/default/css/admin.css +++ b/admin-dev/themes/default/css/admin.css @@ -546,6 +546,7 @@ form#product_form h4 { font-size:18px; font-weight:normal;} .default_modules_list_display_type #modules_list_container_content li table tr td{border: none} .default_modules_list_display_type #modules_list_container_content li table {border: solid 1px #ccc; height: 115px} +#modules_list_container_tab ul li {margin:5px;height:140px} /*MODULE POSITION*/ .blocLiveEdit { float:right; clear:right; background-color: #EBEDF4; border: 1px solid #C2C4D9;display: block; width:250px;} diff --git a/admin-dev/themes/default/template/controllers/products/helpers/list/list_header.tpl b/admin-dev/themes/default/template/controllers/products/helpers/list/list_header.tpl index 3b7a193cc..faa1f679d 100644 --- a/admin-dev/themes/default/template/controllers/products/helpers/list/list_header.tpl +++ b/admin-dev/themes/default/template/controllers/products/helpers/list/list_header.tpl @@ -35,7 +35,7 @@ if (this.value !== "") location.href = base_url + '&id_category=' + parseInt(this.value); else - location.href = base_url; + location.href = base_url + '&reset_filter_category=1'; }); // Make sure the checkbox is checked/unchecked when the link is clicked @@ -47,7 +47,7 @@ else { $(this).find('input').removeAttr('checked'); - location.href = base_url; + location.href = base_url + '&reset_filter_category=1'; } }); }); diff --git a/admin-dev/themes/default/template/layout-export.tpl b/admin-dev/themes/default/template/layout-export.tpl new file mode 100644 index 000000000..385d49b23 --- /dev/null +++ b/admin-dev/themes/default/template/layout-export.tpl @@ -0,0 +1,29 @@ +{* +* 2007-2013 PrestaShop +* +* NOTICE OF LICENSE +* +* This source file is subject to the Academic Free License (AFL 3.0) +* that is bundled with this package in the file LICENSE.txt. +* It is also available through the world-wide-web at this URL: +* http://opensource.org/licenses/afl-3.0.php +* If you did not receive a copy of the license and are unable to +* obtain it through the world-wide-web, please send an email +* to license@prestashop.com so we can send you a copy immediately. +* +* DISCLAIMER +* +* Do not edit or add to this file if you wish to upgrade PrestaShop to newer +* versions in the future. If you wish to customize PrestaShop for your +* needs please refer to http://www.prestashop.com for more information. +* +* @author PrestaShop SA +* @copyright 2007-2013 PrestaShop SA +* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0) +* International Registered Trademark & Property of PrestaShop SA +*} +{foreach from=$export_headers item=header}{$header};{/foreach} +{foreach from=$export_content item=line} + +{foreach from=$line item=content}{$content};{/foreach} +{/foreach} \ No newline at end of file diff --git a/classes/Cart.php b/classes/Cart.php index 921b185fd..1dda83cb7 100644 --- a/classes/Cart.php +++ b/classes/Cart.php @@ -2325,7 +2325,7 @@ class CartCore extends ObjectModel public function getDeliveryOption($default_country = null, $dontAutoSelectOptions = false, $use_cache = true) { static $cache = array(); - $cache_id = (int)$default_country.'-'.(int)$dontAutoSelectOptions; + $cache_id = (int)(is_object($default_country) ? $default_country->id : 0).'-'.(int)$dontAutoSelectOptions; if (isset($cache[$cache_id]) && $use_cache) return $cache[$cache_id]; @@ -2865,7 +2865,9 @@ class CartCore extends ObjectModel if ($cart_rule['free_shipping'] && (empty($cart_rule['code']) || preg_match('/^'.CartRule::BO_ORDER_CODE_PREFIX.'[0-9]+/', $cart_rule['code']))) { $cart_rule['value_real'] -= $total_shipping; - $cart_rule['value_tax_exc'] = $total_shipping_tax_exc; + $cart_rule['value_tax_exc'] -= $total_shipping_tax_exc; + $total_discounts -= $total_shipping; + $total_discounts_tax_exc -= $total_shipping_tax_exc; // Update total shipping $total_shipping = 0; diff --git a/classes/Category.php b/classes/Category.php index 24076a287..7286a630d 100644 --- a/classes/Category.php +++ b/classes/Category.php @@ -1048,7 +1048,7 @@ class CategoryCore extends ObjectModel $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' SELECT ctg.`id_group` FROM '._DB_PREFIX_.'category_group ctg - WHERE ctg.`id_category` = '.(int)$this->id.' AND ctg.`id_group` = 1 + WHERE ctg.`id_category` = '.(int)$this->id.' AND ctg.`id_group` = '.(int)Group::getCurrent()->id.' '); } else { $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' diff --git a/classes/Media.php b/classes/Media.php index 7e2802c00..a9e46a0d3 100755 --- a/classes/Media.php +++ b/classes/Media.php @@ -128,12 +128,18 @@ class MediaCore public static function packJS($js_content) { - if (strlen($js_content) > 0) + if (!empty($js_content)) { require_once(_PS_TOOL_DIR_.'js_minify/jsmin.php'); - return JSMin::minify($js_content); + try { + $js_content = JSMin::minify($js_content); + } catch (Exception $e) { + if (_PS_MODE_DEV_) + echo $e->getMessage(); + return $js_content; + } } - return false; + return $js_content; } public static function minifyCSS($css_content, $fileuri = false, &$import_url = array()) diff --git a/classes/Product.php b/classes/Product.php index d4db0e7d6..d0e1f61a5 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -2668,7 +2668,6 @@ class ProductCore extends ObjectModel // Add Tax if ($use_tax) $price = $product_tax_calculator->addTaxes($price); - $price = Tools::ps_round($price, $decimals); // Reduction $reduc = 0; @@ -2680,14 +2679,14 @@ class ProductCore extends ObjectModel if (!$specific_price['id_currency']) $reduction_amount = Tools::convertPrice($reduction_amount, $id_currency); - $reduc = Tools::ps_round(!$use_tax ? $product_tax_calculator->removeTaxes($reduction_amount) : $reduction_amount, $decimals); + $reduc = !$use_tax ? $product_tax_calculator->removeTaxes($reduction_amount) : $reduction_amount; } else - $reduc = Tools::ps_round($price * $specific_price['reduction'], $decimals); + $reduc = $price * $specific_price['reduction']; } if ($only_reduc) - return $reduc; + return Tools::ps_round($reduc, $decimals); if ($use_reduc) $price -= $reduc; @@ -2700,7 +2699,6 @@ class ProductCore extends ObjectModel $price *= ((100 - Group::getReductionByIdGroup($id_group)) / 100); } - $price = Tools::ps_round($price, $decimals); // Eco Tax if (($result['ecotax'] || isset($result['attribute_ecotax'])) && $with_ecotax) { @@ -4236,7 +4234,7 @@ class ProductCore extends ObjectModel SELECT ctg.`id_group` FROM `'._DB_PREFIX_.'category_product` cp INNER JOIN `'._DB_PREFIX_.'category_group` ctg ON (ctg.`id_category` = cp.`id_category`) - WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` = 1'); + WHERE cp.`id_product` = '.(int)$this->id.' AND ctg.`id_group` ='.(int)Group::getCurrent()->id); else return (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' SELECT cg.`id_group` diff --git a/classes/Tools.php b/classes/Tools.php index d722d9d68..ba0ce7031 100644 --- a/classes/Tools.php +++ b/classes/Tools.php @@ -978,11 +978,11 @@ class ToolsCore if ($allow_accented_chars === null) $allow_accented_chars = Configuration::get('PS_ALLOW_ACCENTED_CHARS_URL'); + $str = trim($str); + if (function_exists('mb_strtolower')) $str = mb_strtolower($str, 'utf-8'); - - $str = trim($str); - if (!function_exists('mb_strtolower') || !$allow_accented_chars) + elseif (!$allow_accented_chars) $str = Tools::replaceAccentedChars($str); // Remove all non-whitelist chars. @@ -990,7 +990,7 @@ class ToolsCore $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-\pL]/u', '', $str); else $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-]/','', $str); - + $str = preg_replace('/[\s\'\:\/\[\]-]+/', ' ', $str); $str = str_replace(array(' ', '/'), '-', $str); @@ -1691,11 +1691,9 @@ class ToolsCore FileETag INode MTime Size - AddOutputFilterByType DEFLATE text/html - AddOutputFilterByType DEFLATE text/css - AddOutputFilterByType DEFLATE text/javascript - AddOutputFilterByType DEFLATE application/javascript - AddOutputFilterByType DEFLATE application/x-javascript + + AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/x-javascript + \n\n"; fwrite($write_fd, $cache_control); } diff --git a/classes/controller/AdminController.php b/classes/controller/AdminController.php index bfda6b83d..1f9949518 100644 --- a/classes/controller/AdminController.php +++ b/classes/controller/AdminController.php @@ -170,6 +170,8 @@ class AdminControllerCore extends Controller /** @var bool boolean List content lines are clickable if true */ protected $list_no_link = false; + protected $allow_export = false; + /** @var array $cache_lang cache for traduction */ public static $cache_lang = array(); @@ -564,6 +566,39 @@ class AdminControllerCore extends Controller $this->errors[] = Tools::displayError('An error occurred during image deletion (cannot load object).'); return $object; } + + public function processExport() + { + // clean buffer + ob_clean(); + $this->getList($this->context->language->id); + if (!count($this->_list)) + return; + + header('Content-type: text/csv'); + header('Content-Type: application/force-download; charset=UTF-8'); + header('Cache-Control: no-store, no-cache'); + header('Content-disposition: attachment; filename="'.$this->table.'_'.date('Y-m-d_His').'.csv"'); + + $headers = array(); + foreach ($this->fields_list as $datas) + $headers[] = $datas['title']; + + $content = array(); + foreach ($this->_list as $i => $row) + { + $content[$i] = array(); + foreach ($this->fields_list as $key => $value) + $content[$i][] = $row[$key]; + } + $this->context->smarty->assign(array( + 'export_headers' => $headers, + 'export_content' => $content + ) + ); + + $this->layout = 'layout-export.tpl'; + } /** * Object Delete @@ -1025,6 +1060,11 @@ class AdminControllerCore extends Controller 'href' => self::$currentIndex.'&add'.$this->table.'&token='.$this->token, 'desc' => $this->l('Add new') ); + if ($this->allow_export) + $this->toolbar_btn['export'] = array( + 'href' => self::$currentIndex.'&export'.$this->table.'&token='.$this->token, + 'desc' => $this->l('Export') + ); } $this->addToolBarModulesListButton(); } @@ -1929,6 +1969,11 @@ class AdminControllerCore extends Controller else $this->errors[] = Tools::displayError('You do not have permission to view here.'); } + elseif (isset($_GET['export'.$this->table])) + { + if ($this->tabAccess['view'] === '1') + $this->action = 'export'; + } /* Cancel all filters for this tab */ elseif (isset($_POST['submitReset'.$this->table])) $this->action = 'reset_filters'; diff --git a/classes/db/MySQL.php b/classes/db/MySQL.php index 2713305d8..b8db3dbd6 100644 --- a/classes/db/MySQL.php +++ b/classes/db/MySQL.php @@ -68,7 +68,12 @@ class MySQLCore extends Db */ public function nextRow($result = false) { - return mysql_fetch_assoc($result ? $result : $this->result); + $return = false; + if(is_resource($result) && $result) + $return = mysql_fetch_assoc($result); + elseif(is_resource($this->_result) && $this->_result) + $return = mysql_fetch_assoc($this->_result); + return $return; } /** diff --git a/config/smarty.config.inc.php b/config/smarty.config.inc.php index 892a22dd3..f45ce627d 100644 --- a/config/smarty.config.inc.php +++ b/config/smarty.config.inc.php @@ -55,11 +55,6 @@ if (defined('_PS_ADMIN_DIR_')) else require_once (dirname(__FILE__).'/smartyfront.config.inc.php'); -if (Configuration::get('PS_HTML_THEME_COMPRESSION')) - $smarty->registerFilter('output', 'smartyMinifyHTML'); -if (Configuration::get('PS_JS_HTML_THEME_COMPRESSION')) - $smarty->registerFilter('output', 'smartyPackJSinHTML'); - smartyRegisterFunction($smarty, 'modifier', 'truncate', 'smarty_modifier_truncate'); smartyRegisterFunction($smarty, 'modifier', 'secureReferrer', array('Tools', 'secureReferrer')); diff --git a/config/smartyfront.config.inc.php b/config/smartyfront.config.inc.php index 70de9a1bb..b95642a4b 100644 --- a/config/smartyfront.config.inc.php +++ b/config/smartyfront.config.inc.php @@ -27,6 +27,11 @@ global $smarty; $smarty->setTemplateDir(_PS_THEME_DIR_.'tpl'); +if (Configuration::get('PS_HTML_THEME_COMPRESSION')) + $smarty->registerFilter('output', 'smartyMinifyHTML'); +if (Configuration::get('PS_JS_HTML_THEME_COMPRESSION')) + $smarty->registerFilter('output', 'smartyPackJSinHTML'); + function smartyTranslate($params, &$smarty) { global $_LANG; diff --git a/controllers/admin/AdminAddressesController.php b/controllers/admin/AdminAddressesController.php index e949ad4f3..223b0f12b 100644 --- a/controllers/admin/AdminAddressesController.php +++ b/controllers/admin/AdminAddressesController.php @@ -44,6 +44,8 @@ class AdminAddressesControllerCore extends AdminController $this->addRowAction('delete'); $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); + $this->allow_export = true; + if (!Tools::getValue('realedit')) $this->deleted = true; @@ -61,8 +63,15 @@ class AdminAddressesControllerCore extends AdminController 'country' => array('title' => $this->l('Country'), 'width' => 100, 'type' => 'select', 'list' => $this->countries_array, 'filter_key' => 'cl!id_country')); parent::__construct(); + + $this->_select = 'cl.`name` as country'; + $this->_join = ' + LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (cl.`id_country` = a.`id_country` AND cl.`id_lang` = '.(int)$this->context->language->id.') + LEFT JOIN `'._DB_PREFIX_.'customer` c ON a.id_customer = c.id_customer + '; + $this->_where = 'AND a.id_customer != 0 '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c'); } - + public function initToolbar() { parent::initToolbar(); @@ -71,18 +80,6 @@ class AdminAddressesControllerCore extends AdminController 'desc' => $this->l('Import') ); } - - public function renderList() - { - $this->_select = 'cl.`name` as country'; - $this->_join = ' - LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (cl.`id_country` = a.`id_country` AND cl.`id_lang` = '.(int)$this->context->language->id.') - LEFT JOIN `'._DB_PREFIX_.'customer` c ON a.id_customer = c.id_customer - '; - $this->_where = 'AND a.id_customer != 0 '.Shop::addSqlRestriction(Shop::SHARE_CUSTOMER, 'c'); - - return parent::renderList(); - } public function renderForm() { diff --git a/controllers/admin/AdminCartsController.php b/controllers/admin/AdminCartsController.php index a0a85295e..9c8a0d299 100755 --- a/controllers/admin/AdminCartsController.php +++ b/controllers/admin/AdminCartsController.php @@ -35,6 +35,7 @@ class AdminCartsControllerCore extends AdminController $this->addRowAction('view'); $this->addRowAction('delete'); + $this->allow_export = true; $this->_select = 'CONCAT(LEFT(c.`firstname`, 1), \'. \', c.`lastname`) `customer`, a.id_cart total, ca.name carrier, o.id_order, IF(co.id_guest, 1, 0) id_guest'; $this->_join = 'LEFT JOIN '._DB_PREFIX_.'customer c ON (c.id_customer = a.id_customer) diff --git a/controllers/admin/AdminCategoriesController.php b/controllers/admin/AdminCategoriesController.php index 3b7bdec9b..175456f7c 100644 --- a/controllers/admin/AdminCategoriesController.php +++ b/controllers/admin/AdminCategoriesController.php @@ -45,6 +45,7 @@ class AdminCategoriesControllerCore extends AdminController $this->lang = true; $this->deleted = false; $this->explicitSelect = true; + $this->allow_export = true; $this->context = Context::getContext(); diff --git a/controllers/admin/AdminCustomersController.php b/controllers/admin/AdminCustomersController.php index 727df43ec..29855a5a8 100644 --- a/controllers/admin/AdminCustomersController.php +++ b/controllers/admin/AdminCustomersController.php @@ -42,6 +42,8 @@ class AdminCustomersControllerCore extends AdminController $this->deleted = true; $this->explicitSelect = true; + $this->allow_export = true; + $this->addRowAction('edit'); $this->addRowAction('view'); $this->addRowAction('delete'); diff --git a/controllers/admin/AdminManufacturersController.php b/controllers/admin/AdminManufacturersController.php index cae9b74ee..c20657521 100644 --- a/controllers/admin/AdminManufacturersController.php +++ b/controllers/admin/AdminManufacturersController.php @@ -35,6 +35,7 @@ class AdminManufacturersControllerCore extends AdminController $this->className = 'Manufacturer'; $this->lang = false; $this->deleted = false; + $this->allow_export = true; $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); diff --git a/controllers/admin/AdminMetaController.php b/controllers/admin/AdminMetaController.php index dfc09fa84..85cef7942 100644 --- a/controllers/admin/AdminMetaController.php +++ b/controllers/admin/AdminMetaController.php @@ -64,6 +64,13 @@ class AdminMetaControllerCore extends AdminController 'type' => 'rewriting_settings', 'mod_rewrite' => $mod_rewrite ), + 'PS_ALLOW_ACCENTED_CHARS_URL' => array( + 'title' => $this->l('Accented URL'), + 'desc' => $this->l('Enable if you want to allow accented characters in your friendly URLs.'), + 'validation' => 'isBool', + 'cast' => 'intval', + 'type' => 'bool' + ), 'PS_CANONICAL_REDIRECT' => array( 'title' => $this->l('Automatically redirect to the canonical URL.'), 'desc' => $this->l('Recommended, but your theme must be compliant.'), diff --git a/controllers/admin/AdminModulesController.php b/controllers/admin/AdminModulesController.php index b4d277280..675735b77 100644 --- a/controllers/admin/AdminModulesController.php +++ b/controllers/admin/AdminModulesController.php @@ -1072,6 +1072,12 @@ class AdminModulesControllerCore extends AdminController unset($object); } + // Don't display categories without modules + $cleaned_list = array(); + foreach ($this->list_modules_categories as $k => $list) + if ($list['nb'] > 0) + $cleaned_list[$k] = $list; + // Actually used for the report of the upgraded errors if (count($module_errors)) { @@ -1109,7 +1115,7 @@ class AdminModulesControllerCore extends AdminController $tpl_vars['nb_modules_uninstalled'] = $tpl_vars['nb_modules'] - $tpl_vars['nb_modules_installed']; $tpl_vars['nb_modules_activated'] = $this->nb_modules_activated; $tpl_vars['nb_modules_unactivated'] = $tpl_vars['nb_modules_installed'] - $tpl_vars['nb_modules_activated']; - $tpl_vars['list_modules_categories'] = $this->list_modules_categories; + $tpl_vars['list_modules_categories'] = $cleaned_list; $tpl_vars['list_modules_authors'] = $this->modules_authors; $tpl_vars['check_url_fopen'] = (ini_get('allow_url_fopen') ? 'ok' : 'ko'); diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index a3c5cf7e6..b41ebc079 100755 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -35,7 +35,7 @@ class AdminOrdersControllerCore extends AdminController $this->lang = false; $this->addRowAction('view'); $this->explicitSelect = true; - + $this->allow_export = true; $this->deleted = false; $this->context = Context::getContext(); diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 8a26749cb..c48f024e6 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -53,6 +53,8 @@ class AdminProductsControllerCore extends AdminController protected $position_identifier = 'id_product'; protected $submitted_tabs; + + protected $id_current_category; public function __construct() { @@ -71,6 +73,7 @@ class AdminProductsControllerCore extends AdminController $this->_defaultOrderBy = 'position'; $this->max_file_size = (int)(Configuration::get('PS_LIMIT_UPLOAD_FILE_VALUE') * 1000000); $this->max_image_size = (int)Configuration::get('PS_PRODUCT_PICTURE_MAX_SIZE'); + $this->allow_export = true; // @since 1.5 : translations for tabs $this->available_tabs_lang = array ( @@ -121,17 +124,28 @@ class AdminProductsControllerCore extends AdminController $this->available_tabs_lang['Module'.ucfirst($m['module'])] = Module::getModuleName($m['module']); } - + if (Tools::getValue('reset_filter_category')) + $this->context->cookie->id_category_products_filter = false; /* Join categories table */ if ($id_category = (int)Tools::getValue('productFilter_cl!name')) { $this->_category = new Category((int)$id_category); $_POST['productFilter_cl!name'] = $this->_category->name[$this->context->language->id]; } - elseif ($id_category = Tools::getvalue('id_category')) - $this->_category = new Category((int)$id_category); else - $this->_category = new Category(); + { + if ($id_category = (int)Tools::getValue('id_category')) + { + $this->id_current_category = $id_category; + $this->context->cookie->id_category_products_filter = $id_category; + } + elseif ($id_category = $this->context->cookie->id_category_products_filter) + $this->id_current_category = $id_category; + if ($this->id_current_category) + $this->_category = new Category((int)$this->id_current_category); + else + $this->_category = new Category(); + } $join_category = false; if (Validate::isLoadedObject($this->_category) && empty($this->_filter)) @@ -241,7 +255,8 @@ class AdminProductsControllerCore extends AdminController 'type' => 'bool', 'orderby' => false ); - if ((int)Tools::getValue('id_category')) + + if ((int)$this->id_current_category) $this->fields_list['position'] = array( 'title' => $this->l('Position'), 'width' => 70, @@ -2126,8 +2141,8 @@ class AdminProductsControllerCore extends AdminController } else { - if ($id_category = (int)Tools::getValue('id_category')) - self::$currentIndex .= '&id_category='.(int)$id_category; + if ($id_category = (int)$this->id_current_category) + self::$currentIndex .= '&id_category='.(int)$this->id_current_category; // If products from all categories are displayed, we don't want to use sorting by position if (!$id_category) @@ -2139,8 +2154,9 @@ class AdminProductsControllerCore extends AdminController unset($this->context->cookie->{$this->table.'Orderway'}); } } - $id_category = (int)Tools::getValue('id_category', 1); - $this->tpl_list_vars['is_category_filter'] = Tools::getValue('id_category') ? true : false; + if (!$id_category) + $id_category = 1; + $this->tpl_list_vars['is_category_filter'] = (bool)$this->id_current_category; // Generate category selection tree $helper = new Helper(); diff --git a/controllers/admin/AdminSuppliersController.php b/controllers/admin/AdminSuppliersController.php index b8644d642..95f9ebe4c 100644 --- a/controllers/admin/AdminSuppliersController.php +++ b/controllers/admin/AdminSuppliersController.php @@ -34,6 +34,8 @@ class AdminSuppliersControllerCore extends AdminController $this->addRowAction('view'); $this->addRowAction('edit'); $this->addRowAction('delete'); + $this->allow_export = true; + $this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?'))); $this->_select = 'COUNT(DISTINCT ps.`id_product`) AS products'; diff --git a/controllers/front/OrderController.php b/controllers/front/OrderController.php index de8de6ba5..49927ce98 100644 --- a/controllers/front/OrderController.php +++ b/controllers/front/OrderController.php @@ -340,19 +340,10 @@ class OrderControllerCore extends ParentOrderController parent::_assignCarrier(); // Assign wrapping and TOS $this->_assignWrappingAndTOS(); - - // If a rule offer free-shipping, force hidding shipping prices - $free_shipping = false; - foreach ($this->context->cart->getCartRules() as $rule) - if ($rule['free_shipping']) - { - $free_shipping = true; - break; - } - + $this->context->smarty->assign( array( - 'free_shipping' => $free_shipping, + 'free_shipping' => false, // Deprecated since a cart rule can be applied the specific carriers only 'is_guest' => (isset($this->context->customer->is_guest) ? $this->context->customer->is_guest : 0) )); } diff --git a/controllers/front/OrderOpcController.php b/controllers/front/OrderOpcController.php index 0098850b3..42254f911 100644 --- a/controllers/front/OrderOpcController.php +++ b/controllers/front/OrderOpcController.php @@ -480,15 +480,6 @@ class OrderOpcControllerCore extends ParentOrderController else $link_conditions .= '&content_only=1'; - // If a rule offer free-shipping, force hidding shipping prices - $free_shipping = false; - foreach ($this->context->cart->getCartRules() as $rule) - if ($rule['free_shipping']) - { - $free_shipping = true; - break; - } - $carriers = $this->context->cart->simulateCarriersOutput(); $delivery_option = $this->context->cart->getDeliveryOption(null, false, false); @@ -496,7 +487,7 @@ class OrderOpcControllerCore extends ParentOrderController $wrapping_fees_tax_inc = $wrapping_fees = $this->context->cart->getGiftWrappingPrice(); $vars = array( - 'free_shipping' => $free_shipping, + 'free_shipping' => false, // Deprecated since a cart rule can be applied the specific carriers only 'checkedTOS' => (int)($this->context->cookie->checkedTOS), 'recyclablePackAllowed' => (int)(Configuration::get('PS_RECYCLABLE_PACK')), 'giftAllowed' => (int)(Configuration::get('PS_GIFT_WRAPPING')), diff --git a/controllers/front/PageNotFoundController.php b/controllers/front/PageNotFoundController.php index 016362e1d..ebbf835c8 100644 --- a/controllers/front/PageNotFoundController.php +++ b/controllers/front/PageNotFoundController.php @@ -37,6 +37,16 @@ class PageNotFoundControllerCore extends FrontController { header('HTTP/1.1 404 Not Found'); header('Status: 404 Not Found'); + + if (in_array(Tools::strtolower(substr($_SERVER['REQUEST_URI'], -3)), array('png', 'jpg', 'gif'))) + { + header('Content-Type: image/gif'); + readfile(_PS_IMG_DIR_.'img/404.gif'); + exit; + } + elseif (in_array(Tools::strtolower(substr($_SERVER['REQUEST_URI'], -3)), array('.js', 'css'))) + exit; + parent::initContent(); $this->setTemplate(_PS_THEME_DIR_.'404.tpl'); diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index f5d9db5fd..b29b7e7cc 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -87,19 +87,11 @@ class ProductControllerCore extends FrontController { header('HTTP/1.1 404 Not Found'); header('Status: 404 Not Found'); + $this->errors[] = Tools::displayError('Product not found'); } - else - $this->canonicalRedirection(); - - if (!Validate::isLoadedObject($this->product)) - $this->errors[] = Tools::displayError('Product not found'); else { - if (Pack::isPack((int)$this->product->id) && !Pack::isInStock((int)$this->product->id)) - $this->product->quantity = 0; - - $this->product->description = $this->transformDescriptionWithImg($this->product->description); - + $this->canonicalRedirection(); /* * If the product is associated to the shop * and is active or not active but preview mode (need token + file_exists) @@ -181,11 +173,14 @@ class ProductControllerCore extends FrontController if (!$this->errors) { + if (Pack::isPack((int)$this->product->id) && !Pack::isInStock((int)$this->product->id)) + $this->product->quantity = 0; + + $this->product->description = $this->transformDescriptionWithImg($this->product->description); + // Assign to the template the id of the virtual product. "0" if the product is not downloadable. $this->context->smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int)$this->product->id)); - // Product pictures management - require_once('images.inc.php'); $this->context->smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI']))); if (Tools::isSubmit('submitCustomizedDatas')) @@ -204,15 +199,21 @@ class ProductControllerCore extends FrontController else if (Tools::getIsset('deletePicture') && !$this->context->cart->deleteCustomizationToProduct($this->product->id, Tools::getValue('deletePicture'))) $this->errors[] = Tools::displayError('An error occurred while deleting the selected picture'); - $files = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_FILE, true); + $pictures = array(); - foreach ($files as $file) - $pictures['pictures_'.$this->product->id.'_'.$file['index']] = $file['value']; - - $texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true); $text_fields = array(); - foreach ($texts as $text_field) - $text_fields['textFields_'.$this->product->id.'_'.$text_field['index']] = str_replace('
', "\n", $text_field['value']); + if ($this->product->customizable) + { + $files = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_FILE, true); + foreach ($files as $file) + $pictures['pictures_'.$this->product->id.'_'.$file['index']] = $file['value']; + + $texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true); + + foreach ($texts as $text_field) + $text_fields['textFields_'.$this->product->id.'_'.$text_field['index']] = str_replace('
', "\n", $text_field['value']); + } + $this->context->smarty->assign(array( 'pictures' => $pictures, 'textFields' => $text_fields)); diff --git a/install-dev/langs/fr/data/gender.xml b/install-dev/langs/fr/data/gender.xml index 2a62da434..56260b8c3 100644 --- a/install-dev/langs/fr/data/gender.xml +++ b/install-dev/langs/fr/data/gender.xml @@ -2,5 +2,5 @@ - + diff --git a/install-dev/theme/views/welcome.phtml b/install-dev/theme/views/welcome.phtml index da2f83d6e..cb5563181 100644 --- a/install-dev/theme/views/welcome.phtml +++ b/install-dev/theme/views/welcome.phtml @@ -101,11 +101,11 @@
- + session->licence_agrement): ?>checked="checked" /> +

- + session->configuration_agrement): ?>checked="checked" /> +
displayTemplate('footer') ?> \ No newline at end of file diff --git a/install-dev/upgrade/php/add_default_restrictions_modules_groups.php b/install-dev/upgrade/php/add_default_restrictions_modules_groups.php index abd1ae996..dd009061c 100644 --- a/install-dev/upgrade/php/add_default_restrictions_modules_groups.php +++ b/install-dev/upgrade/php/add_default_restrictions_modules_groups.php @@ -41,7 +41,7 @@ function add_default_restrictions_modules_groups() FROM `'._DB_PREFIX_.'shop`'); foreach ($groups as $group) { - if (!is_array($modules)) + if (!is_array($modules) || !is_array($shops)) return false; else { @@ -49,10 +49,10 @@ function add_default_restrictions_modules_groups() foreach ($modules as $mod) foreach ($shops as $s) $sql .= '("'.(int)$mod['id_module'].'", "'.(int)$s.'", "'.(int)$group['id_group'].'"),'; - // removing last comma to avoid SQL error - $sql = substr($sql, 0, strlen($sql) - 1); - $res &= Db::getInstance()->execute($sql); + // removing last comma to avoid SQL error + $sql = substr($sql, 0, strlen($sql) - 1); + $res &= Db::getInstance()->execute($sql); } } return $res; -} +} \ No newline at end of file diff --git a/install-dev/upgrade/php/generate_root_category_for_multishop.php b/install-dev/upgrade/php/generate_root_category_for_multishop.php index ddf6be28d..851572863 100644 --- a/install-dev/upgrade/php/generate_root_category_for_multishop.php +++ b/install-dev/upgrade/php/generate_root_category_for_multishop.php @@ -54,29 +54,35 @@ function generate_root_category_for_multishop() '); $data = array(); - foreach ($langs as $lang) - foreach ($shops as $shop) - $data[] = array( - 'id_lang' => $lang['id_lang'], - 'id_shop' => $shop['id_shop'], - 'id_category' => $id, - 'name' => 'Root', - 'link_rewrite' => '', - ); - Db::getInstance()->insert('category_lang', $data); + if(is_array($shops) && is_array($langs)) + { + foreach ($langs as $lang) + foreach ($shops as $shop) + $data[] = array( + 'id_lang' => $lang['id_lang'], + 'id_shop' => $shop['id_shop'], + 'id_category' => $id, + 'name' => 'Root', + 'link_rewrite' => '', + ); + Db::getInstance()->insert('category_lang', $data); + } $categories = Db::getInstance()->executeS(' SELECT `id_category` FROM `'._DB_PREFIX_.'category` '); $data = array(); - foreach ($categories as $category) - foreach ($shops as $shop) - $data[] = array( - 'id_category' => $category['id_category'], - 'id_shop' => $shop['id_shop'] - ); - Db::getInstance()->insert('category_shop', $data); + if(is_array($shops) && is_array($categories)) + { + foreach ($categories as $category) + foreach ($shops as $shop) + $data[] = array( + 'id_category' => $category['id_category'], + 'id_shop' => $shop['id_shop'] + ); + Db::getInstance()->insert('category_shop', $data); + } Db::getInstance()->execute(' UPDATE `'._DB_PREFIX_.'category` @@ -90,4 +96,4 @@ function generate_root_category_for_multishop() '); generate_ntree(); -} +} \ No newline at end of file diff --git a/install-dev/upgrade/php/p15012_add_missing_columns.php b/install-dev/upgrade/php/p15012_add_missing_columns.php index fcff0b101..8fb9569f9 100644 --- a/install-dev/upgrade/php/p15012_add_missing_columns.php +++ b/install-dev/upgrade/php/p15012_add_missing_columns.php @@ -160,22 +160,24 @@ function p15012_add_missing_columns() if (empty($table)) continue; $list_fields = $db->executeS('SHOW FIELDS FROM `'._DB_PREFIX_.$table.'`'); - foreach($list_fields as $k => $field) - $list_fields[$k] = $field['Field']; - foreach ($cols as $col => $q) - { - // do only if column exists - if (in_array($col, $list_fields)) - $do = 'mod'; - else - $do = 'add'; - - if (!empty($q[$do])) + if (is_array($list_fields)) + foreach($list_fields as $k => $field) + $list_fields[$k] = $field['Field']; + if (is_array($cols)) + foreach ($cols as $col => $q) { - if (!$db->execute($q[$do])) - $errors[] = ''.$q[$do].''.$db->getMsgError().''; + // do only if column exists + if (is_array($list_fields) && in_array($col, $list_fields)) + $do = 'mod'; + else + $do = 'add'; + + if (!empty($q[$do])) + { + if (!$db->execute($q[$do])) + $errors[] = ''.$q[$do].''.$db->getMsgError().''; + } } - } } if (sizeof($errors) > 0) @@ -185,5 +187,4 @@ function p15012_add_missing_columns() } else return true; -} - +} \ No newline at end of file diff --git a/install-dev/upgrade/sql/1.5.0.1.sql b/install-dev/upgrade/sql/1.5.0.1.sql index 883ce36bd..c3e62fe48 100644 --- a/install-dev/upgrade/sql/1.5.0.1.sql +++ b/install-dev/upgrade/sql/1.5.0.1.sql @@ -146,7 +146,7 @@ INSERT INTO `PREFIX_gender_lang` (`id_gender`, `id_lang`, `name`) VALUES (2, 4, 'Frau'), (2, 5, 'Sig.ra'), (3, 1, 'Miss'), -(3, 2, 'Melle'), +(3, 2, 'Mlle'), (3, 3, 'Miss'), (3, 4, 'Miss'), (3, 5, 'Miss'); diff --git a/themes/default/password.tpl b/themes/default/password.tpl index 2907784fd..fa2d0a51a 100644 --- a/themes/default/password.tpl +++ b/themes/default/password.tpl @@ -31,9 +31,9 @@ {include file="$tpl_dir./errors.tpl"} {if isset($confirmation) && $confirmation == 1} -

{l s='Your password has been successfully reset and a confirmation has been sent to your email address:'} {$smarty.post.email|escape:'htmlall':'UTF-8'|stripslashes}

+

{l s='Your password has been successfully reset and a confirmation has been sent to your email address:'} {if isset($email)}{$email|escape:'htmlall':'UTF-8'|stripslashes}{/if}

{elseif isset($confirmation) && $confirmation == 2} -

{l s='A confirmation email has been sent to your address:'} {$smarty.post.email|escape:'htmlall':'UTF-8'|stripslashes}

+

{l s='A confirmation email has been sent to your address:'} {if isset($email)}{$email|escape:'htmlall':'UTF-8'|stripslashes}{/if}

{else}

{l s='Please enter the email address you used to register. We will then send you a new password. '}

diff --git a/tools/profiling/Controller.php b/tools/profiling/Controller.php index 7011ea222..1b55dd0dd 100644 --- a/tools/profiling/Controller.php +++ b/tools/profiling/Controller.php @@ -387,7 +387,7 @@ abstract class Controller extends ControllerCore uasort($queries, 'prestashop_querytime_sort'); foreach ($queries as $data) { - echo $hr.'getTimeColor($data['time'] * 1000).'>'.round($data['time'] * 1000, 3).' ms '.$data['query'].'
in '.$data['file'].':'.$data['line'].'
'; + echo $hr.'getTimeColor($data['time'] * 1000).'>'.round($data['time'] * 1000, 3).' ms '.htmlspecialchars($data['query'], ENT_NOQUOTES, 'utf-8', false).'
in '.$data['file'].':'.$data['line'].'
'; if (preg_match('/^\s*select\s+/i', $data['query'])) { $explain = Db::getInstance()->executeS('explain '.$data['query']); diff --git a/tools/smarty/Smarty.class.php b/tools/smarty/Smarty.class.php index b8a10c5d0..40532fc2a 100644 --- a/tools/smarty/Smarty.class.php +++ b/tools/smarty/Smarty.class.php @@ -2,7 +2,7 @@ /** * Project: Smarty: the PHP compiling template engine * File: Smarty.class.php - * SVN: $Id: Smarty.class.php 4551 2012-02-06 20:45:10Z rodneyrehm $ + * SVN: $Id: Smarty.class.php 4694 2013-01-13 21:13:14Z uwe.tews@googlemail.com $ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ * @author Uwe Tews * @author Rodney Rehm * @package Smarty - * @version 3.1.8 + * @version 3.1.13 */ /** @@ -57,7 +57,7 @@ if (!defined('SMARTY_PLUGINS_DIR')) { define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); } if (!defined('SMARTY_MBSTRING')) { - define('SMARTY_MBSTRING', function_exists('mb_strlen')); + define('SMARTY_MBSTRING', function_exists('mb_split')); } if (!defined('SMARTY_RESOURCE_CHAR_SET')) { // UTF-8 can only be done properly when mbstring is available! @@ -113,7 +113,7 @@ class Smarty extends Smarty_Internal_TemplateBase { /** * smarty version */ - const SMARTY_VERSION = 'Smarty-3.1.8'; + const SMARTY_VERSION = 'Smarty-3.1.13'; /** * define variable scopes @@ -189,8 +189,12 @@ class Smarty extends Smarty_Internal_TemplateBase { * Flag denoting if PCRE should run in UTF-8 mode */ public static $_UTF8_MODIFIER = 'u'; - - + + /** + * Flag denoting if operating system is windows + */ + public static $_IS_WINDOWS = false; + /**#@+ * variables */ @@ -1277,7 +1281,7 @@ class Smarty extends Smarty_Internal_TemplateBase { } // plugin filename is expected to be: [type].[name].php $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; - + $_stream_resolve_include_path = function_exists('stream_resolve_include_path'); // loop through plugin dirs and find the plugin @@ -1298,7 +1302,7 @@ class Smarty extends Smarty_Internal_TemplateBase { } else { $file = Smarty_Internal_Get_Include_Path::getIncludePath($file); } - + if ($file !== false) { require_once($file); return $file; @@ -1388,10 +1392,12 @@ class Smarty extends Smarty_Internal_TemplateBase { // add the SMARTY_DIR to the list of muted directories if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { $smarty_dir = realpath(SMARTY_DIR); - Smarty::$_muted_directories[SMARTY_DIR] = array( - 'file' => $smarty_dir, - 'length' => strlen($smarty_dir), - ); + if ($smarty_dir !== false) { + Smarty::$_muted_directories[SMARTY_DIR] = array( + 'file' => $smarty_dir, + 'length' => strlen($smarty_dir), + ); + } } // walk the muted directories and test against $errfile @@ -1399,6 +1405,11 @@ class Smarty extends Smarty_Internal_TemplateBase { if (!$dir) { // resolve directory and length for speedy comparisons $file = realpath($key); + if ($file === false) { + // this directory does not exist, remove and skip it + unset(Smarty::$_muted_directories[$key]); + continue; + } $dir = array( 'file' => $file, 'length' => strlen($file), @@ -1464,6 +1475,9 @@ class Smarty extends Smarty_Internal_TemplateBase { } } +// Check if we're running on windows +Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN'; + // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 if (Smarty::$_CHARSET !== 'UTF-8') { Smarty::$_UTF8_MODIFIER = ''; @@ -1474,6 +1488,10 @@ if (Smarty::$_CHARSET !== 'UTF-8') { * @package Smarty */ class SmartyException extends Exception { + public static $escape = true; + public function __construct($message) { + $this->message = self::$escape ? htmlentities($message) : $message; + } } /** @@ -1502,8 +1520,8 @@ function smartyAutoload($class) 'smarty_resource_recompiled' => true, ); - if (preg_match('/^[0-9a-z_-]+$/i', $_class) && !strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { - include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; + if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { + include SMARTY_SYSPLUGINS_DIR . $_class . '.php'; } } diff --git a/tools/smarty/plugins/function.html_checkboxes.php b/tools/smarty/plugins/function.html_checkboxes.php index fb9584bbd..1866bc2f3 100644 --- a/tools/smarty/plugins/function.html_checkboxes.php +++ b/tools/smarty/plugins/function.html_checkboxes.php @@ -116,6 +116,23 @@ function smarty_function_html_checkboxes($params, $template) case 'assign': break; + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + default: if(!is_array($_val)) { $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; diff --git a/tools/smarty/plugins/function.html_options.php b/tools/smarty/plugins/function.html_options.php index 86266e269..68fa0524a 100644 --- a/tools/smarty/plugins/function.html_options.php +++ b/tools/smarty/plugins/function.html_options.php @@ -90,7 +90,24 @@ function smarty_function_html_options($params, $template) $selected = smarty_function_escape_special_chars((string) $_val); } break; - + + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + default: if (!is_array($_val)) { $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; @@ -150,6 +167,8 @@ function smarty_function_html_options_optoutput($key, $value, $selected, $id, $c trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); return ''; } + } else { + $value = smarty_function_escape_special_chars((string) $value); } $_html_result .= $_html_class . $_html_id . '>' . $value . '' . "\n"; $idx++; diff --git a/tools/smarty/plugins/function.html_radios.php b/tools/smarty/plugins/function.html_radios.php index 7c830724a..a2741f68f 100644 --- a/tools/smarty/plugins/function.html_radios.php +++ b/tools/smarty/plugins/function.html_radios.php @@ -102,6 +102,23 @@ function smarty_function_html_radios($params, $template) case 'assign': break; + case 'strict': break; + + case 'disabled': + case 'readonly': + if (!empty($params['strict'])) { + if (!is_scalar($_val)) { + trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE); + } + + if ($_val === true || $_val === $_key) { + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"'; + } + + break; + } + // omit break; to fall through! + default: if (!is_array($_val)) { $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; diff --git a/tools/smarty/plugins/modifier.date_format.php b/tools/smarty/plugins/modifier.date_format.php index 3cca7d395..f3eaba057 100644 --- a/tools/smarty/plugins/modifier.date_format.php +++ b/tools/smarty/plugins/modifier.date_format.php @@ -35,7 +35,7 @@ function smarty_modifier_date_format($string, $format=null, $default_date='', $f * Include the {@link shared.make_timestamp.php} plugin */ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); - if ($string != '') { + if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') { $timestamp = smarty_make_timestamp($string); } elseif ($default_date != '') { $timestamp = smarty_make_timestamp($default_date); diff --git a/tools/smarty/plugins/modifier.escape.php b/tools/smarty/plugins/modifier.escape.php index 680bcfe3f..70876293d 100644 --- a/tools/smarty/plugins/modifier.escape.php +++ b/tools/smarty/plugins/modifier.escape.php @@ -21,38 +21,76 @@ * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities() * @return string escaped input string */ -function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) +/* PrestaShop +change double_encode to false by default +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) +*/ +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = false) +/* END */ { + static $_double_encode = null; + if ($_double_encode === null) { + $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>='); + } + if (!$char_set) { $char_set = Smarty::$_CHARSET; } switch ($esc_type) { case 'html': -/* PrestaShop - return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); - */ - return htmlspecialchars($string, ENT_QUOTES, $char_set); - /* END */ + if ($_double_encode) { + // php >=5.3.2 - go native + return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); + } else { + if ($double_encode) { + // php <5.2.3 - only handle double encoding + return htmlspecialchars($string, ENT_QUOTES, $char_set); + } else { + // php <5.2.3 - prevent double encoding + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlspecialchars($string, ENT_QUOTES, $char_set); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + return $string; + } + } case 'htmlall': if (Smarty::$_MBSTRING) { // mb_convert_encoding ignores htmlspecialchars() - /* PrestaShop - return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); - */ - return htmlspecialchars($string, ENT_QUOTES, $char_set); - /* END */ + if ($_double_encode) { + // php >=5.3.2 - go native + $string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); + } else { + if ($double_encode) { + // php <5.2.3 - only handle double encoding + $string = htmlspecialchars($string, ENT_QUOTES, $char_set); + } else { + // php <5.2.3 - prevent double encoding + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlspecialchars($string, ENT_QUOTES, $char_set); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + return $string; + } + } + // htmlentities() won't convert everything, so use mb_convert_encoding return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set); } // no MBString fallback - /* PrestaShop - return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); - */ - return htmlentities($string, ENT_QUOTES, $char_set); - /* END */ + if ($_double_encode) { + return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); + } else { + if ($double_encode) { + return htmlentities($string, ENT_QUOTES, $char_set); + } else { + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlentities($string, ENT_QUOTES, $char_set); + $string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string); + return $string; + } + } case 'url': return rawurlencode($string); @@ -152,4 +190,4 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ } } -?> \ No newline at end of file +?> diff --git a/tools/smarty/plugins/modifiercompiler.escape.php b/tools/smarty/plugins/modifiercompiler.escape.php index b4f1f6638..f50028bd9 100644 --- a/tools/smarty/plugins/modifiercompiler.escape.php +++ b/tools/smarty/plugins/modifiercompiler.escape.php @@ -25,6 +25,11 @@ require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' ); */ function smarty_modifiercompiler_escape($params, $compiler) { + static $_double_encode = null; + if ($_double_encode === null) { + $_double_encode = version_compare(PHP_VERSION, '5.2.3', '>='); + } + try { $esc_type = smarty_literal_compiler_param($params, 1, 'html'); $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET); @@ -36,48 +41,56 @@ function smarty_modifiercompiler_escape($params, $compiler) switch ($esc_type) { case 'html': - /* PrestaShop - return 'htmlspecialchars(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ', ' - . var_export($double_encode, true) . ')'; - */ - return 'htmlspecialchars(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ')'; - /* END */ - - case 'htmlall': - /* PrestaShop - if (Smarty::$_MBSTRING) { - return 'mb_convert_encoding(htmlspecialchars(' + if ($_double_encode) { + return 'htmlspecialchars(' . $params[0] .', ENT_QUOTES, ' . var_export($char_set, true) . ', ' - . var_export($double_encode, true) - . '), "HTML-ENTITIES", ' - . var_export($char_set, true) . ')'; - } - */ - if (Smarty::$_MBSTRING) { - return 'mb_convert_encoding(htmlspecialchars(' + . var_export($double_encode, true) . ')'; + } else if ($double_encode) { + return 'htmlspecialchars(' . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) - . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')'; + } else { + // fall back to modifier.escape.php + } + + case 'htmlall': + if (Smarty::$_MBSTRING) { + if ($_double_encode) { + // php >=5.2.3 - go native + return 'mb_convert_encoding(htmlspecialchars(' + . $params[0] .', ENT_QUOTES, ' + . var_export($char_set, true) . ', ' + . var_export($double_encode, true) + . '), "HTML-ENTITIES", ' + . var_export($char_set, true) . ')'; + } else if ($double_encode) { + // php <5.2.3 - only handle double encoding + return 'mb_convert_encoding(htmlspecialchars(' + . $params[0] .', ENT_QUOTES, ' + . var_export($char_set, true) + . '), "HTML-ENTITIES", ' + . var_export($char_set, true) . ')'; + } else { + // fall back to modifier.escape.php + } } - /* END */ // no MBString fallback - /* PrestaShop - return 'htmlentities(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ', ' - . var_export($double_encode, true) . ')'; - */ - return 'htmlentities(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ')'; - /* END */ + if ($_double_encode) { + // php >=5.2.3 - go native + return 'htmlentities(' + . $params[0] .', ENT_QUOTES, ' + . var_export($char_set, true) . ', ' + . var_export($double_encode, true) . ')'; + } else if ($double_encode) { + // php <5.2.3 - only handle double encoding + return 'htmlentities(' + . $params[0] .', ENT_QUOTES, ' + . var_export($char_set, true) . ')'; + } else { + // fall back to modifier.escape.php + } case 'url': return 'rawurlencode(' . $params[0] . ')'; diff --git a/tools/smarty/plugins/outputfilter.trimwhitespace.php b/tools/smarty/plugins/outputfilter.trimwhitespace.php index 31a75557c..87cf8c781 100644 --- a/tools/smarty/plugins/outputfilter.trimwhitespace.php +++ b/tools/smarty/plugins/outputfilter.trimwhitespace.php @@ -40,6 +40,7 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s } // Strip all HTML-Comments + // yes, even the ones in