diff --git a/admin-dev/themes/default/template/controllers/modules_positions/form.tpl b/admin-dev/themes/default/template/controllers/modules_positions/form.tpl index 608833654..ebd8d9dbc 100644 --- a/admin-dev/themes/default/template/controllers/modules_positions/form.tpl +++ b/admin-dev/themes/default/template/controllers/modules_positions/form.tpl @@ -44,7 +44,7 @@
*
diff --git a/admin-dev/themes/default/template/controllers/orders/_product_line.tpl b/admin-dev/themes/default/template/controllers/orders/_product_line.tpl index 4453470c8..6519dadaf 100755 --- a/admin-dev/themes/default/template/controllers/orders/_product_line.tpl +++ b/admin-dev/themes/default/template/controllers/orders/_product_line.tpl @@ -135,7 +135,7 @@ {if sizeof($invoices_collection)} {else} diff --git a/admin-dev/themes/default/template/controllers/orders/form.tpl b/admin-dev/themes/default/template/controllers/orders/form.tpl index 7e1138ca0..e6179ea30 100755 --- a/admin-dev/themes/default/template/controllers/orders/form.tpl +++ b/admin-dev/themes/default/template/controllers/orders/form.tpl @@ -300,7 +300,7 @@ id_product: id_product, id_product_attribute: id_product_attribute, id_customer: id_customer, - price: new_price + price: new Number(new_price.replace(",",".")).toFixed(4).toString() }, success : function(res) { diff --git a/classes/Cart.php b/classes/Cart.php index 792c0d490..9b0b477e4 100644 --- a/classes/Cart.php +++ b/classes/Cart.php @@ -1331,6 +1331,9 @@ class CartCore extends ObjectModel else $shipping_fees = 0; + if ($type == Cart::ONLY_SHIPPING) + return $shipping_fees; + if ($type == Cart::ONLY_PRODUCTS_WITHOUT_SHIPPING) $type = Cart::ONLY_PRODUCTS; @@ -1455,12 +1458,14 @@ class CartCore extends ObjectModel $wrapping_fees = 0; if ($this->gift) $wrapping_fees = Tools::convertPrice(Tools::ps_round($this->getGiftWrappingPrice($with_taxes), 2), Currency::getCurrencyInstance((int)$this->id_currency)); + if ($type == Cart::ONLY_WRAPPING) + return $wrapping_fees; $order_total_discount = 0; if (!in_array($type, array(Cart::ONLY_SHIPPING, Cart::ONLY_PRODUCTS)) && CartRule::isFeatureActive()) { // First, retrieve the cart rules associated to this "getOrderTotal" - if ($with_shipping) + if ($with_shipping || $type == Cart::ONLY_DISCOUNTS) $cart_rules = $this->getCartRules(CartRule::FILTER_ACTION_ALL); else { @@ -1486,7 +1491,7 @@ class CartCore extends ObjectModel foreach ($cart_rules as $cart_rule) { // If the cart rule offers free shipping, add the shipping cost - if ($with_shipping && $cart_rule['obj']->free_shipping) + if (($with_shipping || $type == Cart::ONLY_DISCOUNTS) && $cart_rule['obj']->free_shipping) $order_total_discount += Tools::ps_round($cart_rule['obj']->getContextualValue($with_taxes, $virtual_context, CartRule::FILTER_ACTION_SHIPPING, ($param_product ? $package : null), $use_cache), 2); // If the cart rule is a free gift, then add the free gift value only if the gift is in this package @@ -1512,12 +1517,6 @@ class CartCore extends ObjectModel $order_total -= $order_total_discount; } - if ($type == Cart::ONLY_SHIPPING) - return $shipping_fees; - - if ($type == Cart::ONLY_WRAPPING) - return $wrapping_fees; - if ($type == Cart::BOTH) $order_total += $shipping_fees + $wrapping_fees; @@ -2837,8 +2836,8 @@ class CartCore extends ObjectModel $invoice = new Address((int)$this->id_address_invoice); // New layout system with personalization fields + $formatted_addresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery); $formatted_addresses['invoice'] = AddressFormat::getFormattedLayoutData($invoice); - $formatted_addresses['delivery'] = AddressFormat::getFormattedLayoutData($delivery); $total_tax = $this->getOrderTotal() - $this->getOrderTotal(false); diff --git a/classes/CartRule.php b/classes/CartRule.php index b0f7fd4a5..2495155e7 100644 --- a/classes/CartRule.php +++ b/classes/CartRule.php @@ -31,6 +31,7 @@ class CartRuleCore extends ObjectModel const FILTER_ACTION_SHIPPING = 2; const FILTER_ACTION_REDUCTION = 3; const FILTER_ACTION_GIFT = 4; + const FILTER_ACTION_ALL_NOCAP = 5; const BO_ORDER_CODE_PREFIX = 'BO_ORDER_'; @@ -119,14 +120,20 @@ class CartRuleCore extends ObjectModel /** * @see ObjectModel::add() */ - public function add($autodate = true, $nullValues = false) + public function add($autodate = true, $null_values = false) { - if (!parent::add($autodate, $nullValues)) + if (!parent::add($autodate, $null_values)) return false; Configuration::updateGlobalValue('PS_CART_RULE_FEATURE_ACTIVE', '1'); return true; } + + public function update($null_values = false) + { + Cache::clean('getContextualValue_'.$this->id.'_*'); + return parent::update($null_values); + } /** * @see ObjectModel::delete() @@ -216,27 +223,26 @@ class CartRuleCore extends ObjectModel FROM `'._DB_PREFIX_.'cart_rule` cr LEFT JOIN `'._DB_PREFIX_.'cart_rule_lang` crl ON (cr.`id_cart_rule` = crl.`id_cart_rule` AND crl.`id_lang` = '.(int)$id_lang.') WHERE ( - cr.`id_customer` = '.(int)$id_customer.' + cr.`id_customer` = '.(int)$id_customer.' OR cr.group_restriction = 1 '.($includeGeneric ? 'OR cr.`id_customer` = 0' : '').' ) + AND cr.date_from < "'.date('Y-m-d H:i:s').'" + AND cr.date_to > "'.date('Y-m-d H:i:s').'" '.($active ? 'AND cr.`active` = 1' : '').' '.($inStock ? 'AND cr.`quantity` > 0' : '')); // Remove cart rule that does not match the customer groups - if ($includeGeneric) - { - $customerGroups = Customer::getGroupsStatic($id_customer); - foreach ($result as $key => $cart_rule) - if ($cart_rule['group_restriction']) - { - $cartRuleGroups = Db::getInstance()->getValue('SELECT id_group FROM '._DB_PREFIX_.'cart_rule_group WHERE id_cart_rule = '.(int)$cart_rule['id_cart_rule']); - foreach ($cartRuleGroups as $cartRuleGroup) - if (in_array($cartRuleGroups['id_group'], $customerGroups)) - continue 2; + $customerGroups = Customer::getGroupsStatic($id_customer); + foreach ($result as $key => $cart_rule) + if ($cart_rule['group_restriction']) + { + $cartRuleGroups = Db::getInstance()->executeS('SELECT id_group FROM '._DB_PREFIX_.'cart_rule_group WHERE id_cart_rule = '.(int)$cart_rule['id_cart_rule']); + foreach ($cartRuleGroups as $cartRuleGroup) + if (in_array($cartRuleGroup['id_group'], $customerGroups)) + continue 2; - unset($result[$key]); - } - } + unset($result[$key]); + } foreach ($result as &$cart_rule) if ($cart_rule['quantity_per_user']) @@ -749,7 +755,7 @@ class CartRuleCore extends ObjectModel return Cache::retrieve($cache_id); // Free shipping on selected carriers - if ($this->free_shipping && ($filter == CartRule::FILTER_ACTION_ALL || $filter == CartRule::FILTER_ACTION_SHIPPING)) + if ($this->free_shipping && in_array($filter, array(CartRule::FILTER_ACTION_ALL, CartRule::FILTER_ACTION_ALL_NOCAP, CartRule::FILTER_ACTION_SHIPPING))) { if (!$this->carrier_restriction) $reduction_value += $context->cart->getOrderTotal($use_tax, Cart::ONLY_SHIPPING, is_null($package) ? null : $package['products'], is_null($package) ? null : $package['id_carrier']); @@ -767,7 +773,7 @@ class CartRuleCore extends ObjectModel } } - if ($filter == CartRule::FILTER_ACTION_ALL || $filter == CartRule::FILTER_ACTION_REDUCTION) + if (in_array($filter, array(CartRule::FILTER_ACTION_ALL, CartRule::FILTER_ACTION_ALL_NOCAP, CartRule::FILTER_ACTION_REDUCTION))) { // Discount (%) on the whole order if ($this->reduction_percent && $this->reduction_product == 0) @@ -858,7 +864,15 @@ class CartRuleCore extends ObjectModel // If it has the same tax application that you need, then it's the right value, whatever the product! if ($this->reduction_tax == $use_tax) + { + // The reduction cannot exceed the products total, except when we do not want it to be limited (for the partial use calculation) + if ($filter != CartRule::FILTER_ACTION_ALL_NOCAP) + { + $cart_amount = $context->cart->getOrderTotal($use_tax, Cart::ONLY_PRODUCTS); + $reduction_amount = min($reduction_amount, $cart_amount); + } $reduction_value += $prorata * $reduction_amount; + } else { if ($this->reduction_product > 0) @@ -884,9 +898,12 @@ class CartRuleCore extends ObjectModel // Discount (¤) on the whole order elseif ($this->reduction_product == 0) { - // TODO : this should not use the prorata $cart_amount_ti = $context->cart->getOrderTotal(true, Cart::ONLY_PRODUCTS); $cart_amount_te = $context->cart->getOrderTotal(false, Cart::ONLY_PRODUCTS); + + // The reduction cannot exceed the products total, except when we do not want it to be limited (for the partial use calculation) + if ($filter != CartRule::FILTER_ACTION_ALL_NOCAP) + $reduction_amount = min($reduction_amount, $this->reduction_tax ? $cart_amount_ti : $cart_amount_te); $cart_vat_amount = $cart_amount_ti - $cart_amount_te; @@ -911,7 +928,7 @@ class CartRuleCore extends ObjectModel } // Free gift - if ((int)$this->gift_product && ($filter == CartRule::FILTER_ACTION_ALL || $filter == CartRule::FILTER_ACTION_GIFT)) + if ((int)$this->gift_product && in_array($filter, array(CartRule::FILTER_ACTION_ALL, CartRule::FILTER_ACTION_ALL_NOCAP, CartRule::FILTER_ACTION_GIFT))) { $id_address = (is_null($package) ? 0 : $package['id_address']); foreach ($package_products as $product) diff --git a/classes/Customer.php b/classes/Customer.php index ef3ab32df..f8a01c5ce 100644 --- a/classes/Customer.php +++ b/classes/Customer.php @@ -412,16 +412,17 @@ class CustomerCore extends ObjectModel */ public static function customerHasAddress($id_customer, $id_address) { - if (!array_key_exists($id_customer, self::$_customerHasAddress)) + $key = (int)$id_customer.'-'.(int)$id_address; + if (!array_key_exists($id_address, self::$_customerHasAddress)) { - self::$_customerHasAddress[$id_customer] = (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' + self::$_customerHasAddress[$key] = (bool)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue(' SELECT `id_address` FROM `'._DB_PREFIX_.'address` WHERE `id_customer` = '.(int)$id_customer.' AND `id_address` = '.(int)$id_address.' AND `deleted` = 0'); } - return self::$_customerHasAddress[$id_customer]; + return self::$_customerHasAddress[$key]; } public static function resetAddressCache($id_customer) @@ -438,13 +439,14 @@ class CustomerCore extends ObjectModel */ public function getAddresses($id_lang) { - $sql = 'SELECT a.*, cl.`name` AS country, s.name AS state, s.iso_code AS state_iso + $sql = 'SELECT DISTINCT a.*, cl.`name` AS country, s.name AS state, s.iso_code AS state_iso FROM `'._DB_PREFIX_.'address` a LEFT JOIN `'._DB_PREFIX_.'country` c ON (a.`id_country` = c.`id_country`) LEFT JOIN `'._DB_PREFIX_.'country_lang` cl ON (c.`id_country` = cl.`id_country`) LEFT JOIN `'._DB_PREFIX_.'state` s ON (s.`id_state` = a.`id_state`) '.(Context::getContext()->shop->getGroup()->share_order ? '' : Shop::addSqlAssociation('country', 'c')).' WHERE `id_lang` = '.(int)$id_lang.' AND `id_customer` = '.(int)$this->id.' AND a.`deleted` = 0'; + return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS($sql); } diff --git a/classes/Dispatcher.php b/classes/Dispatcher.php index 000037882..a0381064c 100644 --- a/classes/Dispatcher.php +++ b/classes/Dispatcher.php @@ -468,7 +468,7 @@ class DispatcherCore if ($keywords) { $transform_keywords = array(); - preg_match_all('#\\\{(([^{}]+)\\\:)?('.implode('|', array_keys($keywords)).')(\\\:([^{}]+))?\\\}#', $regexp, $m); + preg_match_all('#\\\{(([^{}]*)\\\:)?('.implode('|', array_keys($keywords)).')(\\\:([^{}]*))?\\\}#', $regexp, $m); for ($i = 0, $total = count($m[0]); $i < $total; $i++) { $prepend = $m[2][$i]; @@ -537,7 +537,7 @@ class DispatcherCore if (!isset($this->routes[$id_lang]) && !isset($this->routes[$id_lang][$route_id])) return false; - return preg_match('#\{([^{}]+:)?'.preg_quote($keyword, '#').'(:[^{}])?\}#', $this->routes[$id_lang][$route_id]['rule']); + return preg_match('#\{([^{}]*:)?'.preg_quote($keyword, '#').'(:[^{}]*)?\}#', $this->routes[$id_lang][$route_id]['rule']); } /** @@ -554,7 +554,7 @@ class DispatcherCore return false; foreach ($this->default_routes[$route_id]['keywords'] as $keyword => $data) - if (isset($data['param']) && !preg_match('#\{([^{}]+:)?'.$keyword.'(:[^{}])?\}#', $rule)) + if (isset($data['param']) && !preg_match('#\{([^{}]*:)?'.$keyword.'(:[^{}]*)?\}#', $rule)) $errors[] = $keyword; return (count($errors)) ? false : true; @@ -614,10 +614,10 @@ class DispatcherCore $replace = $route['keywords'][$key]['prepend'].$params[$key].$route['keywords'][$key]['append']; else $replace = ''; - $url = preg_replace('#\{([^{}]+:)?'.$key.'(:[^{}])?\}#', $replace, $url); + $url = preg_replace('#\{([^{}]*:)?'.$key.'(:[^{}]*)?\}#', $replace, $url); } } - $url = preg_replace('#\{([^{}]+:)?[a-z0-9_]+?(:[^{}])?\}#', '', $url); + $url = preg_replace('#\{([^{}]*:)?[a-z0-9_]+?(:[^{}]*)?\}#', '', $url); if (count($add_param)) $url .= '?'.http_build_query($add_param, '', '&'); } diff --git a/classes/Hook.php b/classes/Hook.php index 7a5349522..1ad1b4ca3 100644 --- a/classes/Hook.php +++ b/classes/Hook.php @@ -98,7 +98,7 @@ class HookCore extends ObjectModel return Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' SELECT * FROM `'._DB_PREFIX_.'hook` h '.($position ? 'WHERE h.`position` = 1' : '').' - ORDER BY `title`' + ORDER BY `name`' ); } diff --git a/classes/ImageManager.php b/classes/ImageManager.php index cc89349f8..257c3356c 100644 --- a/classes/ImageManager.php +++ b/classes/ImageManager.php @@ -119,7 +119,10 @@ class ImageManagerCore */ public static function resize($src_file, $dst_file, $dst_width = null, $dst_height = null, $file_type = 'jpg', $force_type = false) { - clearstatcache(true, $src_file); + if (PHP_VERSION_ID < 50300) + clearstatcache(); + else + clearstatcache(true, $src_file); if (!file_exists($src_file) || !filesize($src_file)) return false; diff --git a/classes/Media.php b/classes/Media.php index eb1c574e9..7e2802c00 100755 --- a/classes/Media.php +++ b/classes/Media.php @@ -32,7 +32,7 @@ class MediaCore 'ui.mouse' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget'), 'theme' => false), 'ui.position' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array(), 'theme' => false), 'ui.draggable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => false), - 'ui.droppable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('uicore', 'ui.widget', 'ui.mouse', 'ui.draggable'), 'theme' => false), + 'ui.droppable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse', 'ui.draggable'), 'theme' => false), 'ui.resizable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true), 'ui.selectable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true), 'ui.sortable' => array('fileName' => 'jquery.ui.mouse.min.js', 'dependencies' => array('ui.core', 'ui.widget', 'ui.mouse'), 'theme' => true), @@ -539,4 +539,4 @@ class MediaCore return array_merge(array($protocol_link.Tools::getMediaServer($url).$url), $js_external_files); } -} \ No newline at end of file +} diff --git a/classes/PaymentModule.php b/classes/PaymentModule.php index b42b70f3a..2b56a4846 100644 --- a/classes/PaymentModule.php +++ b/classes/PaymentModule.php @@ -406,8 +406,8 @@ abstract class PaymentModuleCore extends Module { $package = array('id_carrier' => $order->id_carrier, 'id_address' => $order->id_address_delivery, 'products' => $order->product_list); $values = array( - 'tax_incl' => $cart_rule['obj']->getContextualValue(true, $this->context, CartRule::FILTER_ACTION_ALL, $package), - 'tax_excl' => $cart_rule['obj']->getContextualValue(false, $this->context, CartRule::FILTER_ACTION_ALL, $package) + 'tax_incl' => $cart_rule['obj']->getContextualValue(true, $this->context, CartRule::FILTER_ACTION_ALL_NOCAP, $package), + 'tax_excl' => $cart_rule['obj']->getContextualValue(false, $this->context, CartRule::FILTER_ACTION_ALL_NOCAP, $package) ); // If the reduction is not applicable to this order, then continue with the next one @@ -469,7 +469,7 @@ abstract class PaymentModuleCore extends Module $values['tax_excl'] -= $values['tax_excl'] - $order->total_products; } - $order->addCartRule($cart_rule['obj']->id, $cart_rule['obj']->name, $values); + $order->addCartRule($cart_rule['obj']->id, $cart_rule['obj']->name, $values, 0, $cart_rule['obj']->free_shipping); if ($id_order_state != Configuration::get('PS_OS_ERROR') && $id_order_state != Configuration::get('PS_OS_CANCELED') && !in_array($cart_rule['obj']->id, $cart_rule_used)) { @@ -616,7 +616,7 @@ abstract class PaymentModuleCore extends Module { $pdf = new PDF($order->getInvoicesCollection(), PDF::TEMPLATE_INVOICE, $this->context->smarty); $file_attachement['content'] = $pdf->render(false); - $file_attachement['name'] = Configuration::get('PS_INVOICE_PREFIX', (int)$order->id_lang).sprintf('%06d', $order->invoice_number).'.pdf'; + $file_attachement['name'] = Configuration::get('PS_INVOICE_PREFIX', (int)$order->id_lang, null, $order->id_shop).sprintf('%06d', $order->invoice_number).'.pdf'; $file_attachement['mime'] = 'application/pdf'; } else diff --git a/classes/Product.php b/classes/Product.php index 0f0c85f65..d76a1ac3a 100644 --- a/classes/Product.php +++ b/classes/Product.php @@ -902,7 +902,7 @@ class ProductCore extends ObjectModel ); $return = Db::getInstance()->delete('category_product', 'id_product = '.(int)$this->id); - if ($clean_positions === true) + if ($clean_positions === true && is_array($result)) foreach ($result as $row) $return &= $this->cleanPositions((int)$row['id_category']); @@ -4951,7 +4951,7 @@ class ProductCore extends ObjectModel { $query->from('product_attribute', 'pa'); $query->join(Shop::addSqlAssociation('product_attribute', 'pa')); - $query->innerJoin('product_lang', 'pl', 'pl.id_product = pa.id_product AND pl.id_lang = '.(int)$id_lang); + $query->innerJoin('product_lang', 'pl', 'pl.id_product = pa.id_product AND pl.id_lang = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl')); $query->leftJoin('product_attribute_combination', 'pac', 'pac.id_product_attribute = pa.id_product_attribute'); $query->leftJoin('attribute', 'atr', 'atr.id_attribute = pac.id_attribute'); $query->leftJoin('attribute_lang', 'al', 'al.id_attribute = atr.id_attribute AND al.id_lang = '.(int)$id_lang); @@ -4962,6 +4962,7 @@ class ProductCore extends ObjectModel { $query->from('product_lang', 'pl'); $query->where('pl.id_product = '.(int)$id_product); + $query->where('pl.id_lang = '.(int)$id_lang.Shop::addSqlRestrictionOnLang('pl')); } return Db::getInstance()->getValue($query); diff --git a/classes/Tools.php b/classes/Tools.php index 3f8788106..a6e4b3118 100644 --- a/classes/Tools.php +++ b/classes/Tools.php @@ -1277,10 +1277,9 @@ class ToolsCore public static function file_get_contents($url, $use_include_path = false, $stream_context = null, $curl_timeout = 5) { - if ($stream_context == null) - $stream_context = @stream_context_create(array('http' => array('timeout' => 5))); - - if (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1'))) + if ($stream_context == null && !preg_match('/^https?:\/\//', $url)) + $stream_context = @stream_context_create(array('http' => array('timeout' => $curl_timeout))); + if (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1')) || !preg_match('/^https?:\/\//', $url)) return @file_get_contents($url, $use_include_path, $stream_context); elseif (function_exists('curl_init')) { @@ -1289,6 +1288,16 @@ class ToolsCore curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $curl_timeout); curl_setopt($curl, CURLOPT_TIMEOUT, $curl_timeout); + $opts = stream_context_get_options($stream_context); + if (isset($opts['http']['method']) && Tools::strtolower($opts['http']['method']) == 'post') + { + curl_setopt($curl, CURLOPT_POST, true); + if (isset($opts['http']['content'])) + { + parse_str($opts['http']['content'], $datas); + curl_setopt($curl, CURLOPT_POSTFIELDS, $datas); + } + } $content = curl_exec($curl); curl_close($curl); return $content; @@ -1299,10 +1308,7 @@ class ToolsCore public static function simplexml_load_file($url, $class_name = null) { - if (in_array(ini_get('allow_url_fopen'), array('On', 'on', '1'))) - return @simplexml_load_string(Tools::file_get_contents($url), $class_name); - else - return false; + return @simplexml_load_string(Tools::file_get_contents($url), $class_name); } @@ -1535,6 +1541,18 @@ class ToolsCore 'virtual' => $shop_url->virtual_uri, 'id_shop' => $shop_url->id_shop ); + + if ($shop_url->domain == $shop_url->domain_ssl) + continue; + + if (!isset($domains[$shop_url->domain_ssl])) + $domains[$shop_url->domain_ssl] = array(); + + $domains[$shop_url->domain_ssl][] = array( + 'physical' => $shop_url->physical_uri, + 'virtual' => $shop_url->virtual_uri, + 'id_shop' => $shop_url->id_shop + ); } // Write data in .htaccess file diff --git a/classes/cache/CacheMemcache.php b/classes/cache/CacheMemcache.php index 543a7e797..99ef0ee92 100755 --- a/classes/cache/CacheMemcache.php +++ b/classes/cache/CacheMemcache.php @@ -46,26 +46,33 @@ class CacheMemcacheCore extends Cache // Get keys (this code comes from Doctrine 2 project) $this->keys = array(); - $all_slabs = $this->memcache->getExtendedStats('slabs'); - - foreach ($all_slabs as $server => $slabs) - { - if (is_array($slabs)) - { - foreach (array_keys($slabs) as $slab_id) - { - $dump = $this->memcache->getExtendedStats('cachedump', (int)$slab_id); - if ($dump) - { - foreach ($dump as $entries) - { - if ($entries) - $this->keys = array_merge($this->keys, array_keys($entries)); - } - } - } - } - } + $servers = self::getMemcachedServers(); + + if(is_array($servers) && count($servers) > 0 && method_exists('Memcache', 'getStats')) + $all_slabs = $this->memcache->getStats('slabs'); + + if(isset($all_slabs) && is_array($all_slabs)) + foreach ($all_slabs as $server => $slabs) + { + if (is_array($slabs)) + { + foreach (array_keys($slabs) as $slab_id) + { + if(is_int($slab_id)) + { + $dump = $this->memcache->getStats('cachedump', (int)$slab_id); + if ($dump) + { + foreach ($dump as $entries) + { + if ($entries) + $this->keys = array_merge($this->keys, array_keys($entries)); + } + } + } + } + } + } } public function __destruct() @@ -78,12 +85,16 @@ class CacheMemcacheCore extends Cache */ public function connect() { - $this->memcache = new Memcache(); - $servers = CacheMemcache::getMemcachedServers(); + if (class_exists('Memcache') && extension_loaded('memcache')) + $this->memcache = new Memcache(); + else + return false; + + $servers = self::getMemcachedServers(); if (!$servers) return false; foreach ($servers as $server) - $this->memcache->addServer($server['ip'], $server['port'], $server['weight']); + $this->memcache->addServer($server['ip'], $server['port'], true, (int) $server['weight']); $this->is_connected = true; } diff --git a/classes/controller/AdminController.php b/classes/controller/AdminController.php index 20a8d5331..d7cc66f89 100644 --- a/classes/controller/AdminController.php +++ b/classes/controller/AdminController.php @@ -2268,9 +2268,10 @@ class AdminControllerCore extends Controller $class_name = $this->className; /* Class specific validation rules */ - $rules = call_user_func(array($class_name, 'getValidationRules'), $class_name); + if (!empty($class_name)) + $rules = call_user_func(array($class_name, 'getValidationRules'), $class_name); - if ((count($rules['requiredLang']) || count($rules['sizeLang']) || count($rules['validateLang']))) + if (isset($rules) && count($rules) && (count($rules['requiredLang']) || count($rules['sizeLang']) || count($rules['validateLang']))) { /* Language() instance determined by default language */ $default_language = new Language((int)Configuration::get('PS_LANG_DEFAULT')); @@ -2280,56 +2281,61 @@ class AdminControllerCore extends Controller } /* Checking for required fields */ - foreach ($rules['required'] as $field) - if (($value = Tools::getValue($field)) == false && (string)$value != '0') - if (!Tools::getValue($this->identifier) || ($field != 'passwd' && $field != 'no-picture')) - $this->errors[] = sprintf( - Tools::displayError('The field %s is required.'), - call_user_func(array($class_name, 'displayFieldName'), $field, $class_name) - ); + if (isset($rules['required']) && is_array($rules['required'])) + foreach ($rules['required'] as $field) + if (($value = Tools::getValue($field)) == false && (string)$value != '0') + if (!Tools::getValue($this->identifier) || ($field != 'passwd' && $field != 'no-picture')) + $this->errors[] = sprintf( + Tools::displayError('The field %s is required.'), + call_user_func(array($class_name, 'displayFieldName'), $field, $class_name) + ); /* Checking for multilingual required fields */ - foreach ($rules['requiredLang'] as $field_lang) - if (($empty = Tools::getValue($field_lang.'_'.$default_language->id)) === false || $empty !== '0' && empty($empty)) - $this->errors[] = sprintf( - Tools::displayError('The field %1$s is required at least in %2$s.'), - call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name), - $default_language->name - ); + if (isset($rules['requiredLang']) && is_array($rules['requiredLang'])) + foreach ($rules['requiredLang'] as $field_lang) + if (($empty = Tools::getValue($field_lang.'_'.$default_language->id)) === false || $empty !== '0' && empty($empty)) + $this->errors[] = sprintf( + Tools::displayError('The field %1$s is required at least in %2$s.'), + call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name), + $default_language->name + ); /* Checking for maximum fields sizes */ - foreach ($rules['size'] as $field => $max_length) - if (Tools::getValue($field) !== false && Tools::strlen(Tools::getValue($field)) > $max_length) - $this->errors[] = sprintf( - Tools::displayError('The field %1$s is too long (%2$d chars max).'), - call_user_func(array($class_name, 'displayFieldName'), $field, $class_name), - $max_length - ); - - /* Checking for maximum multilingual fields size */ - foreach ($rules['sizeLang'] as $field_lang => $max_length) - foreach ($languages as $language) - { - $field_lang_value = Tools::getValue($field_lang.'_'.$language['id_lang']); - if ($field_lang_value !== false && Tools::strlen($field_lang_value) > $max_length) + if (isset($rules['size']) && is_array($rules['size'])) + foreach ($rules['size'] as $field => $max_length) + if (Tools::getValue($field) !== false && Tools::strlen(Tools::getValue($field)) > $max_length) $this->errors[] = sprintf( - Tools::displayError('The field %1$s (%2$s) is too long (%3$d chars max, html chars including).'), - call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name), - $language['name'], + Tools::displayError('The field %1$s is too long (%2$d chars max).'), + call_user_func(array($class_name, 'displayFieldName'), $field, $class_name), $max_length ); - } + + /* Checking for maximum multilingual fields size */ + if (isset($rules['sizeLang']) && is_array($rules['sizeLang'])) + foreach ($rules['sizeLang'] as $field_lang => $max_length) + foreach ($languages as $language) + { + $field_lang_value = Tools::getValue($field_lang.'_'.$language['id_lang']); + if ($field_lang_value !== false && Tools::strlen($field_lang_value) > $max_length) + $this->errors[] = sprintf( + Tools::displayError('The field %1$s (%2$s) is too long (%3$d chars max, html chars including).'), + call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name), + $language['name'], + $max_length + ); + } /* Overload this method for custom checking */ $this->_childValidation(); /* Checking for fields validity */ - foreach ($rules['validate'] as $field => $function) - if (($value = Tools::getValue($field)) !== false && ($field != 'passwd')) - if (!Validate::$function($value) && !empty($value)) - $this->errors[] = sprintf( - Tools::displayError('The field %s is invalid.'), - call_user_func(array($class_name, 'displayFieldName'), $field, $class_name) - ); + if (isset($rules['validate']) && is_array($rules['validate'])) + foreach ($rules['validate'] as $field => $function) + if (($value = Tools::getValue($field)) !== false && ($field != 'passwd')) + if (!Validate::$function($value) && !empty($value)) + $this->errors[] = sprintf( + Tools::displayError('The field %s is invalid.'), + call_user_func(array($class_name, 'displayFieldName'), $field, $class_name) + ); /* Checking for passwd_old validity */ if (($value = Tools::getValue('passwd')) != false) @@ -2347,15 +2353,16 @@ class AdminControllerCore extends Controller } /* Checking for multilingual fields validity */ - foreach ($rules['validateLang'] as $field_lang => $function) - foreach ($languages as $language) - if (($value = Tools::getValue($field_lang.'_'.$language['id_lang'])) !== false && !empty($value)) - if (!Validate::$function($value)) - $this->errors[] = sprintf( - Tools::displayError('The field %1$s (%2$s) is invalid.'), - call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name), - $language['name'] - ); + if (isset($rules['validateLang']) && is_array($rules['validateLang'])) + foreach ($rules['validateLang'] as $field_lang => $function) + foreach ($languages as $language) + if (($value = Tools::getValue($field_lang.'_'.$language['id_lang'])) !== false && !empty($value)) + if (!Validate::$function($value)) + $this->errors[] = sprintf( + Tools::displayError('The field %1$s (%2$s) is invalid.'), + call_user_func(array($class_name, 'displayFieldName'), $field_lang, $class_name), + $language['name'] + ); } /** diff --git a/classes/controller/FrontController.php b/classes/controller/FrontController.php index d07d14d9d..60d4bf987 100755 --- a/classes/controller/FrontController.php +++ b/classes/controller/FrontController.php @@ -585,7 +585,7 @@ class FrontControllerCore extends Controller /* Display a maintenance page if shop is closed */ protected function displayMaintenancePage() { - if ($this->maintenance == true || (basename($_SERVER['PHP_SELF']) != 'disabled.php' && !(int)(Configuration::get('PS_SHOP_ENABLE')))) + if ($this->maintenance == true || !(int)Configuration::get('PS_SHOP_ENABLE')) { $this->maintenance = true; if (!in_array(Tools::getRemoteAddr(), explode(',', Configuration::get('PS_MAINTENANCE_IP')))) diff --git a/classes/db/Db.php b/classes/db/Db.php index 4a94f3b5b..e543f35ce 100644 --- a/classes/db/Db.php +++ b/classes/db/Db.php @@ -674,6 +674,11 @@ abstract class DbCore return call_user_func_array(array(Db::getClass(), 'hasTableWithSamePrefix'), array($server, $user, $pwd, $db, $prefix)); } + public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine) + { + return call_user_func_array(array(Db::getClass(), 'checkCreatePrivilege'), array($server, $user, $pwd, $db, $prefix, $engine)); + } + /** * @deprecated 1.5.0 */ diff --git a/classes/db/DbMySQLi.php b/classes/db/DbMySQLi.php index 959a52d3a..3d5556908 100644 --- a/classes/db/DbMySQLi.php +++ b/classes/db/DbMySQLi.php @@ -185,6 +185,25 @@ class DbMySQLiCore extends Db $link->close(); return 0; } + + public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine) + { + $link = @new mysqli($server, $user, $pwd, $db); + if (mysqli_connect_error()) + return false; + + $sql = ' + CREATE TABLE `'.$prefix.'test` ( + `test` tinyint(1) unsigned NOT NULL + ) ENGINE=MyISAM'; + $result = $link->query($sql); + + if (!$result) + return $link->error; + + $link->query('DROP TABLE `'.$prefix.'test`'); + return true; + } /** * @see Db::checkEncoding() diff --git a/classes/db/DbPDO.php b/classes/db/DbPDO.php index 06ce7539c..ac8709c75 100644 --- a/classes/db/DbPDO.php +++ b/classes/db/DbPDO.php @@ -174,6 +174,28 @@ class DbPDOCore extends Db return (bool)$result->fetch(); } + public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine) + { + try { + $link = DbPDO::_getPDO($server, $user, $pwd, $db, 5); + } catch (PDOException $e) { + return false; + } + + $sql = ' + CREATE TABLE `'.$prefix.'test` ( + `test` tinyint(1) unsigned NOT NULL + ) ENGINE=MyISAM'; + $result = $link->query($sql); + if (!$result) + { + $error = $link->errorInfo(); + return $error[2]; + } + $link->query('DROP TABLE `'.$prefix.'test`'); + return true; + } + /** * @see Db::checkConnection() */ diff --git a/classes/db/MySQL.php b/classes/db/MySQL.php index 92c41768b..2713305d8 100644 --- a/classes/db/MySQL.php +++ b/classes/db/MySQL.php @@ -174,6 +174,28 @@ class MySQLCore extends Db @mysql_close($link); return 0; } + + public static function checkCreatePrivilege($server, $user, $pwd, $db, $prefix, $engine) + { + ini_set('mysql.connect_timeout', 5); + if (!$link = @mysql_connect($server, $user, $pwd, true)) + return false; + if (!@mysql_select_db($db, $link)) + return false; + + $sql = ' + CREATE TABLE `'.$prefix.'test` ( + `test` tinyint(1) unsigned NOT NULL + ) ENGINE=MyISAM'; + + $result = mysql_query($sql, $link); + + if (!$result) + return mysql_error($link); + + mysql_query('DROP TABLE `'.$prefix.'test`', $link); + return true; + } /** * @see Db::checkEncoding() diff --git a/classes/module/Module.php b/classes/module/Module.php index 900d88bd3..b8d93cd7b 100644 --- a/classes/module/Module.php +++ b/classes/module/Module.php @@ -189,7 +189,10 @@ abstract class ModuleCore { // Check module name validation if (!Validate::isModuleName($this->name)) - die(Tools::displayError()); + { + $this->_errors[] = $this->l('Unable to install the module (Module name is not valid).'); + return false; + } // Check PS version compliancy if (version_compare(_PS_VERSION_, $this->ps_versions_compliancy['min']) < 0 || version_compare(_PS_VERSION_, $this->ps_versions_compliancy['max']) >= 0) diff --git a/classes/order/Order.php b/classes/order/Order.php index b9681a7c2..34806bb8f 100644 --- a/classes/order/Order.php +++ b/classes/order/Order.php @@ -264,7 +264,7 @@ class OrderCore extends ObjectModel public function getFields() { if (!$this->id_lang) - $this->id_lang = Configuration::get('PS_LANG_DEFAULT'); + $this->id_lang = Configuration::get('PS_LANG_DEFAULT', null, null, $this->id_shop); return parent::getFields(); } @@ -289,7 +289,7 @@ class OrderCore extends ObjectModel if ($this->hasBeenDelivered()) { - if (!Configuration::get('PS_ORDER_RETURN')) + if (!Configuration::get('PS_ORDER_RETURN', null, null, $this->id_shop)) throw new PrestaShopException('PS_ORDER_RETURN is not defined in table configuration'); $orderDetail->product_quantity_return += (int)($quantity); return $orderDetail->update(); @@ -1027,7 +1027,7 @@ class OrderCore extends ObjectModel * @param int $id_order_invoice * @return bool */ - public function addCartRule($id_cart_rule, $name, $values, $id_order_invoice = 0) + public function addCartRule($id_cart_rule, $name, $values, $id_order_invoice = 0, $free_shipping = null) { $order_cart_rule = new OrderCartRule(); $order_cart_rule->id_order = $this->id; @@ -1036,12 +1036,18 @@ class OrderCore extends ObjectModel $order_cart_rule->name = $name; $order_cart_rule->value = $values['tax_incl']; $order_cart_rule->value_tax_excl = $values['tax_excl']; + if ($free_shipping === null) + { + $cart_rule = new CartRule($id_cart_rule); + $free_shipping = $cart_rule->free_shipping; + } + $order_cart_rule->free_shipping = (int)$free_shipping; $order_cart_rule->add(); } public function getNumberOfDays() { - $nbReturnDays = (int)(Configuration::get('PS_ORDER_RETURN_NB_DAYS')); + $nbReturnDays = (int)(Configuration::get('PS_ORDER_RETURN_NB_DAYS', null, null, $this->id_shop)); if (!$nbReturnDays) return true; $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow(' @@ -1059,7 +1065,7 @@ class OrderCore extends ObjectModel */ public function isReturnable() { - if (Configuration::get('PS_ORDER_RETURN') && $this->isPaidAndShipped()) + if (Configuration::get('PS_ORDER_RETURN', null, null, $this->id_shop) && $this->isPaidAndShipped()) return $this->getNumberOfDays(); return false; @@ -1082,10 +1088,10 @@ class OrderCore extends ObjectModel { $order_invoice = new OrderInvoice(); $order_invoice->id_order = $this->id; - $order_invoice->number = Configuration::get('PS_INVOICE_START_NUMBER'); + $order_invoice->number = Configuration::get('PS_INVOICE_START_NUMBER', null, null, $this->id_shop); // If invoice start number has been set, you clean the value of this configuration if ($order_invoice->number) - Configuration::updateValue('PS_INVOICE_START_NUMBER', false ); + Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $this->id_shop); else $order_invoice->number = Order::getLastInvoiceNumber() + 1; @@ -1169,11 +1175,11 @@ class OrderCore extends ObjectModel $order_invoice_collection = $this->getInvoicesCollection(); foreach ($order_invoice_collection as $order_invoice) { - $number = (int)Configuration::get('PS_DELIVERY_NUMBER'); + $number = (int)Configuration::get('PS_DELIVERY_NUMBER', null, null, $this->id_shop); if (!$number) { //if delivery number is not set or wrong, we set a default one. - Configuration::updateValue('PS_DELIVERY_NUMBER', 1); + Configuration::updateValue('PS_DELIVERY_NUMBER', 1, false, null, $this->id_shop); $number = 1; } @@ -1185,7 +1191,7 @@ class OrderCore extends ObjectModel // Keep for backward compatibility $this->delivery_number = $number; - Configuration::updateValue('PS_DELIVERY_NUMBER', $number + 1); + Configuration::updateValue('PS_DELIVERY_NUMBER', $number + 1, false, null, $this->id_shop); } // Keep it for backward compatibility, to remove on 1.6 version @@ -1591,7 +1597,7 @@ class OrderCore extends ObjectModel else { $amount = Tools::convertPrice($payment->amount, $payment->id_currency, false); - if ($currency->id == Configuration::get('PS_DEFAULT_CURRENCY')) + if ($currency->id == Configuration::get('PS_DEFAULT_CURRENCY', null, null, $this->id_shop)) $total += $amount; else $total += Tools::convertPrice($amount, $currency->id, true); diff --git a/classes/order/OrderHistory.php b/classes/order/OrderHistory.php index 7c4af620f..0af2e1535 100644 --- a/classes/order/OrderHistory.php +++ b/classes/order/OrderHistory.php @@ -70,10 +70,10 @@ class OrderHistoryCore extends ObjectModel * Sets the new state of the given order * * @param int $new_order_state - * @param int $id_order + * @param int/object $id_order * @param bool $use_existing_payment */ - public function changeIdOrderState($new_order_state, &$id_order, $use_existing_payment = false) + public function changeIdOrderState($new_order_state, $id_order, $use_existing_payment = false) { if (!$new_order_state || !$id_order) return; @@ -210,7 +210,7 @@ class OrderHistoryCore extends ObjectModel // if the product is a pack, we restock every products in the pack using the last negative stock mvts if (Pack::isPack($product['product_id'])) { - $pack_products = Pack::getItems($product['product_id'], Configuration::get('PS_LANG_DEFAULT')); + $pack_products = Pack::getItems($product['product_id'], Configuration::get('PS_LANG_DEFAULT', null, null, $order->id_shop)); foreach ($pack_products as $pack_product) { if ($pack_product->advanced_stock_management == 1) diff --git a/classes/order/OrderInvoice.php b/classes/order/OrderInvoice.php index 7d46ec488..ea74e877e 100644 --- a/classes/order/OrderInvoice.php +++ b/classes/order/OrderInvoice.php @@ -345,6 +345,11 @@ class OrderInvoiceCore extends ObjectModel // shipping cost are added in the product taxes breakdown if ($this->useOneAfterAnotherTaxComputationMethod()) return $taxes_breakdown; + + // No shipping breakdown if it's free! + foreach ($order->getCartRules() as $cart_rule) + if ($cart_rule['free_shipping']) + return $taxes_breakdown; $shipping_tax_amount = $this->total_shipping_tax_incl - $this->total_shipping_tax_excl; @@ -654,9 +659,9 @@ class OrderInvoiceCore extends ObjectModel * @param int $id_lang for invoice_prefix * @return string */ - public function getInvoiceNumberFormatted($id_lang) + public function getInvoiceNumberFormatted($id_lang, $id_shop = null) { - return '#'.Configuration::get('PS_INVOICE_PREFIX', $id_lang).sprintf('%06d', $this->number); + return '#'.Configuration::get('PS_INVOICE_PREFIX', $id_lang, null, $id_shop).sprintf('%06d', $this->number); } public function saveCarrierTaxCalculator(array $taxes_amount) diff --git a/classes/order/OrderReturn.php b/classes/order/OrderReturn.php index cdd4e4355..287cd93f9 100644 --- a/classes/order/OrderReturn.php +++ b/classes/order/OrderReturn.php @@ -225,11 +225,12 @@ class OrderReturnCore extends ObjectModel public static function addReturnedQuantity(&$products, $id_order) { $details = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS(' - SELECT od.id_order_detail, GREATEST(od.product_quantity_return, IFNULL(ord.product_quantity,0)) as qty_returned + SELECT od.id_order_detail, GREATEST(od.product_quantity_return, IFNULL(SUM(ord.product_quantity),0)) as qty_returned FROM '._DB_PREFIX_.'order_detail od LEFT JOIN '._DB_PREFIX_.'order_return_detail ord ON ord.id_order_detail = od.id_order_detail - WHERE od.id_order = '.(int)$id_order + WHERE od.id_order = '.(int)$id_order.' + GROUP BY od.id_order_detail' ); if (!$details) return; diff --git a/classes/pdf/HTMLTemplateInvoice.php b/classes/pdf/HTMLTemplateInvoice.php index 8861f7459..efbbc790a 100755 --- a/classes/pdf/HTMLTemplateInvoice.php +++ b/classes/pdf/HTMLTemplateInvoice.php @@ -42,7 +42,7 @@ class HTMLTemplateInvoiceCore extends HTMLTemplate $this->date = Tools::displayDate($order_invoice->date_add, (int)$this->order->id_lang); $id_lang = Context::getContext()->language->id; - $this->title = HTMLTemplateInvoice::l('Invoice ').' #'.Configuration::get('PS_INVOICE_PREFIX', $id_lang).sprintf('%06d', $order_invoice->number); + $this->title = HTMLTemplateInvoice::l('Invoice ').' #'.Configuration::get('PS_INVOICE_PREFIX', $id_lang, null, (int)$this->order->id_shop).sprintf('%06d', $order_invoice->number); // footer informations $this->shop = new Shop((int)$this->order->id_shop); } diff --git a/config/alias.php b/config/alias.php index 77ee8fac0..9c4cbb36a 100644 --- a/config/alias.php +++ b/config/alias.php @@ -74,7 +74,7 @@ function bqSQL($string) function displayFatalError() { $error = error_get_last(); - if ($error !== NULL) + if ($error !== NULL && in_array($error['type'], array(E_ERROR, E_PARSE))) echo '[PrestaShop] Fatal error in module '.substr(basename($error['file']), 0, -4).':
'.$error['message']; } diff --git a/controllers/admin/AdminCurrenciesController.php b/controllers/admin/AdminCurrenciesController.php index 760415fe2..3ec2ea389 100644 --- a/controllers/admin/AdminCurrenciesController.php +++ b/controllers/admin/AdminCurrenciesController.php @@ -71,6 +71,7 @@ class AdminCurrenciesControllerCore extends AdminController $this->_select .= 'currency_shop.conversion_rate conversion_rate'; $this->_join .= Shop::addSqlAssociation('currency', 'a'); + $this->_group .= 'GROUP BY id_currency'; } public function renderList() diff --git a/controllers/admin/AdminImportController.php b/controllers/admin/AdminImportController.php index 20e62134b..6c3581753 100644 --- a/controllers/admin/AdminImportController.php +++ b/controllers/admin/AdminImportController.php @@ -644,10 +644,14 @@ class AdminImportControllerCore extends AdminController do $uniqid_path = _PS_UPLOAD_DIR_.uniqid(); while (file_exists($uniqid_path)); file_put_contents($uniqid_path, $field); - $fd = fopen($uniqid_path, 'r'); - $tab = fgetcsv($fd, MAX_LINE_SIZE, $separator); - fclose($fd); - unlink($uniqid_path); + $tab = ''; + if(!empty($uniqid_path)) + { + $fd = fopen($uniqid_path, 'r'); + $tab = fgetcsv($fd, MAX_LINE_SIZE, $separator); + fclose($fd); + unlink($uniqid_path); + } if (empty($tab) || (!is_array($tab))) return array(); @@ -727,8 +731,9 @@ class AdminImportControllerCore extends AdminController public static function getMaskedRow($row) { $res = array(); - foreach (self::$column_mask as $type => $nb) - $res[$type] = isset($row[$nb]) ? $row[$nb] : null; + if (is_array(self::$column_mask)) + foreach (self::$column_mask as $type => $nb) + $res[$type] = isset($row[$nb]) ? $row[$nb] : null; if (Tools::getValue('forceIds')) // if you choose to force table before import the column id is remove from the CSV file. unset($res['id']); @@ -899,7 +904,7 @@ class AdminImportControllerCore extends AdminController $category_to_create->name[$default_language_id], (isset($category_to_create->id) ? $category_to_create->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -972,10 +977,10 @@ class AdminImportControllerCore extends AdminController { $this->errors[] = sprintf( Tools::displayError('%1$s (ID: %2$s) cannot be saved'), - $info['name'], - (isset($info['id']) ? $info['id'] : 'null') + (isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'), + (isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID') ); - $error_tmp = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').Db::getInstance()->getMsgError(); + $error_tmp = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '').Db::getInstance()->getMsgError(); if ($error_tmp != '') $this->errors[] = $error_tmp; } @@ -1099,7 +1104,7 @@ class AdminImportControllerCore extends AdminController $manufacturer->name, (isset($manufacturer->id) ? $manufacturer->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -1130,7 +1135,7 @@ class AdminImportControllerCore extends AdminController $supplier->name, (isset($supplier->id) ? $supplier->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -1176,7 +1181,7 @@ class AdminImportControllerCore extends AdminController $category_to_create->name[$default_language_id], (isset($category_to_create->id) ? $category_to_create->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -1208,7 +1213,7 @@ class AdminImportControllerCore extends AdminController $category_to_create->name[$default_language_id], (isset($category_to_create->id) ? $category_to_create->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -1303,10 +1308,10 @@ class AdminImportControllerCore extends AdminController { $this->errors[] = sprintf( Tools::displayError('%1$s (ID: %2$s) cannot be saved'), - $info['name'], - (isset($info['id']) ? $info['id'] : 'null') + (isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'), + (isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } @@ -1347,7 +1352,7 @@ class AdminImportControllerCore extends AdminController $specific_price->from = (isset($info['reduction_from']) && Validate::isDate($info['reduction_from'])) ? $info['reduction_from'] : '0000-00-00 00:00:00'; $specific_price->to = (isset($info['reduction_to']) && Validate::isDate($info['reduction_to'])) ? $info['reduction_to'] : '0000-00-00 00:00:00'; if (!$specific_price->add()) - $this->addProductWarning($info['name'], $product->id, $this->l('Discount is invalid')); + $this->addProductWarning(Tools::safeOutput($info['name']), $product->id, $this->l('Discount is invalid')); } if (isset($product->tags) && !empty($product->tags)) @@ -1363,7 +1368,7 @@ class AdminImportControllerCore extends AdminController $is_tag_added = Tag::addTags($key, $product->id, $tags, $this->multiple_value_separator); if (!$is_tag_added) { - $this->addProductWarning($info['name'], $product->id, $this->l('Tags list is invalid')); + $this->addProductWarning(Tools::safeOutput($info['name']), $product->id, $this->l('Tags list is invalid')); break; } } @@ -1380,7 +1385,7 @@ class AdminImportControllerCore extends AdminController $is_tag_added = Tag::addTags($key, $product->id, $str, $this->multiple_value_separator); if (!$is_tag_added) { - $this->addProductWarning($info['name'], $product->id, 'Invalid tag(s) ('.$str.')'); + $this->addProductWarning(Tools::safeOutput($info['name']), (int)$product->id, 'Invalid tag(s) ('.$str.')'); break; } } @@ -1445,9 +1450,12 @@ class AdminImportControllerCore extends AdminController $feature_name = trim($tab_feature[0]); $feature_value = trim($tab_feature[1]); $position = isset($tab_feature[2]) ? $tab_feature[2]: false; - $id_feature = Feature::addFeatureImport($feature_name, $position); - $id_feature_value = FeatureValue::addFeatureValueImport($id_feature, $feature_value); - Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value); + if(!empty($feature_name) && !empty($feature_value)) + { + $id_feature = Feature::addFeatureImport($feature_name, $position); + $id_feature_value = FeatureValue::addFeatureValueImport($id_feature, $feature_value); + Product::addFeatureProductImport($product->id, $id_feature, $id_feature_value); + } } // clean feature positions to avoid conflict Feature::cleanPositions(); @@ -1464,9 +1472,6 @@ class AdminImportControllerCore extends AdminController } - if (Configuration::get('PS_SEARCH_INDEXATION')) - Search::indexation(true); - $this->closeCsvFile($handle); } @@ -1511,8 +1516,12 @@ class AdminImportControllerCore extends AdminController $id_shop_list[] = Shop::getIdByName($shop); else $id_shop_list[] = $shop; - - $product = new Product((int)$info['id_product'], false, $default_language); + + if(isset($info['id_product'])) + $product = new Product((int)$info['id_product'], false, $default_language); + else + continue; + $id_image = null; //delete existing images if "delete_existing_images" is set to 1 @@ -1552,7 +1561,7 @@ class AdminImportControllerCore extends AdminController Tools::displayError('%s cannot be saved'), (isset($image->id_product) ? ' ('.$image->id_product.')' : '') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : '').mysql_error(); + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : '').mysql_error(); } } elseif (isset($info['image_position']) && $info['image_position']) @@ -1577,53 +1586,54 @@ class AdminImportControllerCore extends AdminController $id_attribute_group = 0; // groups $groups_attributes = array(); - foreach (explode($this->multiple_value_separator, $info['group']) as $key => $group) - { - $tab_group = explode(':', $group); - $group = trim($tab_group[0]); - if (!isset($tab_group[1])) - $type = 'select'; - else - $type = trim($tab_group[1]); - - // sets group - $groups_attributes[$key]['group'] = $group; - - // if position is filled - if (isset($tab_group[2])) - $position = trim($tab_group[2]); - else - $position = false; - - if (!isset($groups[$group])) + if(isset($info['group'])) + foreach (explode($this->multiple_value_separator, $info['group']) as $key => $group) { - $obj = new AttributeGroup(); - $obj->is_color_group = false; - $obj->group_type = pSQL($type); - $obj->name[$default_language] = $group; - $obj->public_name[$default_language] = $group; - $obj->position = (!$position) ? AttributeGroup::getHigherPosition() + 1 : $position; - - if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true && - ($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true) - { - $obj->add(); - $obj->associateTo($id_shop_list); - $groups[$group] = $obj->id; - } + $tab_group = explode(':', $group); + $group = trim($tab_group[0]); + if (!isset($tab_group[1])) + $type = 'select'; else - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''); - - // fils groups attributes - $id_attribute_group = $obj->id; - $groups_attributes[$key]['id'] = $id_attribute_group; + $type = trim($tab_group[1]); + + // sets group + $groups_attributes[$key]['group'] = $group; + + // if position is filled + if (isset($tab_group[2])) + $position = trim($tab_group[2]); + else + $position = false; + + if (!isset($groups[$group])) + { + $obj = new AttributeGroup(); + $obj->is_color_group = false; + $obj->group_type = pSQL($type); + $obj->name[$default_language] = $group; + $obj->public_name[$default_language] = $group; + $obj->position = (!$position) ? AttributeGroup::getHigherPosition() + 1 : $position; + + if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true && + ($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true) + { + $obj->add(); + $obj->associateTo($id_shop_list); + $groups[$group] = $obj->id; + } + else + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''); + + // fils groups attributes + $id_attribute_group = $obj->id; + $groups_attributes[$key]['id'] = $id_attribute_group; + } + else // alreay exists + { + $id_attribute_group = $groups[$group]; + $groups_attributes[$key]['id'] = $id_attribute_group; + } } - else // alreay exists - { - $id_attribute_group = $groups[$group]; - $groups_attributes[$key]['id'] = $id_attribute_group; - } - } // inits attribute $id_product_attribute = 0; @@ -1631,116 +1641,118 @@ class AdminImportControllerCore extends AdminController $attributes_to_add = array(); // for each attribute - foreach (explode($this->multiple_value_separator, $info['attribute']) as $key => $attribute) - { - $tab_attribute = explode(':', $attribute); - $attribute = trim($tab_attribute[0]); - // if position is filled - if (isset($tab_attribute[1])) - $position = trim($tab_attribute[1]); - else - $position = false; - - if (isset($groups_attributes[$key])) + if(isset($info['attribute'])) + foreach (explode($this->multiple_value_separator, $info['attribute']) as $key => $attribute) { - $group = $groups_attributes[$key]['group']; - if (!isset($attributes[$group.'_'.$attribute]) && count($groups_attributes[$key]) == 2) + $tab_attribute = explode(':', $attribute); + $attribute = trim($tab_attribute[0]); + // if position is filled + if (isset($tab_attribute[1])) + $position = trim($tab_attribute[1]); + else + $position = false; + + if (isset($groups_attributes[$key])) { - $id_attribute_group = $groups_attributes[$key]['id']; - $obj = new Attribute(); - // sets the proper id (corresponding to the right key) - $obj->id_attribute_group = $groups_attributes[$key]['id']; - $obj->name[$default_language] = str_replace('\n', '', str_replace('\r', '', $attribute)); - $obj->position = (!$position) ? Attribute::getHigherPosition($groups[$group]) + 1 : $position; - - if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true && - ($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true) + $group = $groups_attributes[$key]['group']; + if (!isset($attributes[$group.'_'.$attribute]) && count($groups_attributes[$key]) == 2) { - $obj->add(); - $obj->associateTo($id_shop_list); - $attributes[$group.'_'.$attribute] = $obj->id; - } - else - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''); - } - - $info['minimal_quantity'] = isset($info['minimal_quantity']) && $info['minimal_quantity'] ? (int)$info['minimal_quantity'] : 1; - - $info['wholesale_price'] = str_replace(',', '.', $info['wholesale_price']); - $info['price'] = str_replace(',', '.', $info['price']); - $info['ecotax'] = str_replace(',', '.', $info['ecotax']); - $info['weight'] = str_replace(',', '.', $info['weight']); - - // if a reference is specified for this product, get the associate id_product_attribute to UPDATE - if (isset($info['reference']) && !empty($info['reference'])) - { - $id_product_attribute = Combination::getIdByReference($product->id, strval($info['reference'])); - - // updates the attribute - if ($id_product_attribute) - { - // gets all the combinations of this product - $attribute_combinations = $product->getAttributeCombinations($default_language); - foreach ($attribute_combinations as $attribute_combination) + $id_attribute_group = $groups_attributes[$key]['id']; + $obj = new Attribute(); + // sets the proper id (corresponding to the right key) + $obj->id_attribute_group = $groups_attributes[$key]['id']; + $obj->name[$default_language] = str_replace('\n', '', str_replace('\r', '', $attribute)); + $obj->position = (!$position && isset($groups[$group])) ? Attribute::getHigherPosition($groups[$group]) + 1 : $position; + + if (($field_error = $obj->validateFields(UNFRIENDLY_ERROR, true)) === true && + ($lang_field_error = $obj->validateFieldsLang(UNFRIENDLY_ERROR, true)) === true) { - if ($id_product_attribute && in_array($id_product_attribute, $attribute_combination)) + $obj->add(); + $obj->associateTo($id_shop_list); + $attributes[$group.'_'.$attribute] = $obj->id; + } + else + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''); + } + + $info['minimal_quantity'] = isset($info['minimal_quantity']) && $info['minimal_quantity'] ? (int)$info['minimal_quantity'] : 1; + + $info['wholesale_price'] = str_replace(',', '.', $info['wholesale_price']); + $info['price'] = str_replace(',', '.', $info['price']); + $info['ecotax'] = str_replace(',', '.', $info['ecotax']); + $info['weight'] = str_replace(',', '.', $info['weight']); + + // if a reference is specified for this product, get the associate id_product_attribute to UPDATE + if (isset($info['reference']) && !empty($info['reference'])) + { + $id_product_attribute = Combination::getIdByReference($product->id, strval($info['reference'])); + + // updates the attribute + if ($id_product_attribute) + { + // gets all the combinations of this product + $attribute_combinations = $product->getAttributeCombinations($default_language); + foreach ($attribute_combinations as $attribute_combination) { - $product->updateAttribute( - $id_product_attribute, - (float)$info['wholesale_price'], - (float)$info['price'], - (float)$info['weight'], - 0, - (float)$info['ecotax'], - $id_image, - strval($info['reference']), - strval($info['ean13']), - (int)$info['default_on'], - 0, - strval($info['upc']), - (int)$info['minimal_quantity'], - 0, - null, - $id_shop_list - ); - - $id_product_attribute_update = true; + if ($id_product_attribute && in_array($id_product_attribute, $attribute_combination)) + { + $product->updateAttribute( + $id_product_attribute, + (float)$info['wholesale_price'], + (float)$info['price'], + (float)$info['weight'], + 0, + (float)$info['ecotax'], + $id_image, + strval($info['reference']), + strval($info['ean13']), + (int)$info['default_on'], + 0, + strval($info['upc']), + (int)$info['minimal_quantity'], + 0, + null, + $id_shop_list + ); + + $id_product_attribute_update = true; + } } } } + + // if no attribute reference is specified, creates a new one + if (!$id_product_attribute) + { + $id_product_attribute = $product->addCombinationEntity( + (float)$info['wholesale_price'], + (float)$info['price'], + (float)$info['weight'], + 0, + (float)$info['ecotax'], + (int)$info['quantity'], + $id_image, + strval($info['reference']), + 0, + strval($info['ean13']), + (int)$info['default_on'], + 0, + strval($info['upc']), + (int)$info['minimal_quantity'], + $id_shop_list + ); + } + + // fills our attributes array, in order to add the attributes to the product_attribute afterwards + if(isset($attributes[$group.'_'.$attribute])) + $attributes_to_add[] = (int)$attributes[$group.'_'.$attribute]; + + // after insertion, we clean attribute position and group attribute position + $obj = new Attribute(); + $obj->cleanPositions((int)$id_attribute_group, false); + AttributeGroup::cleanPositions(); } - - // if no attribute reference is specified, creates a new one - if (!$id_product_attribute) - { - $id_product_attribute = $product->addCombinationEntity( - (float)$info['wholesale_price'], - (float)$info['price'], - (float)$info['weight'], - 0, - (float)$info['ecotax'], - (int)$info['quantity'], - $id_image, - strval($info['reference']), - 0, - strval($info['ean13']), - (int)$info['default_on'], - 0, - strval($info['upc']), - (int)$info['minimal_quantity'], - $id_shop_list - ); - } - - // fills our attributes array, in order to add the attributes to the product_attribute afterwards - $attributes_to_add[] = (int)$attributes[$group.'_'.$attribute]; - - // after insertion, we clean attribute position and group attribute position - $obj = new Attribute(); - $obj->cleanPositions((int)$id_attribute_group, false); - AttributeGroup::cleanPositions(); } - } $product->checkDefaultAttributes(); if (!$product->cache_default_attribute) @@ -1907,7 +1919,7 @@ class AdminImportControllerCore extends AdminController $info['email'], (isset($info['id']) ? $info['id'] : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -1954,7 +1966,7 @@ class AdminImportControllerCore extends AdminController else { $this->errors[] = sprintf(Tools::displayError('%s cannot be saved'), $country->name[$default_language_id]); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -1984,7 +1996,7 @@ class AdminImportControllerCore extends AdminController else { $this->errors[] = sprintf(Tools::displayError('%s cannot be saved'), $state->name); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -2053,7 +2065,7 @@ class AdminImportControllerCore extends AdminController $manufacturer->name, (isset($manufacturer->id) ? $manufacturer->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -2074,7 +2086,7 @@ class AdminImportControllerCore extends AdminController $supplier->name, (isset($supplier->id) ? $supplier->id : 'null') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -2188,10 +2200,10 @@ class AdminImportControllerCore extends AdminController { $this->errors[] = Db::getInstance()->getMsgError().' '.sprintf( Tools::displayError('%1$s (ID: %2$s) cannot be saved'), - $info['name'], - (isset($info['id']) ? $info['id'] : 'null') + (isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'), + (isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID') ); - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''). + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''). Db::getInstance()->getMsgError(); } } @@ -2235,8 +2247,8 @@ class AdminImportControllerCore extends AdminController if (!$res) $this->errors[] = Db::getInstance()->getMsgError().' '.sprintf( Tools::displayError('%1$s (ID: %2$s) cannot be saved'), - $info['name'], - (isset($info['id']) ? $info['id'] : 'null') + (isset($info['name']) ? Tools::safeOutput($info['name']) : 'No Name'), + (isset($info['id']) ? Tools::safeOutput($info['id']) : 'No ID') ); else { @@ -2263,7 +2275,7 @@ class AdminImportControllerCore extends AdminController else { $this->errors[] = $this->l('Supplier is invalid').' ('.$supplier->name.')'; - $this->errors[] = ($field_error !== true ? $field_error : '').($lang_field_error !== true ? $lang_field_error : ''); + $this->errors[] = ($field_error !== true ? $field_error : '').(isset($lang_field_error) && $lang_field_error !== true ? $lang_field_error : ''); } } $this->closeCsvFile($handle); diff --git a/controllers/admin/AdminLoginController.php b/controllers/admin/AdminLoginController.php index d39c30a3a..b6e79f95a 100755 --- a/controllers/admin/AdminLoginController.php +++ b/controllers/admin/AdminLoginController.php @@ -215,7 +215,7 @@ class AdminLoginControllerCore extends AdminController '{passwd}' => $pwd ); - if (Mail::Send((int)Configuration::get('PS_LANG_DEFAULT'), 'password', Mail::l('Your new password', (int)Configuration::get('PS_LANG_DEFAULT')), $params, $employee->email, $employee->firstname.' '.$employee->lastname)) + if (Mail::Send($employee->id_lang, 'password', Mail::l('Your new password', $employee->id_lang), $params, $employee->email, $employee->firstname.' '.$employee->lastname)) { // Update employee only if the mail can be sent $result = $employee->update(); diff --git a/controllers/admin/AdminLogsController.php b/controllers/admin/AdminLogsController.php index 4c170d71c..081c76e53 100644 --- a/controllers/admin/AdminLogsController.php +++ b/controllers/admin/AdminLogsController.php @@ -61,7 +61,7 @@ class AdminLogsControllerCore extends AdminController 'submit' => array() ) ); - + $this->list_no_link = true; parent::__construct(); } diff --git a/controllers/admin/AdminModulesController.php b/controllers/admin/AdminModulesController.php index 477514792..3b5dc24d6 100644 --- a/controllers/admin/AdminModulesController.php +++ b/controllers/admin/AdminModulesController.php @@ -208,6 +208,7 @@ class AdminModulesControllerCore extends AdminController die ('KO'); if ($result == 'OK') { + Configuration::updateValue('PS_LOGGED_ON_ADDONS', 1); $this->context->cookie->username_addons = pSQL(trim(Tools::getValue('username_addons'))); $this->context->cookie->password_addons = pSQL(trim(Tools::getValue('password_addons'))); } diff --git a/controllers/admin/AdminOrdersController.php b/controllers/admin/AdminOrdersController.php index 257db3ca5..a3c5cf7e6 100755 --- a/controllers/admin/AdminOrdersController.php +++ b/controllers/admin/AdminOrdersController.php @@ -434,7 +434,7 @@ class AdminOrdersControllerCore extends AdminController else { $message = $customer_message->message; - if (Configuration::get('PS_MAIL_TYPE') != Mail::TYPE_TEXT) + if (Configuration::get('PS_MAIL_TYPE', null, null, $order->id_shop) != Mail::TYPE_TEXT) $message = Tools::nl2br($customer_message->message); $varsTpl = array( @@ -972,7 +972,7 @@ class AdminOrdersControllerCore extends AdminController } elseif (Tools::isSubmit('submitGenerateInvoice') && isset($order)) { - if (!Configuration::get('PS_INVOICE')) + if (!Configuration::get('PS_INVOICE', null, null, $order->id_shop)) $this->errors[] = Tools::displayError('Invoice management has been disabled'); elseif ($order->hasInvoice()) $this->errors[] = Tools::displayError('This order already has an invoice'); @@ -1102,7 +1102,7 @@ class AdminOrdersControllerCore extends AdminController foreach ($order_invoices_collection as $order_invoice) { if (Tools::getValue('discount_value') > $order_invoice->total_paid_tax_incl) - $this->errors[] = Tools::displayError('Discount value is greater than the order invoice total (Invoice:').$order_invoice->getInvoiceNumberFormatted(Context::getContext()->language->id).')'; + $this->errors[] = Tools::displayError('Discount value is greater than the order invoice total (Invoice:').$order_invoice->getInvoiceNumberFormatted(Context::getContext()->language->id, (int)$order->id_shop).')'; else { $cart_rules[$order_invoice->id]['value_tax_incl'] = Tools::ps_round(Tools::getValue('discount_value'), 2); @@ -1292,7 +1292,7 @@ class AdminOrdersControllerCore extends AdminController // display warning if there are products out of stock $display_out_of_stock_warning = false; $current_order_state = $order->getCurrentOrderState(); - if ($current_order_state->delivery != 1 && $current_order_state->shipped != 1) + if (!Validate::isLoadedObject($current_order_state) || ($current_order_state->delivery != 1 && $current_order_state->shipped != 1)) $display_out_of_stock_warning = true; // products current stock (from stock_available) @@ -1352,7 +1352,7 @@ class AdminOrdersControllerCore extends AdminController 'invoices_collection' => $order->getInvoicesCollection(), 'not_paid_invoices_collection' => $order->getNotPaidInvoicesCollection(), 'payment_methods' => $payment_methods, - 'invoice_management_active' => Configuration::get('PS_INVOICE') + 'invoice_management_active' => Configuration::get('PS_INVOICE', null, null, $order->id_shop) ); return parent::renderView(); @@ -1535,7 +1535,7 @@ class AdminOrdersControllerCore extends AdminController $use_taxes = true; $initial_product_price_tax_incl = Product::getPriceStatic($product->id, $use_taxes, isset($combination) ? $combination->id : null, 2, null, false, true, 1, - false, $order->id_customer, $cart->id, $order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); + false, $order->id_customer, $cart->id, $order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)}); // Creating specific price if needed if ($product_informations['product_price_tax_incl'] != $initial_product_price_tax_incl) @@ -1612,11 +1612,11 @@ class AdminOrdersControllerCore extends AdminController $order_invoice->id_order = $order->id; if ($order_invoice->number) - Configuration::updateValue('PS_INVOICE_START_NUMBER', false); + Configuration::updateValue('PS_INVOICE_START_NUMBER', false, false, null, $order->id_shop); else $order_invoice->number = Order::getLastInvoiceNumber() + 1; - $invoice_address = new Address((int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE')}); + $invoice_address = new Address((int)$order->{Configuration::get('PS_TAX_ADDRESS_TYPE', null, null, $order->id_shop)}); $carrier = new Carrier((int)$order->id_carrier); $tax_calculator = $carrier->getTaxCalculator($invoice_address); @@ -1713,7 +1713,7 @@ class AdminOrdersControllerCore extends AdminController $invoice_array = array(); foreach ($invoice_collection as $invoice) { - $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id); + $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id, (int)$order->id_shop); $invoice_array[] = $invoice; } @@ -1909,14 +1909,14 @@ class AdminOrdersControllerCore extends AdminController $product['quantity_refundable'] = $product['product_quantity'] - $resume['product_quantity']; $product['amount_refundable'] = $product['total_price_tax_incl'] - $resume['amount_tax_incl']; $product['amount_refund'] = Tools::displayPrice($resume['amount_tax_incl']); - + $product['refund_history'] = OrderSlip::getProductSlipDetail($order_detail->id); // Get invoices collection $invoice_collection = $order->getInvoicesCollection(); $invoice_array = array(); foreach ($invoice_collection as $invoice) { - $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id); + $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id, (int)$order->id_shop); $invoice_array[] = $invoice; } @@ -2003,7 +2003,7 @@ class AdminOrdersControllerCore extends AdminController $invoice_array = array(); foreach ($invoice_collection as $invoice) { - $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id); + $invoice->name = $invoice->getInvoiceNumberFormatted(Context::getContext()->language->id, (int)$order->id_shop); $invoice_array[] = $invoice; } diff --git a/controllers/admin/AdminPerformanceController.php b/controllers/admin/AdminPerformanceController.php index d09925582..a893f66f7 100644 --- a/controllers/admin/AdminPerformanceController.php +++ b/controllers/admin/AdminPerformanceController.php @@ -725,6 +725,7 @@ class AdminPerformanceControllerCore extends AdminController $cache_active = 0; else $cache_active = 1; + if (!$caching_system = Tools::getValue('caching_system')) $this->errors[] = Tools::displayError('Caching system is missing'); else @@ -733,6 +734,7 @@ class AdminPerformanceControllerCore extends AdminController 'define(\'_PS_CACHING_SYSTEM_\', \''.$caching_system.'\');', $new_settings ); + if ($cache_active && $caching_system == 'CacheMemcache' && !extension_loaded('memcache')) $this->errors[] = Tools::displayError('To use Memcached, you must install the Memcache PECL extension on your server.').' http://www.php.net/manual/en/memcache.installation.php'; @@ -759,7 +761,7 @@ class AdminPerformanceControllerCore extends AdminController Configuration::updateValue('PS_CACHEFS_DIRECTORY_DEPTH', (int)$depth); } } - else if ($caching_system == 'MCached' && $cache_active && !_PS_CACHE_ENABLED_ && _PS_CACHING_SYSTEM_ == 'MCached') + else if ($caching_system == 'CacheMemcache' && $cache_active && !_PS_CACHE_ENABLED_ && _PS_CACHING_SYSTEM_ == 'CacheMemcache') Cache::getInstance()->flush(); if (!count($this->errors)) @@ -778,8 +780,7 @@ class AdminPerformanceControllerCore extends AdminController else $this->errors[] = Tools::displayError('You do not have permission to edit here.'); } - - if ($redirecAdmin) + if ($redirecAdmin && (!isset($this->errors) || !count($this->errors))) Tools::redirectAdmin(self::$currentIndex.'&token='.Tools::getValue('token').'&conf=4'); else return parent::postProcess(); diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php index 201e39d3d..a3b1045bf 100644 --- a/controllers/admin/AdminProductsController.php +++ b/controllers/admin/AdminProductsController.php @@ -1422,8 +1422,9 @@ class AdminProductsControllerCore extends AdminController if (!Image::getCover($image->id_product)) { $res &= Db::getInstance()->execute(' - UPDATE `'._DB_PREFIX_.'image_shop` image_shop - SET image_shop.`cover` = 1 + UPDATE `'._DB_PREFIX_.'image_shop` image_shop, '._DB_PREFIX_.'image i + SET image_shop.`cover` = 1, + i.cover = 1 WHERE image_shop.`id_image` = (SELECT id_image FROM (SELECT image_shop.id_image FROM '._DB_PREFIX_.'image i'. @@ -1431,7 +1432,8 @@ class AdminProductsControllerCore extends AdminController WHERE i.id_product ='.(int)$image->id_product.' LIMIT 1 ) tmpImage) AND id_shop='.(int)$this->context->shop->id.' - LIMIT 1'); + AND i.id_image = image_shop.id_image + '); } if (file_exists(_PS_TMP_IMG_DIR_.'product_'.$image->id_product.'.jpg')) diff --git a/controllers/admin/AdminSearchConfController.php b/controllers/admin/AdminSearchConfController.php index 34b294c5b..274543f5f 100644 --- a/controllers/admin/AdminSearchConfController.php +++ b/controllers/admin/AdminSearchConfController.php @@ -113,7 +113,7 @@ class AdminSearchConfControllerCore extends AdminController 'title' => $this->l('Blacklisted words'), 'size' => 35, 'validation' => 'isGenericName', - 'desc' => $this->l('Please enter the index words separated by a "|".'|".'), + 'desc' => $this->l('Please enter the index words separated by a "|".'), 'type' => 'textLang' ) ), diff --git a/controllers/admin/AdminSearchController.php b/controllers/admin/AdminSearchController.php index 390a53638..9811fd754 100644 --- a/controllers/admin/AdminSearchController.php +++ b/controllers/admin/AdminSearchController.php @@ -202,7 +202,11 @@ class AdminSearchControllerCore extends AdminController global $_LANGADM; $tabs = array(); $key_match = array(); - $result = Db::getInstance()->executeS('SELECT class_name, name FROM '._DB_PREFIX_.'tab t INNER JOIN '._DB_PREFIX_.'tab_lang tl ON t.id_tab = tl.id_tab AND tl.id_lang = '.(int)$this->context->language->id); + $result = Db::getInstance()->executeS(' + SELECT class_name, name + FROM '._DB_PREFIX_.'tab t + INNER JOIN '._DB_PREFIX_.'tab_lang tl ON (t.id_tab = tl.id_tab AND tl.id_lang = '.(int)$this->context->language->id.') + WHERE active = 1'); foreach ($result as $row) { $tabs[strtolower($row['class_name'])] = $row['name']; diff --git a/controllers/admin/AdminTranslationsController.php b/controllers/admin/AdminTranslationsController.php index 530d21dd0..1faa32306 100644 --- a/controllers/admin/AdminTranslationsController.php +++ b/controllers/admin/AdminTranslationsController.php @@ -604,22 +604,32 @@ class AdminTranslationsControllerCore extends AdminController $global = false; foreach ($lines as $line) { + // PHP tags if (in_array($line, array('', ''))) continue; + + // Global variable declaration if (!$global && preg_match('/^global\s+\$([a-z0-9-_]+)\s*;$/i', $line, $matches)) { $global = $matches[1]; continue; } + // Global variable initialization if ($global != false && preg_match('/^\$'.preg_quote($global, '/').'\s*=\s*array\(\s*\)\s*;$/i', $line)) continue; + + // Global variable initialization without declaration if (!$global && preg_match('/^\$([a-z0-9-_]+)\s*=\s*array\(\s*\)\s*;$/i', $line, $matches)) { $global = $matches[1]; continue; } + + // Assignation if (preg_match('/^\$'.preg_quote($global, '/').'\[\''._PS_TRANS_PATTERN_.'\'\]\s*=\s*\''._PS_TRANS_PATTERN_.'\'\s*;$/i', $line)) continue; + + // Sometimes the global variable is returned... if (preg_match('/^return\s+\$'.preg_quote($global, '/').'\s*;$/i', $line, $matches)) continue; return false; diff --git a/controllers/front/AuthController.php b/controllers/front/AuthController.php index 785529f56..ee36cf500 100644 --- a/controllers/front/AuthController.php +++ b/controllers/front/AuthController.php @@ -294,14 +294,16 @@ class AuthControllerCore extends FrontController $this->context->customer = $customer; if (Configuration::get('PS_CART_FOLLOWING') && (empty($this->context->cookie->id_cart) || Cart::getNbProducts($this->context->cookie->id_cart) == 0)) + { $this->context->cookie->id_cart = (int)Cart::lastNoneOrderedCart($this->context->customer->id); - - // Update cart address - $this->context->cart->id = $this->context->cookie->id_cart; - $this->context->cart->setDeliveryOption(null); - $this->context->cart->id_address_delivery = Address::getFirstCustomerAddressId((int)($customer->id)); - - $this->context->cart->id_address_invoice = Address::getFirstCustomerAddressId((int)($customer->id)); + $this->context->cart = new Cart((int)$this->context->cookie->id_cart); + } + else + { + $this->context->cart->setDeliveryOption(null); + $this->context->cart->id_address_delivery = Address::getFirstCustomerAddressId((int)($customer->id)); + $this->context->cart->id_address_invoice = Address::getFirstCustomerAddressId((int)($customer->id)); + } $this->context->cart->secure_key = $customer->secure_key; $this->context->cart->update(); $this->context->cart->autosetProductAddress(); diff --git a/controllers/front/DiscountController.php b/controllers/front/DiscountController.php index 63aa41328..afe4bf328 100644 --- a/controllers/front/DiscountController.php +++ b/controllers/front/DiscountController.php @@ -42,7 +42,7 @@ class DiscountControllerCore extends FrontController $cart_rules = CartRule::getCustomerCartRules($this->context->language->id, $this->context->customer->id, true, false); $nb_cart_rules = count($cart_rules); - $this->context->smarty->assign(array('nb_cart_rules' => (int)$nb_cart_rules, 'cart_rules' => $cart_rules)); + $this->context->smarty->assign(array('nb_cart_rules' => (int)$nb_cart_rules, 'cart_rules' => $cart_rules, 'discount' => $cart_rules, 'nbDiscounts' => (int)$nb_cart_rules)); $this->setTemplate(_PS_THEME_DIR_.'discount.tpl'); } } diff --git a/controllers/front/OrderController.php b/controllers/front/OrderController.php index 1881cc530..de8de6ba5 100644 --- a/controllers/front/OrderController.php +++ b/controllers/front/OrderController.php @@ -273,7 +273,7 @@ class OrderControllerCore extends ParentOrderController // Add checking for all addresses $address_without_carriers = $this->context->cart->getDeliveryAddressesWithoutCarriers(); - if (count($address_without_carriers)) + if (count($address_without_carriers) && !$this->context->cart->isVirtualCart()) { if (count($address_without_carriers) > 1) $this->errors[] = sprintf(Tools::displayError('There are no carriers that deliver to some addresses you selected.', !Tools::getValue('ajax'))); diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php index c57997bbd..84c45a956 100644 --- a/controllers/front/ProductController.php +++ b/controllers/front/ProductController.php @@ -145,7 +145,7 @@ class ProductControllerCore extends FrontController // Load category if (isset($_SERVER['HTTP_REFERER']) - && !strstr($_SERVER['HTTP_REFERER'], Tools::getHttpHost()) // Assure us the previous page was one of the shop + && strstr($_SERVER['HTTP_REFERER'], Tools::getHttpHost()) // Assure us the previous page was one of the shop && preg_match('!^(.*)\/([0-9]+)\-(.*[^\.])|(.*)id_category=([0-9]+)(.*)$!', $_SERVER['HTTP_REFERER'], $regs)) { // If the previous page was a category and is a parent category of the product use this category as parent category diff --git a/install-dev/classes/controllerHttp.php b/install-dev/classes/controllerHttp.php index 2375356a4..fea1b6d12 100644 --- a/install-dev/classes/controllerHttp.php +++ b/install-dev/classes/controllerHttp.php @@ -274,7 +274,10 @@ abstract class InstallControllerHttp */ public function findNextStep() { - return (isset(self::$steps[$this->getStepOffset($this->step) + 1])) ? self::$steps[$this->getStepOffset($this->step) + 1] : false; + $nextStep = (isset(self::$steps[$this->getStepOffset($this->step) + 1])) ? self::$steps[$this->getStepOffset($this->step) + 1] : false; + if ($nextStep == 'system' && self::$instances[$nextStep]->validate()) + $nextStep = self::$instances[$nextStep]->findNextStep(); + return $nextStep; } /** diff --git a/install-dev/controllers/http/configure.php b/install-dev/controllers/http/configure.php index d925785df..b6f49697b 100644 --- a/install-dev/controllers/http/configure.php +++ b/install-dev/controllers/http/configure.php @@ -250,7 +250,7 @@ class InstallControllerHttpConfigure extends InstallControllerHttp foreach ($top_countries as $iso) $this->list_countries[] = array('iso' => $iso, 'name' => $countries[$iso]); - $this->list_countries[] = array('name' => '-----------------'); + $this->list_countries[] = array('iso' => 0, 'name' => '-----------------'); foreach ($countries as $iso => $lang) if (!in_array($iso, $top_countries)) diff --git a/install-dev/data/db_structure.sql b/install-dev/data/db_structure.sql index c4a01418a..788796d48 100644 --- a/install-dev/data/db_structure.sql +++ b/install-dev/data/db_structure.sql @@ -1182,6 +1182,7 @@ CREATE TABLE `PREFIX_order_cart_rule` ( `name` varchar(254) NOT NULL, `value` decimal(17,2) NOT NULL default '0.00', `value_tax_excl` decimal(17,2) NOT NULL default '0.00', + `free_shipping` BOOLEAN NOT NULL DEFAULT FALSE, PRIMARY KEY (`id_order_cart_rule`), KEY `id_order` (`id_order`), KEY `id_cart_rule` (`id_cart_rule`) diff --git a/install-dev/data/xml/hook.xml b/install-dev/data/xml/hook.xml index d8625de40..abeb6527e 100644 --- a/install-dev/data/xml/hook.xml +++ b/install-dev/data/xml/hook.xml @@ -8,434 +8,262 @@ - displayPayment - Payment - + displayPaymentPaymentThis hook displays new elements on the payment page - actionValidateOrder - New orders - + actionValidateOrderNew orders - actionPaymentConfirmation - Payment confirmation - + actionPaymentConfirmationPayment confirmationThis hook displays new elements after the payment is validated - displayPaymentReturn - Payment return - + displayPaymentReturnPayment return - actionUpdateQuantity - Quantity update - Quantity is updated only when the customer effectively <b>place</b> his order. + actionUpdateQuantityQuantity updateQuantity is updated only when a customer effectively places their order - displayRightColumn - Right column blocks - + displayRightColumnRight column blocksThis hook displays new elements in the right-hand column - displayLeftColumn - Left column blocks - + displayLeftColumnLeft column blocksThis hook displays new elements in the left-hand column - displayHome - Homepage content - + displayHomeHomepage contentThis hook displays new elements on the homepage - displayHeader - Header of pages - A hook which allow you to do things in the header of each pages + displayHeaderPages headerThis hook displays additional elements in the header of your pages - actionCartSave - Cart creation and update - + actionCartSaveCart creation and updateThis hook is displayed when a product is added to the cart or if the cart's content is modified - actionAuthentication - Successful customer authentication - + actionAuthenticationSuccessful customer authenticationThis hook is displayed after a customer successfully signs in - actionProductAdd - Product creation - + actionProductAddProduct creationThis hook is displayed after a product is created - actionProductUpdate - Product Update - + actionProductUpdateProduct updateThis hook is displayed after a product has been updated - displayTop - Top of pages - A hook which allow you to do things a the top of each pages. + displayTopTop of pagesThis hook displays additional elements at the top of your pages - displayRightColumnProduct - Extra actions on the product page (right column). - + displayRightColumnProductNew elements on the product page (right column)This hook displays new elements in the right-hand column of the product page - actionProductDelete - Product deletion - This hook is called when a product is deleted + actionProductDeleteProduct deletionThis hook is called when a product is deleted - displayFooterProduct - Product footer - Add new blocks under the product description + displayFooterProductProduct footerThis hook adds new blocks under the product's description - displayInvoice - Invoice - Add blocks to invoice (order) + displayInvoiceInvoiceThis hook displays new blocks on the invoice (order) - actionOrderStatusUpdate - Order's status update event - Launch modules when the order's status of an order change. + actionOrderStatusUpdateOrder status update - EventThis hook launches modules when the status of an order changes. - displayAdminOrder - Display in Back-Office, tab AdminOrder - Launch modules when the tab AdminOrder is displayed on back-office. + displayAdminOrderDisplay new elements in the Back Office, tab AdminOrderThis hook launches modules when the AdminOrder" tab is displayed in the Back Office" - displayFooter - Footer - Add block in footer + displayFooterFooterThis hook displays new blocks in the footer - displayPDFInvoice - PDF Invoice - Allow the display of extra informations into the PDF invoice + displayPDFInvoicePDF InvoiceThis hook allows you to display additional information on PDF invoices - displayAdminCustomers - Display in Back-Office, tab AdminCustomers - Launch modules when the tab AdminCustomers is displayed on back-office. + displayAdminCustomersDisplay new elements in the Back Office, tab AdminCustomersThis hook launches modules when the AdminCustomers" tab is displayed in the Back Office" - displayOrderConfirmation - Order confirmation page - Called on order confirmation page + displayOrderConfirmationOrder confirmation pageThis hook is called within an order's confirmation page - actionCustomerAccountAdd - Successful customer create account - Called when new customer create account successfuled + actionCustomerAccountAddSuccessful customer account creationThis hook is called when a new customer creates an account successfully - displayCustomerAccount - Customer account page display in front office - Display on page account of the customer + displayCustomerAccountCustomer account displayed in Front OfficeThis hook displays new elements on the customer account page - actionOrderSlipAdd - Called when a order slip is created - Called when a quantity of one product change in an order. + actionOrderSlipAddOrder slip creationThis hook is called when a product's quantity is modified - displayProductTab - Tabs on product page - Called on order product page tabs + displayProductTabTabs on product pageThis hook is called on the product page's tab - displayProductTabContent - Content of tabs on product page - Called on order product page tabs + displayProductTabContentTabs content on the product pageThis hook is called on the product page's tab - displayShoppingCartFooter - Shopping cart footer - Display some specific informations on the shopping cart page + displayShoppingCartFooterShopping cart footerThis hook displays some specific information on the shopping cart's page - displayCustomerAccountForm - Customer account creation form - Display some information on the form to create a customer account + displayCustomerAccountFormCustomer account creation formThis hook displays some information on the form to create a customer account - displayAdminStatsModules - Stats - Modules - + displayAdminStatsModulesStats - Modules - displayAdminStatsGraphEngine - Graph Engines - + displayAdminStatsGraphEngineGraph engines - actionOrderReturn - Product returned - + actionOrderReturnReturned productThis hook is displayed when a customer returns a product - displayProductButtons - Product actions - Put new action buttons on product page + displayProductButtonsProduct page actionsThis hook adds new action buttons on the product page - displayBackOfficeHome - Administration panel homepage - + displayBackOfficeHomeAdministration panel homepageThis hook is displayed on the admin panel's homepage - displayAdminStatsGridEngine - Grid Engines - + displayAdminStatsGridEngineGrid engines - actionWatermark - Watermark - + actionWatermarkWatermark - actionProductCancel - Product cancelled - This hook is called when you cancel a product in an order + actionProductCancelProduct cancelledThis hook is called when you cancel a product in an order - displayLeftColumnProduct - Extra actions on the product page (left column). - + displayLeftColumnProductNew elements on the product page (left column)This hook displays new elements in the left-hand column of the product page - actionProductOutOfStock - Product out of stock - Make action while product is out of stock + actionProductOutOfStockOut-of-stock productThis hook displays new action buttons if a product is out of stock - actionProductAttributeUpdate - Product attribute update - + actionProductAttributeUpdateProduct attribute updateThis hook is displayed when a product's attribute is updated - displayCarrierList - Extra carrier (module mode) - + displayCarrierListExtra carrier (module mode) - displayShoppingCart - Shopping cart extra button - Display some specific informations + displayShoppingCartShopping cart - Additional buttonThis hook displays new action buttons within the shopping cart - actionSearch - Search - + actionSearchSearch - displayBeforePayment - Redirect in order process - Redirect user to the module instead of displaying payment modules + displayBeforePaymentRedirect during the order processThis hook redirects the user to the module instead of displaying payment modules - actionCarrierUpdate - Carrier Update - This hook is called when a carrier is updated + actionCarrierUpdateCarrier UpdateThis hook is called when a carrier is updated - actionOrderStatusPostUpdate - Post update of order status - + actionOrderStatusPostUpdatePost update of order status - displayCustomerAccountFormTop - Block above the form for create an account - + displayCustomerAccountFormTopBlock above the form for create an accountThis hook is displayed above the customer's account creation form - displayBackOfficeHeader - Administration panel header - + displayBackOfficeHeaderAdministration panel headerThis hook is displayed in the header of the admin panel - displayBackOfficeTop - Administration panel hover the tabs - + displayBackOfficeTopAdministration panel hover the tabsThis hook is displayed on the roll hover of the tabs within the admin panel - displayBackOfficeFooter - Administration panel footer - + displayBackOfficeFooterAdministration panel footerThis hook is displayed within the admin panel's footer - actionProductAttributeDelete - Product Attribute Deletion - + actionProductAttributeDeleteProduct attribute deletionThis hook is displayed when a product's attribute is deleted - actionCarrierProcess - Carrier Process - + actionCarrierProcessCarrier process - actionOrderDetail - Order Detail - To set the follow-up in smarty when order detail is called + actionOrderDetailOrder detailThis hook is used to set the follow-up in Smarty when an order's detail is called - displayBeforeCarrier - Before carrier list - This hook is display before the carrier list on Front office + displayBeforeCarrierBefore carriers listThis hook is displayed before the carrier list in Front Office - displayOrderDetail - Order detail displayed - Displayed on order detail on front office + displayOrderDetailOrder detailThis hook is displayed within the order's details in Front Office - actionPaymentCCAdd - Payment CC added - Payment CC added + actionPaymentCCAddPayment CC added - displayProductComparison - Extra Product Comparison - Extra Product Comparison + displayProductComparisonExtra product comparison - actionCategoryAdd - Category creation - + actionCategoryAddCategory creationThis hook is displayed when a category is created - actionCategoryUpdate - Category modification - + actionCategoryUpdateCategory modificationThis hook is displayed when a category is modified - actionCategoryDelete - Category removal - + actionCategoryDeleteCategory deletionThis hook is displayed when a category is deleted - actionBeforeAuthentication - Before Authentication - Before authentication + actionBeforeAuthenticationBefore authenticationThis hook is displayed before the customer's authentication - displayPaymentTop - Top of payment page - Top of payment page + displayPaymentTopTop of payment pageThis hook is displayed at the top of the payment page - actionHtaccessCreate - After htaccess creation - After htaccess creation + actionHtaccessCreateAfter htaccess creationThis hook is displayed after the htaccess creation - actionAdminMetaSave - After save configuration in AdminMeta - After save configuration in AdminMeta + actionAdminMetaSaveAfter saving the configuration in AdminMetaThis hook is displayed after saving the configuration in AdminMeta - displayAttributeGroupForm - Add fields to the form "attribute group" - Add fields to the form "attribute group" + displayAttributeGroupFormAdd fields to the form 'attribute group'This hook adds fields to the form 'attribute group' - actionAttributeGroupSave - On saving attribute group - On saving attribute group + actionAttributeGroupSaveSaving an attribute groupThis hook is called while saving an attributes group - actionAttributeGroupDelete - On deleting attribute group - On deleting attribute group + actionAttributeGroupDeleteDeleting attribute groupThis hook is called while deleting an attributes group - displayFeatureForm - Add fields to the form "feature" - Add fields to the form "feature" + displayFeatureFormAdd fields to the form 'feature'This hook adds fields to the form 'feature' - actionFeatureSave - On saving attribute feature - On saving attribute feature + actionFeatureSaveSaving attributes' featuresThis hook is called while saving an attributes features - actionFeatureDelete - On deleting attribute feature - On deleting attribute feature + actionFeatureDeleteDeleting attributes' featuresThis hook is called while deleting an attributes features - actionProductSave - On saving products - On saving products + actionProductSaveSaving productsThis hook is called while saving products - actionProductListOverride - Assign product list to a category - Assign product list to a category + actionProductListOverrideAssign a products list to a categoryThis hook assigns a products list to a category - displayAttributeGroupPostProcess - On post-process in admin attribute group - On post-process in admin attribute group + displayAttributeGroupPostProcessOn post-process in admin attribute groupThis hook is called on post-process in admin attribute group - displayFeaturePostProcess - On post-process in admin feature - On post-process in admin feature + displayFeaturePostProcessOn post-process in admin featureThis hook is called on post-process in admin feature - displayFeatureValueForm - Add fields to the form "feature value" - Add fields to the form "feature value" + displayFeatureValueFormAdd fields to the form 'feature value'This hook adds fields to the form 'feature value' - displayFeatureValuePostProcess - On post-process in admin feature value - On post-process in admin feature value + displayFeatureValuePostProcessOn post-process in admin feature valueThis hook is called on post-process in admin feature value - actionFeatureValueDelete - On deleting attribute feature value - On deleting attribute feature value + actionFeatureValueDeleteDeleting attributes' features' valuesThis hook is called while deleting an attributes features value - actionFeatureValueSave - On saving attribute feature value - On saving attribute feature value + actionFeatureValueSaveSaving an attributes features valueThis hook is called while saving an attributes features value - displayAttributeForm - Add fields to the form "attribute value" - Add fields to the form "attribute value" + displayAttributeFormAdd fields to the form 'attribute value'This hook adds fields to the form 'attribute value' - actionAttributePostProcess - On post-process in admin feature value - On post-process in admin feature value + actionAttributePostProcessOn post-process in admin feature valueThis hook is called on post-process in admin feature value - actionAttributeDelete - On deleting attribute feature value - On deleting attribute feature value + actionAttributeDeleteDeleting an attributes features valueThis hook is called while deleting an attributes features value - actionAttributeSave - On saving attribute feature value - On saving attribute feature value + actionAttributeSaveSaving an attributes features valueThis hook is called while saving an attributes features value - actionTaxManager - Tax Manager Factory - + actionTaxManagerTax Manager Factory - displayMyAccountBlock - My account block - Display extra informations inside the "my account" block + displayMyAccountBlockMy account blockThis hook displays extra information within the 'my account' block" diff --git a/install-dev/fixtures/apple/data/product.xml b/install-dev/fixtures/apple/data/product.xml index e04599d94..d852d0dcc 100644 --- a/install-dev/fixtures/apple/data/product.xml +++ b/install-dev/fixtures/apple/data/product.xml @@ -43,31 +43,31 @@ - + - + - + - + - + - + - + diff --git a/install-dev/init.php b/install-dev/init.php index 592b5963a..cf0d611ab 100644 --- a/install-dev/init.php +++ b/install-dev/init.php @@ -67,6 +67,9 @@ require_once(_PS_INSTALL_PATH_.'classes/simplexml.php'); if (!@ini_get('date.timezone')) @date_default_timezone_set('UTC'); +// Some hosting still have magic_quotes_runtime configured +ini_set('magic_quotes_runtime', 0); + // Try to improve memory limit if it's under 32M if (psinstall_get_memory_limit() < psinstall_get_octets('32M')) ini_set('memory_limit', '32M'); diff --git a/install-dev/langs/br/install.php b/install-dev/langs/br/install.php index e6724e2f2..0de7ae733 100644 --- a/install-dev/langs/br/install.php +++ b/install-dev/langs/br/install.php @@ -127,7 +127,7 @@ return array( 'Official forum' => 'Fórum oficial', 'Support' => 'Suporte', 'Documentation' => 'Documentação', - 'Contact us!' => 'Entre em Contato !', + 'Contact us' => 'Entre em Contato', 'Forum' => 'Fórum', 'Blog' => 'Blog', 'Done!' => 'Feito !', @@ -153,8 +153,8 @@ return array( 'If you need help, do not hesitate to check our documentation or to contact our support team: %2$s' => 'Se você precisar de ajuda, não deixe de visitar nossa documentação ou contatar nossa equipe de suporte : %2$s', 'Choose the installer language:' => 'Escolha a língua para instalação :', 'Did you know?' => 'Você sabia ?', - 'PrestaShop and its community offers over 40 different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop e sua comunidade oferece mais de 40 diferentes idiomas de graça, acessível diretamente a partir da sua Área Administrativa na aba localização.', - 'Licenses Agreement' => 'Acordo de licenças', + 'PrestaShop and its community offers over %d different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop e sua comunidade oferece mais de %d diferentes idiomas de graça, acessível diretamente a partir da sua Área Administrativa na aba localização.', + 'License Agreements' => 'Acordo de licença', 'PrestaShop core is released under the OSL 3.0 while PrestaShop modules and themes are released under the AFL 3.0.' => 'O núcleo PrestaShop é publicado sob a OSL 3.0 enquanto os módulos e temas são publicados sob a AFL 3.0.', 'I agree to the above terms and conditions.' => 'Eu concordo com os termos e condições acima.', 'I agree to participate in improving the solution by sending anonymous information about my configuration.' => 'Eu concordo em participar na melhoria da solução enviando informações anônimas sobre a minha configuração.', diff --git a/install-dev/langs/de/install.php b/install-dev/langs/de/install.php index 0b1e1fbac..56757e8df 100644 --- a/install-dev/langs/de/install.php +++ b/install-dev/langs/de/install.php @@ -121,7 +121,7 @@ 'Official forum' => 'Offizielles Forum', 'Support' => 'Support', 'Documentation' => 'Tutotrials', - 'Contact us!' => 'Kontaktieren Sie uns! Persönlicher Support', + 'Contact us' => 'Kontaktieren Sie uns', 'Forum' => 'Forum', 'Blog' => 'Blog', 'Done!' => 'Erfolgreich abgeschlossen', @@ -146,8 +146,8 @@ 'The installation process should take only few minutes!' => 'Der Installationsprozess dauert nur ein paar Minuten!', 'If you need help, do not hesitate to check our documentation or to contact our support team: %2$s' => 'Falls Sie Hilfe benötigen, haben Sie folgende Möglichkeiten: unsere Dokumentation einsehenoder unser Support-Team zu kontaktieren: %2$s', 'Did you know?' => 'Wussten Sie schon?', - 'PrestaShop and its community offers over 40 different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop und Community bietet Ihnen den kostenlosen Zugang zu über 40 verschiedenen Sprachen direkt aus Ihrem Back-office im Tabreiter "Tools"', - 'Licenses Agreement' => 'Lizenzvertrag', + 'PrestaShop and its community offers over %d different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop und Community bietet Ihnen den kostenlosen Zugang zu über %d verschiedenen Sprachen direkt aus Ihrem Back-office im Tabreiter "Tools"', + 'License Agreements' => 'Lizenzvertrag', 'PrestaShop core is released under the OSL 3.0 while PrestaShop modules and themes are released under the AFL 3.0.' => 'PrestaShop core is unter der Lizenz OSL 3.0 herausgegeben. PrestaShop modules und Themes werden unter der Lizenz AFL 3.0. herausgegeben', 'I agree to the above terms and conditions.' => 'Ich stimme den oben genannten Vertragsbedingungen zu.', 'I agree to participate in improving the solution by sending anonymous information about my configuration.' => 'Ich möchte Prestashop in der verbesserung von Fehlern helfen, und stimme zu, dass bei groben Fehlern meine Konfigurationsdaten an Prestashop gesandt werden', diff --git a/install-dev/langs/es/install.php b/install-dev/langs/es/install.php index 719039b28..e1f9aae5c 100644 --- a/install-dev/langs/es/install.php +++ b/install-dev/langs/es/install.php @@ -121,7 +121,7 @@ 'Official forum' => NULL, 'Support' => NULL, 'Documentation' => NULL, - 'Contact us!' => '¡Contacte con nosotros!', + 'Contact us' => 'Contacte con nosotros', 'Forum' => NULL, 'Blog' => 'El blog', 'Done!' => NULL, @@ -146,8 +146,8 @@ 'The installation process should take only few minutes!' => 'El proceso de instalación tardará solo unos minutos.', 'If you need help, do not hesitate to check our documentation or to contact our support team: %2$s' => NULL, 'Did you know?' => '¿Sabía que?', - 'PrestaShop and its community offers over 40 different languages for free, directly accessible from your Back Office on the Localization tab.' => NULL, - 'Licenses Agreement' => 'Contrato de Licencia', + 'PrestaShop and its community offers over %d different languages for free, directly accessible from your Back Office on the Localization tab.' => NULL, + 'License Agreements' => 'Contrato de Licencia', 'PrestaShop core is released under the OSL 3.0 while PrestaShop modules and themes are released under the AFL 3.0.' => NULL, 'I agree to the above terms and conditions.' => 'Estoy de acuerdo con los términos y condiciones.', 'I agree to participate in improving the solution by sending anonymous information about my configuration.' => NULL, diff --git a/install-dev/langs/fr/install.php b/install-dev/langs/fr/install.php index 28b0d1f40..080c09701 100644 --- a/install-dev/langs/fr/install.php +++ b/install-dev/langs/fr/install.php @@ -127,7 +127,7 @@ return array( 'Official forum' => 'Forum officiel', 'Support' => 'Support', 'Documentation' => 'Documentation', - 'Contact us!' => 'Nous contacter !', + 'Contact us' => 'Nous contacter', 'Forum' => 'Forum', 'Blog' => 'Blog', 'Done!' => 'Fin !', @@ -153,8 +153,8 @@ return array( 'If you need help, do not hesitate to check our documentation or to contact our support team: %2$s' => 'Si vous avez besoin d\'aide, n\'hésitez pas à visiter notre documentation ou à contacter notre équipe de support : %2$s', 'Choose the installer language:' => 'Choisissez la langue pour l\'installation :', 'Did you know?' => 'Le saviez vous ?', - 'PrestaShop and its community offers over 40 different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop et sa communauté vous proposent plus de 40 langues gratuites directement accessibles depuis votre administration', - 'Licenses Agreement' => 'Contrat de licences', + 'PrestaShop and its community offers over %d different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop et sa communauté vous proposent gratuitement des traductions dans %d langues directement accessibles depuis votre administration.', + 'License Agreements' => 'Contrats de licence', 'PrestaShop core is released under the OSL 3.0 while PrestaShop modules and themes are released under the AFL 3.0.' => 'Le cœur de PrestaShop est publié sous licence OSL 3.0 tandis que les modules et thèmes sont publiés sous licence AFL 3.0.', 'I agree to the above terms and conditions.' => 'J\'approuve les termes et conditions du contrat ci-dessus.', 'I agree to participate in improving the solution by sending anonymous information about my configuration.' => 'J\'accepte de participer à l\'amélioration de la solution en envoyant des informations anonymes sur ma configuration', diff --git a/install-dev/langs/it/install.php b/install-dev/langs/it/install.php index 994f45997..40b4bc925 100644 --- a/install-dev/langs/it/install.php +++ b/install-dev/langs/it/install.php @@ -121,7 +121,7 @@ 'Official forum' => 'Forum ufficiale', 'Support' => 'Supporto', 'Documentation' => 'Documentazione', - 'Contact us!' => 'Contattaci!', + 'Contact us' => 'Contattaci', 'Forum' => 'Forum', 'Blog' => 'Il blog', 'Done!' => 'Fatto!', @@ -146,8 +146,8 @@ 'The installation process should take only few minutes!' => 'Il processo di installazione dovrebbe durare solo pochi minuti!', 'If you need help, do not hesitate to check our documentation or to contact our support team: %2$s' => 'Se hai bisogno di aiuto non asitare a guardare our documentation o contattare il nostro supporto: %2$s', 'Did you know?' => 'Lo sapevi?', - 'PrestaShop and its community offers over 40 different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop e la sua comunità offre 40 diverse lingue gratuite, direttamente accessibile nel tuo back office nel tab Traduzioni', - 'Licenses Agreement' => 'Contratto di Licenza', + 'PrestaShop and its community offers over %d different languages for free, directly accessible from your Back Office on the Localization tab.' => 'PrestaShop e la sua comunità offre %d diverse lingue gratuite, direttamente accessibile nel tuo back office nel tab Traduzioni', + 'License Agreements' => 'Contratto di Licenza', 'PrestaShop core is released under the OSL 3.0 while PrestaShop modules and themes are released under the AFL 3.0.' => 'Il core di PrestaShop è rilasicata sollo licenza OSL 3.0 mentre i moduli e i temi prestashop sono rilasciati sotto licenza AFL 3.0', 'I agree to the above terms and conditions.' => 'Accetto i termini e le condizioni del contratto seguente.', 'I agree to participate in improving the solution by sending anonymous information about my configuration.' => 'Accetto di partecipare nell\'implementare la soluzione inviando informazioni anonime sulla mia configurazione', diff --git a/install-dev/models/database.php b/install-dev/models/database.php index 5bb2ca9c3..387713854 100644 --- a/install-dev/models/database.php +++ b/install-dev/models/database.php @@ -71,6 +71,12 @@ class InstallModelDatabase extends InstallAbstractModel // Check if a table with same prefix already exists if (!$clear && Db::hasTableWithSamePrefix($server, $login, $password, $database, $prefix)) $errors[] = $this->language->l('At least one table with same prefix was already found, please change your prefix or drop your database'); + if (($create_error = Db::checkCreatePrivilege($server, $login, $password, $database, $prefix, $engine)) !== true) + { + $errors[] = $this->language->l(sprintf('Your database login don\'t have the privileges to create table on the database "%s". Ask your hosting provider:', $database)); + if ($create_error != false) + $errors[] = $create_error; + } break; case 1: diff --git a/install-dev/theme/js/welcome.js b/install-dev/theme/js/welcome.js index fa2a9c467..69b8fd351 100644 --- a/install-dev/theme/js/welcome.js +++ b/install-dev/theme/js/welcome.js @@ -22,4 +22,9 @@ $(document).ready(function() else $('#btNext').addClass('disabled').attr('disabled', true); }); + + if ($('#set_license').prop('checked')) + $('#btNext').removeClass('disabled').attr('disabled', false); + else + $('#btNext').addClass('disabled').attr('disabled', true); }); \ No newline at end of file diff --git a/install-dev/theme/views/footer.phtml b/install-dev/theme/views/footer.phtml index 4107ab37a..f07434609 100644 --- a/install-dev/theme/views/footer.phtml +++ b/install-dev/theme/views/footer.phtml @@ -25,7 +25,7 @@
  • PrestaShop.com |
  • l('Support'); ?> |
  • l('Documentation'); ?> |
  • -
  • l('Contact us!'); ?> |
  • +
  • l('Contact us'); ?> |
  • © 2005-
  • @@ -104,13 +102,7 @@ $(function(){ldelim}

    - {if $vat_display == 2} -
    - {elseif $vat_display == 1} -