diff --git a/admin-dev/themes/default/template/controllers/products/informations.tpl b/admin-dev/themes/default/template/controllers/products/informations.tpl
index 8e56f4b88..93e92fc18 100644
--- a/admin-dev/themes/default/template/controllers/products/informations.tpl
+++ b/admin-dev/themes/default/template/controllers/products/informations.tpl
@@ -154,16 +154,57 @@
|
{include file="controllers/products/multishop/checkbox.tpl" field="visibility" type="default"}
diff --git a/classes/Product.php b/classes/Product.php
index 8af855564..e922dccd2 100644
--- a/classes/Product.php
+++ b/classes/Product.php
@@ -163,7 +163,13 @@ class ProductCore extends ObjectModel
/** @var boolean Product statuts */
public $active = true;
-
+
+ /** @var boolean Product statuts */
+ public $redirect_type = '';
+
+ /** @var boolean Product statuts */
+ public $id_product_redirected = 0;
+
/** @var boolean Product available for order */
public $available_for_order = true;
@@ -272,6 +278,8 @@ class ProductCore extends ObjectModel
'text_fields' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
'uploadable_files' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedInt'),
'active' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
+ 'redirect_type' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isString'),
+ 'id_product_redirected' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId'),
'available_for_order' => array('type' => self::TYPE_BOOL, 'shop' => true, 'validate' => 'isBool'),
'available_date' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'),
'condition' => array('type' => self::TYPE_STRING, 'shop' => true, 'validate' => 'isGenericName', 'values' => array('new', 'used', 'refurbished'), 'default' => 'new'),
diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php
index ae2b93f8d..603078137 100644
--- a/controllers/admin/AdminProductsController.php
+++ b/controllers/admin/AdminProductsController.php
@@ -3299,8 +3299,7 @@ class AdminProductsControllerCore extends AdminController
$data->assign('currency', $currency);
$this->object = $product;
$this->display = 'edit';
-
-
+ $data->assign('product_name_redirected', Product::getProductName((int)$product->id_product_redirected, null, (int)$this->context->language->id));
/*
* Form for adding a virtual product like software, mp3, etc...
*/
diff --git a/controllers/front/ProductController.php b/controllers/front/ProductController.php
index 0a3064a46..9ce391d2e 100644
--- a/controllers/front/ProductController.php
+++ b/controllers/front/ProductController.php
@@ -104,16 +104,45 @@ class ProductControllerCore extends FrontController
* allow showing the product
* In all the others cases => 404 "Product is no longer available"
*/
- if (!$this->product->isAssociatedToShop()
- || ((!$this->product->active && ((Tools::getValue('adtoken') != Tools::getAdminToken('AdminProducts'.(int)Tab::getIdFromClassName('AdminProducts').(int)Tools::getValue('id_employee')))
- || !file_exists(_PS_ROOT_DIR_.'/'.Tools::getValue('ad').'/index.php')))))
+ if (!$this->product->isAssociatedToShop() || !$this->product->active)
{
- header('HTTP/1.1 404 page not found');
- $this->errors[] = Tools::displayError('Product is no longer available.');
+ if (Tools::getValue('adtoken') == Tools::getAdminToken('AdminProducts'.(int)Tab::getIdFromClassName('AdminProducts').(int)Tools::getValue('id_employee')))
+ {
+ // If the product is not active, it's the admin preview mode
+ $this->context->smarty->assign('adminActionDisplay', true);
+ }
+ else
+ {
+ $this->context->smarty->assign('adminActionDisplay', false);
+ if ($this->product->id_product_redirected == $this->product->id)
+ $this->product->redirect_type = '404';
+
+ switch ($this->product->redirect_type)
+ {
+ case '301':
+ header('HTTP/1.1 301 Moved Permanently');
+ header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected));
+ break;
+ case '302':
+ header('HTTP/1.1 302 Moved Temporarily');
+ header('Cache-Control: no-cache');
+ header('Location: '.$this->context->link->getProductLink($this->product->id_product_redirected));
+ break;
+ case '404':
+ header('HTTP/1.1 404 Not Found');
+ header('Status: 404 Not Found');
+ $this->errors[] = Tools::displayError('Product is no longer available.');
+ break;
+ }
+ }
}
else if (!$this->product->checkAccess(isset($this->context->customer) ? $this->context->customer->id : 0))
+ {
+ header('HTTP/1.1 403 Forbidden');
+ header('Status: 403 Forbidden');
$this->errors[] = Tools::displayError('You do not have access to this product.');
-
+ }
+
// Load category
if (isset($_SERVER['HTTP_REFERER'])
&& !strstr($_SERVER['HTTP_REFERER'], Tools::getHttpHost()) // Assure us the previous page was one of the shop
@@ -150,10 +179,6 @@ class ProductControllerCore extends FrontController
// Assign to the template the id of the virtual product. "0" if the product is not downloadable.
$this->context->smarty->assign('virtual', ProductDownload::getIdFromIdProduct((int)$this->product->id));
- // If the product is not active, it's the admin preview mode
- if (!$this->product->active)
- $this->context->smarty->assign('adminActionDisplay', true);
-
// Product pictures management
require_once('images.inc.php');
$this->context->smarty->assign('customizationFormTarget', Tools::safeOutput(urldecode($_SERVER['REQUEST_URI'])));
diff --git a/install-dev/data/db_structure.sql b/install-dev/data/db_structure.sql
index d07b63842..bf5cbc15c 100644
--- a/install-dev/data/db_structure.sql
+++ b/install-dev/data/db_structure.sql
@@ -1376,6 +1376,8 @@ CREATE TABLE `PREFIX_product` (
`uploadable_files` tinyint(4) NOT NULL default '0',
`text_fields` tinyint(4) NOT NULL default '0',
`active` tinyint(1) unsigned NOT NULL default '0',
+ `redirect_type` ENUM('', '404', '301', '302') NOT NULL DEFAULT '',
+ `id_product_redirected` int(10) unsigned NOT NULL default '0',
`available_for_order` tinyint(1) NOT NULL default '1',
`available_date` date NOT NULL,
`condition` ENUM('new', 'used', 'refurbished') NOT NULL DEFAULT 'new',
@@ -1415,6 +1417,8 @@ CREATE TABLE IF NOT EXISTS `PREFIX_product_shop` (
`uploadable_files` tinyint(4) NOT NULL default '0',
`text_fields` tinyint(4) NOT NULL DEFAULT '0',
`active` tinyint(1) unsigned NOT NULL DEFAULT '0',
+ `redirect_type` ENUM('', '404', '301', '302') NOT NULL DEFAULT '',
+ `id_product_redirected` int(10) unsigned NOT NULL default '0',
`available_for_order` tinyint(1) NOT NULL DEFAULT '1',
`available_date` date NOT NULL,
`condition` enum('new','used','refurbished') NOT NULL DEFAULT 'new',
diff --git a/install-dev/fixtures/apple/data/product.xml b/install-dev/fixtures/apple/data/product.xml
index 227202823..e04599d94 100644
--- a/install-dev/fixtures/apple/data/product.xml
+++ b/install-dev/fixtures/apple/data/product.xml
@@ -29,6 +29,8 @@
+
+
@@ -41,31 +43,31 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/install-dev/upgrade/sql/1.5.2.1.sql b/install-dev/upgrade/sql/1.5.2.1.sql
index 7725a0b4a..8dea65958 100644
--- a/install-dev/upgrade/sql/1.5.2.1.sql
+++ b/install-dev/upgrade/sql/1.5.2.1.sql
@@ -6,4 +6,8 @@ ALTER TABLE `PREFIX_address` CHANGE `outstanding_allow_amount` `outstanding_all
/* PHP:block_category_1521(); */;
-UPDATE `PREFIX_order_state` SET `delivery` = 0 WHERE `id_order_state` = 3 ;
\ No newline at end of file
+UPDATE `PREFIX_order_state` SET `delivery` = 0 WHERE `id_order_state` = 3;
+
+ALTER TABLE `PREFIX_product_shop` ADD `id_product_redirected` int(10) unsigned NOT NULL default '0' AFTER `active` , ADD `available_for_order` tinyint(1) NOT NULL default '1' AFTER `id_product_redirected`;
+
+ALTER TABLE `PREFIX_product` ADD `id_product_redirected` int(10) unsigned NOT NULL default '0' AFTER `active` , ADD `available_for_order` tinyint(1) NOT NULL default '1' AFTER `id_product_redirected`;
\ No newline at end of file
diff --git a/js/admin-products.js b/js/admin-products.js
index 5701cc586..5b9789f35 100644
--- a/js/admin-products.js
+++ b/js/admin-products.js
@@ -763,9 +763,8 @@ product_tabs['Attachments'] = new function(){
product_tabs['Informations'] = new function(){
var self = this;
this.bindAvailableForOrder = function (){
- $("#available_for_order").click(function(){
-
-
+ $("#available_for_order").click(function()
+ {
if ($(this).is(':checked') || ($('input[name=\'multishop_check[show_price]\']').lenght && !$('input[name=\'multishop_check[show_price]\']').prop('checked')))
{
$('#show_price').attr('checked', true);
@@ -776,6 +775,34 @@ product_tabs['Informations'] = new function(){
$('#show_price').attr('disabled', false);
}
});
+
+ if ($('#active_on').prop('checked'))
+ showRedirectProductOptions(false);
+ else
+ showRedirectProductOptions(true);
+
+ $('#redirect_type').change(function () {
+ redirectSelectChange();
+ });
+
+ $('#related_product_autocomplete_input')
+ .autocomplete('ajax_products_list.php?excludeIds='+id_product, {
+ minChars: 1,
+ autoFill: true,
+ max:20,
+ matchContains: true,
+ mustMatch:true,
+ scroll:false,
+ cacheLength:0,
+ formatItem: function(item) {
+ return item[0]+' - '+item[1];
+ }
+ }).result(function(e, i){
+ if(i != undefined)
+ addRelatedProduct(i[1], i[0]);
+ $(this).val('');
+ });
+ addRelatedProduct(id_product_redirected, product_name_redirected);
};
this.bindTagImage = function (){
diff --git a/js/admin.js b/js/admin.js
index e6f85de01..34f6186e2 100644
--- a/js/admin.js
+++ b/js/admin.js
@@ -571,6 +571,56 @@ function toggleDraftWarning(show)
$('.draft').show();
}
+function showRedirectProductOptions(show)
+{
+ if (show)
+ $('.redirect_product_options').fadeIn();
+ else
+ $('.redirect_product_options').fadeOut();
+
+ redirectSelectChange();
+}
+
+function redirectSelectChange()
+{
+ if ($('#redirect_type :selected').val() == '404')
+ showRedirectProductSelectOptions(false);
+ else
+ showRedirectProductSelectOptions(true);
+}
+
+function addRelatedProduct(id_product_to_add, product_name)
+{
+ if (!id_product_to_add || id_product == id_product_to_add)
+ return;
+ $('#related_product_name').html(product_name);
+ $('#related_product_name').parent('p').css('margin-top', 0);
+ $('input[name=id_product_redirected]').val(id_product_to_add);
+ $('#related_product_autocomplete_input').hide();
+ $('#related_product_remove').show();
+}
+
+function removeRelatedProduct()
+{
+ $('#related_product_name').html(no_related_product);
+ $('#related_product_name').parent('p').css('margin-top', '0.5em');
+ $('input[name=id_product_redirected]').val(0);
+ $('#related_product_remove').hide();
+ $('#related_product_autocomplete_input').fadeIn();
+}
+
+function showRedirectProductSelectOptions(show)
+{
+ if (show)
+ $('.redirect_product_options_product_choise').show();
+ else
+ {
+ $('.redirect_product_options_product_choise').hide();
+ removeRelatedProduct();
+ }
+
+}
+
function showOptions(show)
{
if (show)
diff --git a/translations/br/admin.php b/translations/br/admin.php
new file mode 100644
index 000000000..3e9562c2b
--- /dev/null
+++ b/translations/br/admin.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/translations/br/errors.php b/translations/br/errors.php
new file mode 100644
index 000000000..604f75d22
--- /dev/null
+++ b/translations/br/errors.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/translations/br/fields.php b/translations/br/fields.php
new file mode 100644
index 000000000..03674f89c
--- /dev/null
+++ b/translations/br/fields.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/translations/br/pdf.php b/translations/br/pdf.php
new file mode 100644
index 000000000..9d9d1dac0
--- /dev/null
+++ b/translations/br/pdf.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
diff --git a/translations/br/tabs.php b/translations/br/tabs.php
new file mode 100644
index 000000000..83db297a2
--- /dev/null
+++ b/translations/br/tabs.php
@@ -0,0 +1,4 @@
+
\ No newline at end of file
|