+
+
+{$content}
+
+
+
+
diff --git a/admin-dev/themes/template/products/prices.tpl b/admin-dev/themes/template/products/prices.tpl
new file mode 100644
index 000000000..f36228a1b
--- /dev/null
+++ b/admin-dev/themes/template/products/prices.tpl
@@ -0,0 +1,59 @@
+
+
+
+
+
+ >
+
+ >
+
+ >
+
+
+
+
+
+ {l s='to'}
+
+
+
+
+
+ {l s='unit'}
+
+
+
+
+{$content}
diff --git a/cache/class_index.php b/cache/class_index.php
index bc744cf15..2d61c74d5 100644
--- a/cache/class_index.php
+++ b/cache/class_index.php
@@ -320,12 +320,19 @@
'AdminBackupController' => '',
'AdminCarriersControllerCore' => 'controllers/admin/AdminCarriersController.php',
'AdminCarriersController' => '',
+ 'AdminCatalogController' => 'controllers/admin/AdminCatalogController.php',
'AdminContactsControllerCore' => 'controllers/admin/AdminContactsController.php',
'AdminContactsController' => '',
+ 'AdminCountriesControllerCore' => 'controllers/admin/AdminCountriesController.php',
+ 'AdminCountriesController' => '',
'AdminCurrenciesControllerCore' => 'controllers/admin/AdminCurrenciesController.php',
'AdminCurrenciesController' => '',
'AdminDbControllerCore' => 'controllers/admin/AdminDbController.php',
'AdminDbController' => '',
+ 'AdminDeliverySlipControllerCore' => 'controllers/admin/AdminDeliverySlipController.php',
+ 'AdminDeliverySlipController' => '',
+ 'AdminEmailsControllerCore' => 'controllers/admin/AdminEmailsController.php',
+ 'AdminEmailsController' => '',
'AdminGendersController' => 'controllers/admin/AdminGendersController.php',
'AdminGroupShopControllerCore' => 'controllers/admin/AdminGroupShopController.php',
'AdminGroupShopController' => '',
@@ -333,10 +340,10 @@
'AdminHomeController' => 'override/controllers/admin/AdminHomeController.php',
'AdminImagesController' => 'controllers/admin/AdminImagesController.php',
'AdminOrderMessageController' => 'controllers/admin/AdminOrderMessageController.php',
+ 'AdminProductsController' => 'controllers/admin/AdminProductsController.php',
'AdminQuickAccessesController' => 'controllers/admin/AdminQuickAccessesController.php',
'AdminRequestSqlControllerCore' => 'controllers/admin/AdminRequestSqlController.php',
'AdminRequestSqlController' => '',
- 'AdminReturnStatesController' => 'controllers/admin/AdminReturnStatesController.php',
'AdminSearchEnginesControllerCore' => 'controllers/admin/AdminSearchEnginesController.php',
'AdminSearchEnginesController' => '',
'AdminShopUrlControllerCore' => 'controllers/admin/AdminShopUrlController.php',
@@ -345,13 +352,12 @@
'AdminStatesController' => '',
'AdminStockControllerCore' => 'controllers/admin/AdminStockController.php',
'AdminStockController' => '',
+ 'AdminStockCoverController' => 'controllers/admin/AdminStockCoverController.php',
'AdminStockInstantStateControllerCore' => 'controllers/admin/AdminStockInstantStateController.php',
'AdminStockInstantStateController' => '',
'AdminStockManagementController' => 'controllers/admin/AdminStockManagementController.php',
'AdminStoresControllerCore' => 'controllers/admin/AdminStoresController.php',
'AdminStoresController' => '',
- 'AdminTaxRulesGroupControllerCore' => 'controllers/admin/AdminTaxRulesGroupController.php',
- 'AdminTaxRulesGroupController' => '',
'AdminToolsControllerCore' => 'controllers/admin/AdminToolsController.php',
'AdminToolsController' => 'override/controllers/admin/AdminToolsController.php',
'AdminTrackingController' => 'controllers/admin/AdminTrackingController.php',
diff --git a/admin-dev/tabs/AdminCatalog.php b/controllers/admin/AdminCatalogController.php
similarity index 81%
rename from admin-dev/tabs/AdminCatalog.php
rename to controllers/admin/AdminCatalogController.php
index 9cde0e3a2..259fb1cc4 100644
--- a/admin-dev/tabs/AdminCatalog.php
+++ b/controllers/admin/AdminCatalogController.php
@@ -25,17 +25,14 @@
* International Registered Trademark & Property of PrestaShop SA
*/
-include_once(_PS_ADMIN_DIR_.'/../classes/AdminTab.php');
-include(_PS_ADMIN_DIR_.'/tabs/AdminCategories.php');
-include(_PS_ADMIN_DIR_.'/tabs/AdminProducts.php');
-class AdminCatalog extends AdminTab
+class AdminCatalogController extends AdminController
{
/** @var object AdminCategories() instance */
- private $adminCategories;
+ //private $adminCategories;
/** @var object AdminProducts() instance */
- private $adminProducts;
+ // private $adminProducts;
/** @var object AttributeGenerator() instance */
private $attributeGenerator;
@@ -73,8 +70,8 @@ class AdminCatalog extends AdminTab
die('Category cannot be loaded');
$this->table = array('category', 'product');
- $this->adminCategories = new AdminCategories();
- $this->adminProducts = new AdminProducts();
+ // $this->adminCategories = new AdminCategories();
+ // $this->adminProducts = new AdminProducts();
parent::__construct();
}
@@ -108,7 +105,7 @@ class AdminCatalog extends AdminTab
}
$this->attributeGenerator->postProcess();
}
- $this->adminProducts->postProcess($this->token);
+ // $this->adminProducts->postProcess($this->token);
}
public function ajaxProcess()
{
@@ -132,7 +129,7 @@ class AdminCatalog extends AdminTab
$this->imageResize->displayErrors();
}
- public function display()
+ public function initContent()
{
// @todo : this has to be dealt in AdminAttributeGenerator !!
if (isset($_GET['attributegenerator']))
@@ -160,13 +157,7 @@ class AdminCatalog extends AdminTab
if (Tools::getValue($tab.'Orderby') && Tools::getValue($tab.'Orderway'))
$catBarIndex = preg_replace('/&'.$tab.'Orderby=([a-z _]*)&'.$tab.'Orderway=([a-z]*)/i', '', self::$currentIndex);
- echo '
'.$this->l('Current category').' : '.getPath($catBarIndex, $id_category, '', '', 'catalog', $home).'
';
- //echo '
'.$this->l('Categories').'
';
- echo '
';
- //$this->adminCategories->display($this->token);
- echo '
';
- echo '
';
- //$this->adminProducts->display($this->token);
+ $this->context->smarty->assign('cat_bar',getPath($catBarIndex, $id_category, '', '', 'catalog', $home));
}
}
}
diff --git a/controllers/admin/AdminProductsController.php b/controllers/admin/AdminProductsController.php
new file mode 100644
index 000000000..26fdaf755
--- /dev/null
+++ b/controllers/admin/AdminProductsController.php
@@ -0,0 +1,4469 @@
+
+* @copyright 2007-2011 PrestaShop SA
+* @version Release: $Revision: 7331 $
+* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
+* International Registered Trademark & Property of PrestaShop SA
+*/
+include_once(_PS_ADMIN_DIR_.'/tabs/AdminProfiles.php');
+include_once('functions.php');
+
+class AdminProductsController extends AdminController
+{
+ protected $maxFileSize = 20000000;
+ /** @var integer Max image size for upload
+ * As of 1.5 it is recommended to not set a limit to max image size
+ **/
+ protected $maxImageSize;
+
+ private $_category;
+
+ protected $available_tabs = array('Informations', 'Images', 'Prices', 'Combinations', 'Features', 'Customization', 'Attachments', 'Quantities');
+
+ public function __construct()
+ {
+ $this->table = 'product';
+ $this->className = 'Product';
+ $this->lang = true;
+ $this->edit = true;
+ $this->delete = true;
+ $this->view = false;
+ $this->duplicate = true;
+ $this->imageType = 'jpg';
+ $this->context = Context::getContext();
+
+ $this->fieldsDisplay = array(
+ 'id_product' => array('title' => $this->l('ID'), 'align' => 'center', 'width' => 20),
+ 'image' => array('title' => $this->l('Photo'), 'align' => 'center', 'image' => 'p', 'width' => 45, 'orderby' => false, 'filter' => false, 'search' => false),
+ 'name' => array('title' => $this->l('Name'), 'width' => 200, 'filter_key' => 'b!name'),
+ 'reference' => array('title' => $this->l('Reference'), 'align' => 'center', 'width' => 20),
+ 'name_category' => array('title' => $this->l('Category'), 'width' => 100, 'filter_key' => 'cl!name'),
+ 'price' => array('title' => $this->l('Base price'), 'width' => 70, 'price' => true, 'align' => 'right', 'filter_key' => 'a!price'),
+ 'price_final' => array('title' => $this->l('Final price'), 'width' => 70, 'price' => true, 'align' => 'right', 'havingFilter' => true, 'orderby' => false),
+ 'quantity' => array('title' => $this->l('Quantity'), 'width' => 30, 'align' => 'right', 'filter_key' => 'a!quantity', 'type' => 'decimal'),
+ 'active' => array('title' => $this->l('Displayed'), 'active' => 'status', 'filter_key' => 'a!active', 'align' => 'center', 'type' => 'bool', 'orderby' => false),
+ 'position' => array('title' => $this->l('Position'), 'width' => 40,'filter_key' => 'cp!position', 'align' => 'center', 'position' => 'position'),
+ );
+
+ /* Join categories table */
+ if ($id_category = Tools::getvalue('id_category'))
+ $this->_category = new Category($id_category);
+ else
+ $this->_category = new Category(1);
+
+ $this->_join = Product::sqlStock('a').'
+ LEFT JOIN `'._DB_PREFIX_.'category_lang` cl ON (a.`id_category_default` = cl.`id_category` AND b.`id_lang` = cl.`id_lang`)
+ LEFT JOIN `'._DB_PREFIX_.'image` i ON (i.`id_product` = a.`id_product` AND i.`cover` = 1)
+ LEFT JOIN `'._DB_PREFIX_.'category_product` cp ON (cp.`id_product` = a.`id_product`)
+ LEFT JOIN `'._DB_PREFIX_.'tax_rule` tr ON (a.`id_tax_rules_group` = tr.`id_tax_rules_group` AND tr.`id_country` = '.(int)$this->context->country->id.' AND tr.`id_state` = 0)
+ LEFT JOIN `'._DB_PREFIX_.'tax` t ON (t.`id_tax` = tr.`id_tax`)';
+ $this->_filter = 'AND cp.`id_category` = '.(int)($this->_category->id);
+ $this->_select = 'cl.name `name_category`, cp.`position`, i.`id_image`, (a.`price` * ((100 + (t.`rate`))/100)) AS price_final, SUM(stock.quantity) AS quantity';
+
+ parent::__construct();
+ }
+ private function _cleanMetaKeywords($keywords)
+ {
+ if (!empty($keywords) && $keywords != '')
+ {
+ $out = array();
+ $words = explode(',', $keywords);
+ foreach ($words as $word_item)
+ {
+ $word_item = trim($word_item);
+ if (!empty($word_item) && $word_item != '')
+ $out[] = $word_item;
+ }
+ return ((count($out) > 0) ? implode(',', $out) : '');
+ }
+ else
+ return '';
+ }
+
+ protected function copyFromPost(&$object, $table)
+ {
+ parent::copyFromPost($object, $table);
+ if (get_class($object) != 'Product')
+ return;
+
+ /* Additional fields */
+ $languages = Language::getLanguages(false);
+ foreach ($languages as $language)
+ if (isset($_POST['meta_keywords_'.$language['id_lang']]))
+ {
+ $_POST['meta_keywords_'.$language['id_lang']] = $this->_cleanMetaKeywords(Tools::strtolower($_POST['meta_keywords_'.$language['id_lang']])); // preg_replace('/ *,? +,* /', ',', strtolower($_POST['meta_keywords_'.$language['id_lang']]));
+ $object->meta_keywords[$language['id_lang']] = $_POST['meta_keywords_'.$language['id_lang']];
+ }
+ $_POST['width'] = empty($_POST['width']) ? '0' : str_replace(',', '.', $_POST['width']);
+ $_POST['height'] = empty($_POST['height']) ? '0' : str_replace(',', '.', $_POST['height']);
+ $_POST['depth'] = empty($_POST['depth']) ? '0' : str_replace(',', '.', $_POST['depth']);
+ $_POST['weight'] = empty($_POST['weight']) ? '0' : str_replace(',', '.', $_POST['weight']);
+ if ($_POST['unit_price'] != null)
+ $object->unit_price = str_replace(',', '.', $_POST['unit_price']);
+ if (array_key_exists('ecotax', $_POST) && $_POST['ecotax'] != null)
+ $object->ecotax = str_replace(',', '.', $_POST['ecotax']);
+ $object->available_for_order = (int)(Tools::isSubmit('available_for_order'));
+ $object->show_price = $object->available_for_order ? 1 : (int)(Tools::isSubmit('show_price'));
+ $object->on_sale = Tools::isSubmit('on_sale');
+ $object->online_only = Tools::isSubmit('online_only');
+ }
+
+ public function getList($id_lang, $orderBy = null, $orderWay = null, $start = 0, $limit = null, $id_lang_shop = null)
+ {
+ $orderByPriceFinal = (empty($orderBy) ? ($this->context->cookie->__get($this->table.'Orderby') ? $this->context->cookie->__get($this->table.'Orderby') : 'id_'.$this->table) : $orderBy);
+ $orderWayPriceFinal = (empty($orderWay) ? ($this->context->cookie->__get($this->table.'Orderway') ? $this->context->cookie->__get($this->table.'Orderby') : 'ASC') : $orderWay);
+ if ($orderByPriceFinal == 'price_final')
+ {
+ $orderBy = 'id_'.$this->table;
+ $orderWay = 'ASC';
+ }
+ parent::getList($id_lang, $orderBy, $orderWay, $start, $limit, $id_lang_shop);
+
+ /* update product quantity with attributes ...*/
+ $nb = count($this->_list);
+ if ($this->_list)
+ {
+ /* update product final price */
+ for ($i = 0; $i < $nb; $i++)
+ $this->_list[$i]['price_tmp'] = Product::getPriceStatic($this->_list[$i]['id_product'], true, null, 6, null, false, true, 1, true);
+ }
+
+ if ($orderByPriceFinal == 'price_final')
+ {
+ if (strtolower($orderWayPriceFinal) == 'desc')
+ uasort($this->_list, 'cmpPriceDesc');
+ else
+ uasort($this->_list, 'cmpPriceAsc');
+ }
+ for ($i = 0; $this->_list && $i < $nb; $i++)
+ {
+ $this->_list[$i]['price_final'] = $this->_list[$i]['price_tmp'];
+ unset($this->_list[$i]['price_tmp']);
+ }
+ }
+
+ public function deleteVirtualProduct()
+ {
+ if (!($id_product_download = ProductDownload::getIdFromIdProduct((int)Tools::getValue('id_product'))))
+ return false;
+ $productDownload = new ProductDownload((int)($id_product_download));
+ return $productDownload->deleteFile();
+ }
+
+ public function deleteVirtualProductAttribute()
+ {
+ if (!($id_product_download = ProductDownload::getIdFromIdAttribute((int)Tools::getValue('id_product'), (int) Tools::getValue('id_product_attribute'))))
+ return false;
+ $productDownload = new ProductDownload((int)($id_product_download));
+ return $productDownload->deleteFile();
+ }
+
+ /**
+ * postProcess handle every checks before saving products information
+ *
+ * @param mixed $token
+ * @return void
+ */
+ public function postProcess($token = null)
+ {
+ /* Add a new product */
+ if (Tools::isSubmit('submitAddproduct') || Tools::isSubmit('submitAddproductAndStay') || Tools::isSubmit('submitAddProductAndPreview'))
+ {
+ if ((Tools::getValue('id_product') && $this->tabAccess['edit'] === '1') || ($this->tabAccess['add'] === '1' && !Tools::isSubmit('id_product')))
+ $this->submitAddproduct($token);
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to add here.');
+ }
+ /* Delete a product in the download folder */
+ else if (Tools::getValue('deleteVirtualProduct'))
+ {
+ if ($this->tabAccess['delete'] === '1')
+ $this->deleteVirtualProduct();
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+ else
+ /* Delete a product in the download folder */
+ if (Tools::getValue('deleteVirtualProductAttribute'))
+ {
+ if ($this->tabAccess['delete'] === '1')
+ $this->deleteVirtualProductAttribute();
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+
+ /* Update attachments */
+ else if (Tools::isSubmit('submitAddAttachments'))
+ {
+ if ($this->tabAccess['add'] === '1')
+ {
+ $languages = Language::getLanguages(false);
+ $is_attachment_name_valid = false;
+ foreach ($languages as $language)
+ {
+ $attachment_name_lang = Tools::getValue('attachment_name_'.(int)($language['id_lang']));
+ if (strlen($attachment_name_lang ) > 0)
+ $is_attachment_name_valid = true;
+
+ if (!Validate::isGenericName(Tools::getValue('attachment_name_'.(int)($language['id_lang']))))
+ $this->_errors[] = Tools::displayError('Invalid Name');
+ else if (Tools::strlen(Tools::getValue('attachment_name_'.(int)($language['id_lang']))) > 32)
+ $this->_errors[] = Tools::displayError('Name is too long');
+ if (!Validate::isCleanHtml(Tools::getValue('attachment_description_'.(int)($language['id_lang']))))
+ $this->_errors[] = Tools::displayError('Invalid description');
+ }
+ if (!$is_attachment_name_valid)
+ $this->_errors[] = Tools::displayError('Attachment Name Required');
+
+ if (empty($this->_errors))
+ {
+ if (isset($_FILES['attachment_file']) && is_uploaded_file($_FILES['attachment_file']['tmp_name']))
+ {
+ if ($_FILES['attachment_file']['size'] > (Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024 * 1024))
+ $this->_errors[] = $this->l('File too large, maximum size allowed:').' '.(Configuration::get('PS_ATTACHMENT_MAXIMUM_SIZE') * 1024).' '.$this->l('kb').'. '.$this->l('File size you\'re trying to upload is:').number_format(($_FILES['attachment_file']['size']/1024), 2, '.', '').$this->l('kb');
+ else
+ {
+ do $uniqid = sha1(microtime()); while (file_exists(_PS_DOWNLOAD_DIR_.$uniqid));
+ if (!copy($_FILES['attachment_file']['tmp_name'], _PS_DOWNLOAD_DIR_.$uniqid))
+ $this->_errors[] = $this->l('File copy failed');
+ @unlink($_FILES['attachment_file']['tmp_name']);
+ }
+ }
+ else if ((int)$_FILES['attachment_file']['error'] === 1)
+ {
+ $max_upload = (int)(ini_get('upload_max_filesize'));
+ $max_post = (int)(ini_get('post_max_size'));
+ $upload_mb = min($max_upload, $max_post);
+ $this->_errors[] = $this->l('the File').'
'.$_FILES['attachment_file']['name'].' '.$this->l('exceeds the size allowed by the server, this limit is set to').'
'.$upload_mb.$this->l('Mb').'';
+ }
+
+ if (empty($this->_errors) && isset($uniqid))
+ {
+ $attachment = new Attachment();
+ foreach ($languages as $language)
+ {
+ if (isset($_POST['attachment_name_'.(int)($language['id_lang'])]))
+ $attachment->name[(int)($language['id_lang'])] = pSQL($_POST['attachment_name_'.(int)($language['id_lang'])]);
+ if (isset($_POST['attachment_description_'.(int)($language['id_lang'])]))
+ $attachment->description[(int)($language['id_lang'])] = pSQL($_POST['attachment_description_'.(int)($language['id_lang'])]);
+ }
+ $attachment->file = $uniqid;
+ $attachment->mime = $_FILES['attachment_file']['type'];
+ $attachment->file_name = pSQL($_FILES['attachment_file']['name']);
+ if (empty($attachment->mime) || Tools::strlen($attachment->mime) > 128)
+ $this->_errors[] = Tools::displayError('Invalid file extension');
+ if (!Validate::isGenericName($attachment->file_name))
+ $this->_errors[] = Tools::displayError('Invalid file name');
+ if (Tools::strlen($attachment->file_name) > 128)
+ $this->_errors[] = Tools::displayError('File name too long');
+ if (!sizeof($this->_errors))
+ {
+ $attachment->add();
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.(int)(Tools::getValue($this->identifier)).'&id_category='.(int)(Tools::getValue('id_category')).'&addproduct&conf=4&tabs=6&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Invalid file');
+ }
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to add here.');
+ }
+ else if (Tools::isSubmit('submitAttachments'))
+ {
+ if ($this->tabAccess['edit'] === '1')
+ if ($id = (int)(Tools::getValue($this->identifier)))
+ if (Attachment::attachToProduct($id, Tools::getValue('attachments')))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.(int)$id.(isset($_POST['id_category']) ? '&id_category='.(int)$_POST['id_category'] : '').'&conf=4&add'.$this->table.'&tabs=6&token='.($token ? $token : $this->token));
+ }
+
+ /* Product duplication */
+ else if (isset($_GET['duplicate'.$this->table]))
+ {
+ if ($this->tabAccess['add'] === '1')
+ {
+ if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product')))))
+ {
+ $id_product_old = $product->id;
+ unset($product->id);
+ unset($product->id_product);
+ $product->indexed = 0;
+ $product->active = 0;
+ if ($product->add()
+ && Category::duplicateProductCategories($id_product_old, $product->id)
+ && ($combinationImages = Product::duplicateAttributes($id_product_old, $product->id)) !== false
+ && GroupReduction::duplicateReduction($id_product_old, $product->id)
+ && Product::duplicateAccessories($id_product_old, $product->id)
+ && Product::duplicateFeatures($id_product_old, $product->id)
+ && Product::duplicateSpecificPrices($id_product_old, $product->id)
+ && Pack::duplicate($id_product_old, $product->id)
+ && Product::duplicateCustomizationFields($id_product_old, $product->id)
+ && Product::duplicateTags($id_product_old, $product->id)
+ && Product::duplicateDownload($id_product_old, $product->id)
+ && $product->duplicateShops($id_product_old))
+ {
+ if ($product->hasAttributes())
+ Product::updateDefaultAttribute($product->id);
+
+ if (!Tools::getValue('noimage') && !Image::duplicateProductImages($id_product_old, $product->id, $combinationImages))
+ $this->_errors[] = Tools::displayError('An error occurred while copying images.');
+ else
+ {
+ Hook::addProduct($product);
+ Search::indexation(false, $product->id);
+ Tools::redirectAdmin(self::$currentIndex.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&conf=19&token='.($token ? $token : $this->token));
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while creating object.');
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to add here.');
+ }
+ /* Change object statuts (active, inactive) */
+ else if (isset($_GET['status']) && Tools::getValue($this->identifier))
+ {
+ if ($this->tabAccess['edit'] === '1')
+ {
+ if (Validate::isLoadedObject($object = $this->loadObject()))
+ {
+ if ($object->toggleStatus())
+ Tools::redirectAdmin(self::$currentIndex.'&conf=5'.((($id_category = (!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1')) && Tools::getValue('id_product')) ? '&id_category='.$id_category : '').'&token='.$token);
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while updating status.');
+ }
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while updating status for object.').'
'.$this->table.' '.Tools::displayError('(cannot load object)');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to edit here.');
+ }
+ /* Delete object */
+ else if (isset($_GET['delete'.$this->table]))
+ {
+ if ($this->tabAccess['delete'] === '1')
+ {
+ if (Validate::isLoadedObject($object = $this->loadObject()) && isset($this->fieldImageSettings))
+ {
+ // check if request at least one object with noZeroObject
+ if (isset($object->noZeroObject) && sizeof($taxes = call_user_func(array($this->className, $object->noZeroObject))) <= 1)
+ $this->_errors[] = Tools::displayError('You need at least one object.').'
'.$this->table.''.Tools::displayError('You cannot delete all of the items.');
+ else
+ {
+ $id_category = Tools::getValue('id_category');
+ $category_url = empty($id_category) ? '' : '&id_category='.$id_category;
+
+ if ($this->deleted)
+ {
+ $object->deleteImages();
+ $object->deleted = 1;
+ if ($object->update())
+ Tools::redirectAdmin(self::$currentIndex.'&conf=1&token='.($token ? $token : $this->token).$category_url);
+ }
+ else if ($object->delete())
+ Tools::redirectAdmin(self::$currentIndex.'&conf=1&token='.($token ? $token : $this->token).$category_url);
+ $this->_errors[] = Tools::displayError('An error occurred during deletion.');
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while deleting object.').'
'.$this->table.' '.Tools::displayError('(cannot load object)');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+
+ /* Delete multiple objects */
+ else if (Tools::getValue('submitDel'.$this->table))
+ {
+ if ($this->tabAccess['delete'] === '1')
+ {
+ if (isset($_POST[$this->table.'Box']))
+ {
+ $object = new $this->className();
+
+ if (isset($object->noZeroObject) &&
+ // Check if all object will be deleted
+ (sizeof(call_user_func(array($this->className, $object->noZeroObject))) <= 1 || sizeof($_POST[$this->table.'Box']) == sizeof(call_user_func(array($this->className, $object->noZeroObject)))))
+ $this->_errors[] = Tools::displayError('You need at least one object.').'
'.$this->table.''.Tools::displayError('You cannot delete all of the items.');
+ else
+ {
+ $result = true;
+ if ($this->deleted)
+ {
+ foreach (Tools::getValue($this->table.'Box') as $id)
+ {
+ $toDelete = new $this->className($id);
+ $toDelete->deleted = 1;
+ $result = $result && $toDelete->update();
+ }
+ }
+ else
+ $result = $object->deleteSelection(Tools::getValue($this->table.'Box'));
+
+ if ($result)
+ {
+ $id_category = Tools::getValue('id_category');
+ $category_url = empty($id_category) ? '' : '&id_category='.$id_category;
+
+ Tools::redirectAdmin(self::$currentIndex.'&conf=2&token='.$token.$category_url);
+ }
+ $this->_errors[] = Tools::displayError('An error occurred while deleting selection.');
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You must select at least one element to delete.');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+
+ /* Product images management */
+ else if (($id_image = (int)(Tools::getValue('id_image'))) && Validate::isUnsignedId($id_image) && Validate::isLoadedObject($image = new Image($id_image)))
+ {
+ if ($this->tabAccess['edit'] === '1')
+ {
+ /* Delete product image */
+ if (isset($_GET['deleteImage']) || $this->action == 'deleteImage')
+ {
+ $image->delete();
+
+ if (!Image::getCover($image->id_product))
+ {
+ $first_img = Db::getInstance()->getRow('
+ SELECT `id_image` FROM `'._DB_PREFIX_.'image`
+ WHERE `id_product` = '.(int)($image->id_product));
+ Db::getInstance()->Execute('
+ UPDATE `'._DB_PREFIX_.'image`
+ SET `cover` = 1
+ WHERE `id_image` = '.(int)($first_img['id_image']));
+ }
+ @unlink(_PS_TMP_IMG_DIR_.'/product_'.$image->id_product.'.jpg');
+ @unlink(_PS_TMP_IMG_DIR_.'/product_mini_'.$image->id_product.'.jpg');
+ if (!$this->ajax)
+ Tools::redirectAdmin($currentIndex.'&id_product='.$image->id_product.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&add'.$this->table.'&tabs=1'.'&token='.($token ? $token : $this->token));
+ }
+
+ /* Update product image/legend */
+ else if (isset($_GET['editImage']))
+ {
+ if ($image->cover)
+ $_POST['cover'] = 1;
+ $languages = Language::getLanguages(false);
+ foreach ($languages as $language)
+ if (isset($image->legend[$language['id_lang']]))
+ $_POST['legend_'.$language['id_lang']] = $image->legend[$language['id_lang']];
+ $_POST['id_image'] = $image->id;
+ // @todo in postProcess, we should avoid displayForm
+ $this->content .= $this->displayForm();
+ }
+
+ /* Choose product cover image */
+ else if (isset($_GET['coverImage']))
+ {
+ Image::deleteCover($image->id_product);
+ $image->cover = 1;
+ if (!$image->update())
+ $this->_errors[] = Tools::displayError('Cannot change the product cover');
+ else
+ {
+ $productId = (int)(Tools::getValue('id_product'));
+ @unlink(_PS_TMP_IMG_DIR_.'/product_'.$productId.'.jpg');
+ @unlink(_PS_TMP_IMG_DIR_.'/product_mini_'.$productId.'.jpg');
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$image->id_product.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&addproduct&tabs=1'.'&token='.($token ? $token : $this->token));
+ }
+ }
+
+ /* Choose product image position */
+ else if (isset($_GET['imgPosition']) && isset($_GET['imgDirection']))
+ {
+ $image->updatePosition(Tools::getValue('imgDirection'), Tools::getValue('imgPosition'));
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$image->id_product.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&add'.$this->table.'&tabs=1&token='.($token ? $token : $this->token));
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to edit here.');
+ }
+
+ /* Product attributes management */
+ else if (Tools::isSubmit('submitProductAttribute'))
+ {
+ if (!Combination::isFeatureActive())
+ return;
+
+ $is_virtual = (int)Tools::getValue('is_virtual');
+
+ if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product')))))
+ {
+ if (!isset($_POST['attribute_price']) || $_POST['attribute_price'] == null)
+ $this->_errors[] = Tools::displayError('Attribute price required.');
+ if (!isset($_POST['attribute_combinaison_list']) || !sizeof($_POST['attribute_combinaison_list']))
+ $this->_errors[] = Tools::displayError('You must add at least one attribute.');
+
+ if (!sizeof($this->_errors))
+ {
+ if (!isset($_POST['attribute_wholesale_price'])) $_POST['attribute_wholesale_price'] = 0;
+ if (!isset($_POST['attribute_price_impact'])) $_POST['attribute_price_impact'] = 0;
+ if (!isset($_POST['attribute_weight_impact'])) $_POST['attribute_weight_impact'] = 0;
+ if (!isset($_POST['attribute_ecotax'])) $_POST['attribute_ecotax'] = 0;
+ if (Tools::getValue('attribute_default'))
+ $product->deleteDefaultAttributes();
+ // Change existing one
+ if ($id_product_attribute = (int)(Tools::getValue('id_product_attribute')))
+ {
+ if ($this->tabAccess['edit'] === '1')
+ {
+ if ($product->productAttributeExists($_POST['attribute_combinaison_list'], $id_product_attribute))
+ $this->_errors[] = Tools::displayError('This attribute already exists.');
+ else
+ {
+ if (Validate::isDateFormat(Tools::getValue('available_date')))
+ {
+ $product->updateProductAttribute($id_product_attribute,
+ Tools::getValue('attribute_wholesale_price'),
+ Tools::getValue('attribute_price') * Tools::getValue('attribute_price_impact'),
+ Tools::getValue('attribute_weight') * Tools::getValue('attribute_weight_impact'),
+ Tools::getValue('attribute_unity') * Tools::getValue('attribute_unit_impact'),
+ Tools::getValue('attribute_ecotax'),
+ false,
+ Tools::getValue('id_image_attr'),
+ Tools::getValue('attribute_reference'),
+ Tools::getValue('attribute_supplier_reference'),
+ Tools::getValue('attribute_ean13'),
+ Tools::getValue('attribute_default'),
+ Tools::getValue('attribute_location'),
+ Tools::getValue('attribute_upc'),
+ Tools::getValue('minimal_quantity'),
+ Tools::getValue('available_date'));
+
+ if ($id_reason = (int)Tools::getValue('id_mvt_reason') && (int)Tools::getValue('attribute_mvt_quantity') > 0 && $id_reason > 0)
+ {
+ if (!$product->addStockMvt(Tools::getValue('attribute_mvt_quantity'), $id_reason, $id_product_attribute, null, $this->context->employee->id))
+ $this->_errors[] = Tools::displayError('An error occurred while updating qty.');
+ }
+ Hook::updateProductAttribute((int)$id_product_attribute);
+ $this->updateDownloadProduct($product, 1, $id_product_attribute);
+ }
+ else
+ {
+ $this->_errors[] = Tools::displayError('Invalid date format.');
+ }
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to add here.');
+ }
+ // Add new
+ else
+ {
+ if ($this->tabAccess['add'] === '1')
+ {
+ if ($product->productAttributeExists($_POST['attribute_combinaison_list']))
+ $this->_errors[] = Tools::displayError('This combination already exists.');
+ else
+ $id_product_attribute = $product->addCombinationEntity(
+ Tools::getValue('attribute_wholesale_price'),
+ Tools::getValue('attribute_price') * Tools::getValue('attribute_price_impact'),
+ Tools::getValue('attribute_weight') * Tools::getValue('attribute_weight_impact'),
+ Tools::getValue('attribute_unity') * Tools::getValue('attribute_unit_impact'),
+ Tools::getValue('attribute_ecotax'),
+ Tools::getValue('attribute_quantity'),
+ Tools::getValue('id_image_attr'),
+ Tools::getValue('attribute_reference'),
+ Tools::getValue('attribute_supplier_reference'),
+ Tools::getValue('attribute_ean13'),
+ Tools::getValue('attribute_default'),
+ Tools::getValue('attribute_location'),
+ Tools::getValue('attribute_upc')
+ );
+ $this->updateDownloadProduct($product, 0, $id_product_attribute);
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to').'
'.Tools::displayError('Edit here.');
+ }
+ if (!sizeof($this->_errors))
+ {
+ $product->addAttributeCombinaison($id_product_attribute, Tools::getValue('attribute_combinaison_list'));
+ $product->checkDefaultAttributes();
+ }
+ if (!sizeof($this->_errors))
+ {
+ if (!$product->cache_default_attribute)
+ Product::updateDefaultAttribute($product->id);
+
+ if (!empty($is_virtual))
+ Product::updateIsVirtual($product->id);
+
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$product->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&add'.$this->table.'&tabs=3&token='.($token ? $token : $this->token));
+ }
+ }
+ }
+ }
+ else if (Tools::isSubmit('deleteProductAttribute'))
+ {
+ if (!Combination::isFeatureActive())
+ return;
+ if ($this->tabAccess['delete'] === '1')
+ {
+ if (($id_product = (int)(Tools::getValue('id_product'))) && Validate::isUnsignedId($id_product) && Validate::isLoadedObject($product = new Product($id_product)))
+ {
+ $product->deleteAttributeCombinaison(Tools::getValue('id_product_attribute'));
+
+ $id_product_download = ProductDownload::getIdFromIdAttribute((int) $id_product, (int) Tools::getValue('id_product_attribute'));
+ if ($id_product_download)
+ {
+ $productDownload = new ProductDownload((int) $id_product_download);
+ $this->deleteDownloadProduct((int) $id_product_download);
+ $productDownload->deleteFile();
+ }
+ $product->checkDefaultAttributes();
+ $product->updateQuantityProductWithAttributeQuantity();
+ if (!$product->hasAttributes())
+ {
+ $product->cache_default_attribute = 0;
+ $product->update();
+ }
+ else
+ Product::updateDefaultAttribute($id_product);
+
+ Tools::redirectAdmin(self::$currentIndex.'&add'.$this->table.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&tabs=3&id_product='.$product->id.'&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Cannot delete attribute');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+ else if (Tools::isSubmit('deleteAllProductAttributes'))
+ {
+ if (!Combination::isFeatureActive())
+ return;
+ if ($this->tabAccess['delete'] === '1')
+ {
+ if (($id_product = (int)(Tools::getValue('id_product'))) && Validate::isUnsignedId($id_product) && Validate::isLoadedObject($product = new Product($id_product)))
+ {
+ $product->deleteProductAttributes();
+ $product->updateQuantityProductWithAttributeQuantity();
+ if ($product->cache_default_attribute)
+ {
+ $product->cache_default_attribute = 0;
+ $product->update();
+ }
+ Tools::redirectAdmin(self::$currentIndex.'&add'.$this->table.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&tabs=3&id_product='.$product->id.'&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Cannot delete attributes');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+ else if (Tools::isSubmit('defaultProductAttribute'))
+ {
+ if (!Combination::isFeatureActive())
+ return;
+ if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product')))))
+ {
+ $product->deleteDefaultAttributes();
+ $product->setDefaultAttribute((int)(Tools::getValue('id_product_attribute')));
+ Tools::redirectAdmin(self::$currentIndex.'&add'.$this->table.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&tabs=3&id_product='.$product->id.'&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Cannot make default attribute');
+ }
+
+ /* Product features management */
+ else if (Tools::isSubmit('submitProductFeature'))
+ {
+ if (!Feature::isFeatureActive())
+ return;
+ if ($this->tabAccess['edit'] === '1')
+ {
+ if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product')))))
+ {
+ // delete all objects
+ $product->deleteFeatures();
+
+ // add new objects
+ $languages = Language::getLanguages(false);
+ foreach ($_POST as $key => $val)
+ {
+ if (preg_match('/^feature_([0-9]+)_value/i', $key, $match))
+ {
+ if ($val)
+ $product->addFeaturesToDB($match[1], $val);
+ else
+ {
+ if ($default_value = $this->checkFeatures($languages, $match[1]))
+ {
+ $id_value = $product->addFeaturesToDB($match[1], 0, 1, (int)$language['id_lang']);
+ foreach ($languages as $language)
+ {
+ if ($cust = Tools::getValue('custom_'.$match[1].'_'.(int)$language['id_lang']))
+ $product->addFeaturesCustomToDB($id_value, (int)$language['id_lang'], $cust);
+ else
+ $product->addFeaturesCustomToDB($id_value, (int)$language['id_lang'], $default_value);
+ }
+ }
+ }
+ }
+ }
+ if (!sizeof($this->_errors))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.(int)$product->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&add'.$this->table.'&tabs=4&conf=4&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Product must be created before adding features.');
+ }
+ $this->_errors[] = Tools::displayError('You do not have permission to edit here.');
+ }
+ /* Product specific prices management */
+ else if (Tools::isSubmit('submitPricesModification'))
+ {
+ $_POST['tabs'] = 5;
+ if ($this->tabAccess['edit'] === '1')
+ {
+ $id_specific_prices = Tools::getValue('spm_id_specific_price');
+ $id_shops = Tools::getValue('spm_id_shop');
+ $id_currencies = Tools::getValue('spm_id_currency');
+ $id_countries = Tools::getValue('spm_id_country');
+ $id_groups = Tools::getValue('spm_id_group');
+ $prices = Tools::getValue('spm_price');
+ $from_quantities = Tools::getValue('spm_from_quantity');
+ $reductions = Tools::getValue('spm_reduction');
+ $reduction_types = Tools::getValue('spm_reduction_type');
+ $froms = Tools::getValue('spm_from');
+ $tos = Tools::getValue('spm_to');
+
+ foreach ($id_specific_prices as $key => $id_specific_price)
+ if ($this->_validateSpecificPrice($id_shops[$key], $id_currencies[$key], $id_countries[$key], $id_groups[$key], $prices[$key], $from_quantities[$key], $reductions[$key], $reduction_types[$key], $froms[$key], $tos[$key]))
+ {
+ $specificPrice = new SpecificPrice((int)($id_specific_price));
+ $specificPrice->id_shop = (int)$id_shops[$key];
+ $specificPrice->id_currency = (int)($id_currencies[$key]);
+ $specificPrice->id_country = (int)($id_countries[$key]);
+ $specificPrice->id_group = (int)($id_groups[$key]);
+ $specificPrice->price = (float)($prices[$key]);
+ $specificPrice->from_quantity = (int)($from_quantities[$key]);
+ $specificPrice->reduction = (float)($reduction_types[$key] == 'percentage' ? ($reductions[$key] / 100) : $reductions[$key]);
+ $specificPrice->reduction_type = !$reductions[$key] ? 'amount' : $reduction_types[$key];
+ $specificPrice->from = !$froms[$key] ? '0000-00-00 00:00:00' : $froms[$key];
+ $specificPrice->to = !$tos[$key] ? '0000-00-00 00:00:00' : $tos[$key];
+ if (!$specificPrice->update())
+ $this->_errors = Tools::displayError('An error occurred while updating the specific price.');
+ }
+ if (!sizeof($this->_errors))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.(int)(Tools::getValue('id_product')).'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&update'.$this->table.'&tabs=2&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to add here.');
+ }
+ else if (Tools::isSubmit('submitPriceAddition'))
+ {
+ if ($this->tabAccess['add'] === '1')
+ {
+ $id_product = (int)(Tools::getValue('id_product'));
+ $id_shop = Tools::getValue('sp_id_shop');
+ $id_currency = Tools::getValue('sp_id_currency');
+ $id_country = Tools::getValue('sp_id_country');
+ $id_group = Tools::getValue('sp_id_group');
+ $price = Tools::getValue('sp_price');
+ $from_quantity = Tools::getValue('sp_from_quantity');
+ $reduction = (float)(Tools::getValue('sp_reduction'));
+ $reduction_type = !$reduction ? 'amount' : Tools::getValue('sp_reduction_type');
+ $from = Tools::getValue('sp_from');
+ $to = Tools::getValue('sp_to');
+ if ($this->_validateSpecificPrice($id_shop, $id_currency, $id_country, $id_group, $price, $from_quantity, $reduction, $reduction_type, $from, $to))
+ {
+ $specificPrice = new SpecificPrice();
+ $specificPrice->id_product = $id_product;
+ $specificPrice->id_shop = (int)$id_shop;
+ $specificPrice->id_currency = (int)($id_currency);
+ $specificPrice->id_country = (int)($id_country);
+ $specificPrice->id_group = (int)($id_group);
+ $specificPrice->price = (float)($price);
+ $specificPrice->from_quantity = (int)($from_quantity);
+ $specificPrice->reduction = (float)($reduction_type == 'percentage' ? $reduction / 100 : $reduction);
+ $specificPrice->reduction_type = $reduction_type;
+ $specificPrice->from = !$from ? '0000-00-00 00:00:00' : $from;
+ $specificPrice->to = !$to ? '0000-00-00 00:00:00' : $to;
+ if (!$specificPrice->add())
+ $this->_errors = Tools::displayError('An error occurred while updating the specific price.');
+ else
+ Tools::redirectAdmin(self::$currentIndex.(Tools::getValue('id_category') ? '&id_category='.Tools::getValue('id_category') : '').'&id_product='.$id_product.'&add'.$this->table.'&tabs=2&conf=3&token='.($token ? $token : $this->token));
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to add here.');
+ }
+ else if (Tools::isSubmit('deleteSpecificPrice'))
+ {
+ if ($this->tabAccess['delete'] === '1')
+ {
+ if (!($obj = $this->loadObject()))
+ return;
+ if (!$id_specific_price = Tools::getValue('id_specific_price') || !Validate::isUnsignedId($id_specific_price))
+ $this->_errors[] = Tools::displayError('Invalid specific price ID');
+ else
+ {
+ $specificPrice = new SpecificPrice((int)($id_specific_price));
+ if (!$specificPrice->delete())
+ $this->_errors[] = Tools::displayError('An error occurred while deleting the specific price');
+ else
+ Tools::redirectAdmin(self::$currentIndex.(Tools::getValue('id_category') ? '&id_category='.Tools::getValue('id_category') : '').'&id_product='.$obj->id.'&add'.$this->table.'&tabs=2&conf=1&token='.($token ? $token : $this->token));
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to delete here.');
+ }
+ else if (Tools::isSubmit('submitSpecificPricePriorities'))
+ {
+ if (!($obj = $this->loadObject()))
+ return;
+ if (!$priorities = Tools::getValue('specificPricePriority'))
+ $this->_errors[] = Tools::displayError('Please specify priorities');
+ else if (Tools::isSubmit('specificPricePriorityToAll'))
+ {
+ if (!SpecificPrice::setPriorities($priorities))
+ $this->_errors[] = Tools::displayError('An error occurred while updating priorities.');
+ else
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$obj->id.'&add'.$this->table.'&tabs=2&conf=4&token='.($token ? $token : $this->token));
+ }
+ else if (!SpecificPrice::setSpecificPriority((int)($obj->id), $priorities))
+ $this->_errors[] = Tools::displayError('An error occurred while setting priorities.');
+ else
+ Tools::redirectAdmin(self::$currentIndex.(Tools::getValue('id_category') ? '&id_category='.Tools::getValue('id_category') : '').'&id_product='.$obj->id.'&add'.$this->table.'&tabs=2&conf=4&token='.($token ? $token : $this->token));
+ }
+ /* Customization management */
+ else if (Tools::isSubmit('submitCustomizationConfiguration'))
+ {
+ if ($this->tabAccess['edit'] === '1')
+ {
+ if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product')))))
+ {
+ if (!$product->createLabels((int)($_POST['uploadable_files']) - (int)($product->uploadable_files), (int)($_POST['text_fields']) - (int)($product->text_fields)))
+ $this->_errors[] = Tools::displayError('An error occurred while creating customization fields.');
+ if (!sizeof($this->_errors) && !$product->updateLabels())
+ $this->_errors[] = Tools::displayError('An error occurred while updating customization.');
+ $product->uploadable_files = (int)($_POST['uploadable_files']);
+ $product->text_fields = (int)($_POST['text_fields']);
+ $product->customizable = ((int)($_POST['uploadable_files']) > 0 || (int)($_POST['text_fields']) > 0) ? 1 : 0;
+ if (!sizeof($this->_errors) && !$product->update())
+ $this->_errors[] = Tools::displayError('An error occurred while updating customization configuration.');
+ if (!sizeof($this->_errors))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$product->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&add'.$this->table.'&tabs=5&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Product must be created before adding customization possibilities.');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to edit here.');
+ }
+ else if (Tools::isSubmit('submitProductCustomization'))
+ {
+ if ($this->tabAccess['edit'] === '1')
+ {
+ if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product')))))
+ {
+ foreach ($_POST as $field => $value)
+ if (strncmp($field, 'label_', 6) == 0 && !Validate::isLabel($value))
+ $this->_errors[] = Tools::displayError('Label fields are invalid');
+ if (!sizeof($this->_errors) && !$product->updateLabels())
+ $this->_errors[] = Tools::displayError('An error occurred while updating customization.');
+ if (!sizeof($this->_errors))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$product->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&add'.$this->table.'&tabs=5&token='.($token ? $token : $this->token));
+ }
+ else
+ $this->_errors[] = Tools::displayError('Product must be created before adding customization possibilities.');
+ }
+ else
+ $this->_errors[] = Tools::displayError('You do not have permission to edit here.');
+ }
+ else if (isset($_GET['position']))
+ {
+ if ($this->tabAccess['edit'] !== '1')
+ $this->_errors[] = Tools::displayError('You do not have permission to edit here.');
+ else if (!Validate::isLoadedObject($object = $this->loadObject()))
+ $this->_errors[] = Tools::displayError('An error occurred while updating status for object.').'
'.$this->table.' '.Tools::displayError('(cannot load object)');
+ if (!$object->updatePosition((int)(Tools::getValue('way')), (int)(Tools::getValue('position'))))
+ $this->_errors[] = Tools::displayError('Failed to update the position.');
+ else
+ Tools::redirectAdmin(self::$currentIndex.'&'.$this->table.'Orderby=position&'.$this->table.'Orderway=asc&conf=5'.(($id_category = (!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1')) ? ('&id_category='.$id_category) : '').'&token='.Tools::getAdminTokenLite('AdminProducts'));
+ }
+ else
+ parent::postProcess(true);
+ }
+
+ public function ajaxPreProcess()
+ {
+ $this->action = Tools::getValue('action');
+ if (Tools::getValue('addImage') !== false)
+ {
+ self::$currentIndex = 'index.php?tab=AdminProducts';
+ $allowedExtensions = array("jpeg", "gif", "png", "jpg");
+ // max file size in bytes
+ $sizeLimit = $this->maxFileSize;
+ $uploader = new FileUploader($allowedExtensions, $sizeLimit);
+ $result = $uploader->handleUpload();
+ if (isset($result['success']))
+ {
+ $shops = false;
+ if (Shop::isFeatureActive())
+ $shops = Shop::getShops();
+ $obj = new Product((int)Tools::getValue('id_product'));
+ $countImages = (int)Db::getInstance()->getValue('SELECT COUNT(id_product) FROM '._DB_PREFIX_.'image WHERE id_product = '.(int)$obj->id);
+ $images = Image::getImages($this->context->language->id, $obj->id);
+ $imagesTotal = Image::getImagesTotal($obj->id);
+ $html = $this->getLineTableImage($result['success'], $imagesTotal + 1, $this->token, $shops);
+ die(Tools::jsonEncode(array("success" => $html)));
+ }
+ else
+ die(Tools::jsonEncode($result));
+ }
+
+ if (Tools::getValue('updateProductImageShopAsso'))
+ {
+ if ($id_image = (int)Tools::getValue('id_image') && $id_shop = (int)Tools::getValue('id_shop'))
+ if (Tools::getValue('active') == "true")
+ die(Db::getInstance()->execute('INSERT INTO '._DB_PREFIX_.'image_shop (`id_image`, `id_shop`) VALUES('.(int)$id_image.', '.(int)$id_shop.')'));
+ else
+ die(Db::getInstance()->execute('DELETE FROM '._DB_PREFIX_.'image_shop WHERE `id_image`='.(int)$id_image.' && `id_shop`='.(int)$id_shop));
+ }
+
+
+
+ }
+
+ public function ajaxProcessDeleteImage()
+ {
+if (false)
+{
+ $image = new Image((int)Tools::getValue('id_image'));
+ $image->delete();
+ if (!Image::getCover($image->id_product))
+ {
+ $first_img = Db::getInstance()->getRow('
+ SELECT `id_image` FROM `'._DB_PREFIX_.'image`
+ WHERE `id_product` = '.(int)($image->id_product));
+ Db::getInstance()->execute('
+ UPDATE `'._DB_PREFIX_.'image`
+ SET `cover` = 1
+ WHERE `id_image` = '.(int)($first_img['id_image']));
+ }
+ @unlink(_PS_TMP_IMG_DIR_.'/product_'.$image->id_product.'.jpg');
+ @unlink(_PS_TMP_IMG_DIR_.'/product_mini_'.$image->id_product.'.jpg');
+ }
+ $this->content = '{deleted:1}';
+ die("deleted");
+ }
+
+ protected function _validateSpecificPrice($id_shop, $id_currency, $id_country, $id_group, $price, $from_quantity, $reduction, $reduction_type, $from, $to)
+ {
+ if (!Validate::isUnsignedId($id_shop) || !Validate::isUnsignedId($id_currency) || !Validate::isUnsignedId($id_country) || !Validate::isUnsignedId($id_group))
+ $this->_errors[] = Tools::displayError('Wrong ID\'s');
+ else if ((empty($price) && empty($reduction)) || (!empty($price) && !Validate::isPrice($price)) || (!empty($reduction) && !Validate::isPrice($reduction)))
+ $this->_errors[] = Tools::displayError('Invalid price/reduction amount');
+ else if (!Validate::isUnsignedInt($from_quantity))
+ $this->_errors[] = Tools::displayError('Invalid quantity');
+ else if ($reduction && !Validate::isReductionType($reduction_type))
+ $this->_errors[] = Tools::displayError('Please select a reduction type (amount or percentage)');
+ else if ($from && $to && (!Validate::isDateFormat($from) || !Validate::isDateFormat($to)))
+ $this->_errors[] = Tools::displayError('Wrong from/to date');
+ else
+ return true;
+ return false;
+ }
+
+ // Checking customs feature
+ private function checkFeatures($languages, $feature_id)
+ {
+ $rules = call_user_func(array('FeatureValue', 'getValidationRules'), 'FeatureValue');
+ $feature = Feature::getFeature(Configuration::get('PS_LANG_DEFAULT'), $feature_id);
+ $val = 0;
+ foreach ($languages as $language)
+ if ($val = Tools::getValue('custom_'.$feature_id.'_'.$language['id_lang']))
+ {
+ $currentLanguage = new Language($language['id_lang']);
+ if (Tools::strlen($val) > $rules['sizeLang']['value'])
+ $this->_errors[] = Tools::displayError('name for feature').'
'.$feature['name'].' '.Tools::displayError('is too long in').' '.$currentLanguage->name;
+ else if (!call_user_func(array('Validate', $rules['validateLang']['value']), $val))
+ $this->_errors[] = Tools::displayError('Valid name required for feature.').'
'.$feature['name'].' '.Tools::displayError('in').' '.$currentLanguage->name;
+ if (sizeof($this->_errors))
+ return (0);
+ // Getting default language
+ if ($language['id_lang'] == Configuration::get('PS_LANG_DEFAULT'))
+ return ($val);
+ }
+ return (0);
+ }
+
+
+ /**
+ * Add or update a product image
+ *
+ * @param object $product Product object to add image
+ */
+ public function addProductImage($product, $method = 'auto')
+ {
+ /* Updating an existing product image */
+ if ($id_image = ((int)(Tools::getValue('id_image'))))
+ {
+ $image = new Image($id_image);
+ if (!Validate::isLoadedObject($image))
+ $this->_errors[] = Tools::displayError('An error occurred while loading object image.');
+ else
+ {
+ if (($cover = Tools::getValue('cover')) == 1)
+ Image::deleteCover($product->id);
+ $image->cover = $cover;
+ $this->validateRules('Image');
+ $this->copyFromPost($image, 'image');
+ if (sizeof($this->_errors) || !$image->update())
+ $this->_errors[] = Tools::displayError('An error occurred while updating image.');
+ else if (isset($_FILES['image_product']['tmp_name']) && $_FILES['image_product']['tmp_name'] != null)
+ $this->copyImage($product->id, $image->id, $method);
+ }
+ }
+ if (isset($image) && Validate::isLoadedObject($image) && !file_exists(_PS_PROD_IMG_DIR_.$image->getExistingImgPath().'.'.$image->image_format))
+ $image->delete();
+ if (sizeof($this->_errors))
+ return false;
+ @unlink(_PS_TMP_IMG_DIR_.'/product_'.$product->id.'.jpg');
+ @unlink(_PS_TMP_IMG_DIR_.'/product_mini_'.$product->id.'.jpg');
+ return ((isset($id_image) && is_int($id_image) && $id_image) ? $id_image : true);
+ }
+ /**
+ * Copy a product image
+ *
+ * @param integer $id_product Product Id for product image filename
+ * @param integer $id_image Image Id for product image filename
+ */
+ public function copyImage($id_product, $id_image, $method = 'auto')
+ {
+ if (!isset($_FILES['image_product']['tmp_name']))
+ return false;
+ if ($error = checkImage($_FILES['image_product']))
+ $this->_errors[] = $error;
+ else
+ {
+ $image = new Image($id_image);
+
+ if (!$new_path = $image->getPathForCreation())
+ $this->_errors[] = Tools::displayError('An error occurred during new folder creation');
+ if (!$tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS') || !move_uploaded_file($_FILES['image_product']['tmp_name'], $tmpName))
+ $this->_errors[] = Tools::displayError('An error occurred during the image upload');
+ else if (!imageResize($tmpName, $new_path.'.'.$image->image_format))
+ $this->_errors[] = Tools::displayError('An error occurred while copying image.');
+ else if ($method == 'auto')
+ {
+ $imagesTypes = ImageType::getImagesTypes('products');
+ foreach ($imagesTypes as $k => $imageType)
+ if (!imageResize($tmpName, $new_path.'-'.stripslashes($imageType['name']).'.'.$image->image_format, $imageType['width'], $imageType['height'], $image->image_format))
+ $this->_errors[] = Tools::displayError('An error occurred while copying image:').' '.stripslashes($imageType['name']);
+ }
+
+ @unlink($tmpName);
+ Module::hookExec('watermark', array('id_image' => $id_image, 'id_product' => $id_product));
+ }
+ }
+
+ /**
+ * Add or update a product
+ */
+ public function submitAddProduct($token = null)
+ {
+ $className = 'Product';
+ $rules = call_user_func(array($this->className, 'getValidationRules'), $this->className);
+ $defaultLanguage = $this->context->language;
+ $languages = Language::getLanguages(false);
+
+ /* Check required fields */
+ foreach ($rules['required'] as $field)
+ if (($value = Tools::getValue($field)) == false && $value != '0')
+ {
+ if (Tools::getValue('id_'.$this->table) && $field == 'passwd')
+ continue;
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), $field, $className).' '.$this->l('is required');
+ }
+
+ /* Check multilingual required fields */
+ foreach ($rules['requiredLang'] as $fieldLang)
+ if (!Tools::getValue($fieldLang.'_'.$defaultLanguage->id))
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), $fieldLang, $className).' '.$this->l('is required at least in').' '.$defaultLanguage->name;
+
+ /* Check fields sizes */
+ foreach ($rules['size'] as $field => $maxLength)
+ if ($value = Tools::getValue($field) && Tools::strlen($value) > $maxLength)
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), $field, $className).' '.$this->l('is too long').' ('.$maxLength.' '.$this->l('chars max').')';
+
+ if (isset($_POST['description_short']))
+ {
+ $saveShort = $_POST['description_short'];
+ $_POST['description_short'] = strip_tags($_POST['description_short']);
+ }
+
+ /* Check description short size without html */
+ $limit = (int)Configuration::get('PS_PRODUCT_SHORT_DESC_LIMIT');
+ if ($limit <= 0) $limit = 400;
+ foreach ($languages as $language)
+ if ($value = Tools::getValue('description_short_'.$language['id_lang']))
+ if (Tools::strlen(strip_tags($value)) > $limit)
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), 'description_short').' ('.$language['name'].') '.$this->l('is too long').' : '.$limit.' '.$this->l('chars max').' ('.$this->l('count now').' '.Tools::strlen(strip_tags($value)).')';
+ /* Check multilingual fields sizes */
+ foreach ($rules['sizeLang'] as $fieldLang => $maxLength)
+ foreach ($languages as $language)
+ if ($value = Tools::getValue($fieldLang.'_'.$language['id_lang']) && Tools::strlen($value) > $maxLength)
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), $fieldLang, $className).' ('.$language['name'].') '.$this->l('is too long').' ('.$maxLength.' '.$this->l('chars max').')';
+ if (isset($_POST['description_short']))
+ $_POST['description_short'] = $saveShort;
+
+ /* Check fields validity */
+ foreach ($rules['validate'] as $field => $function)
+ if ($value = Tools::getValue($field))
+ if (!Validate::$function($value))
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), $field, $className).' '.$this->l('is invalid');
+
+ /* Check multilingual fields validity */
+ foreach ($rules['validateLang'] as $fieldLang => $function)
+ foreach ($languages as $language)
+ if ($value = Tools::getValue($fieldLang.'_'.$language['id_lang']))
+ if (!Validate::$function($value))
+ $this->_errors[] = $this->l('the field').'
'.call_user_func(array($className, 'displayFieldName'), $fieldLang, $className).' ('.$language['name'].') '.$this->l('is invalid');
+
+ /* Categories */
+ $productCats = '';
+ if (!Tools::isSubmit('categoryBox') || !sizeof(Tools::getValue('categoryBox')))
+ $this->_errors[] = $this->l('product must be in at least one Category');
+
+ if (!is_array(Tools::getValue('categoryBox')) || !in_array(Tools::getValue('id_category_default'), Tools::getValue('categoryBox')))
+ $this->_errors[] = $this->l('product must be in the default category');
+
+ /* Tags */
+ foreach ($languages as $language)
+ if ($value = Tools::getValue('tags_'.$language['id_lang']))
+ if (!Validate::isTagsList($value))
+ $this->_errors[] = $this->l('Tags list').' ('.$language['name'].') '.$this->l('is invalid');
+
+ if (!sizeof($this->_errors))
+ {
+ $id = (int)Tools::getValue('id_'.$this->table);
+ $tagError = true;
+
+ /* Update an existing product */
+ if (isset($id) && !empty($id))
+ {
+ $object = new $this->className($id);
+ if (Validate::isLoadedObject($object))
+ {
+ $this->_removeTaxFromEcotax();
+ $this->copyFromPost($object, $this->table);
+ if ($object->update())
+ {
+ if ($id_reason = (int)Tools::getValue('id_mvt_reason') && Tools::getValue('mvt_quantity') > 0 && $id_reason > 0)
+ {
+ if (!$object->addStockMvt(Tools::getValue('mvt_quantity'), $id_reason, null, null, $this->context->employee->id))
+ $this->_errors[] = Tools::displayError('An error occurred while updating qty.');
+ }
+ $this->updateAccessories($object);
+ $this->updateDownloadProduct($object, 1);
+ $this->updateAssoShop((int)$object->id);
+
+ if (!$this->updatePackItems($object))
+ $this->_errors[] = Tools::displayError('An error occurred while adding products to the pack.');
+ else if (!$object->updateCategories($_POST['categoryBox'], true))
+ $this->_errors[] = Tools::displayError('An error occurred while linking object.').'
'.$this->table.' '.Tools::displayError('To categories');
+ else if (!$this->updateTags($languages, $object))
+ $this->_errors[] = Tools::displayError('An error occurred while adding tags.');
+ else if ($id_image = $this->addProductImage($object, Tools::getValue('resizer')))
+ {
+ self::$currentIndex .= '&image_updated='.(int)Tools::getValue('id_image');
+ Hook::updateProduct($object);
+ Search::indexation(false, $object->id);
+ if (Tools::getValue('resizer') == 'man' && isset($id_image) && is_int($id_image) && $id_image)
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$object->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&edit='.strval(Tools::getValue('productCreated')).'&id_image='.$id_image.'&imageresize&toconf=4&submitAddAndStay='.((Tools::isSubmit('submitAdd'.$this->table.'AndStay') || Tools::getValue('productCreated') == 'on') ? 'on' : 'off').'&token='.(($token ? $token : $this->token)));
+
+ // Save and preview
+ if (Tools::isSubmit('submitAddProductAndPreview'))
+ {
+ $preview_url = $this->context->link->getProductLink($this->getFieldValue($object, 'id'), $this->getFieldValue($object, 'link_rewrite', $this->context->language->id), Category::getLinkRewrite($this->getFieldValue($object, 'id_category_default'), $this->context->language->id), null, null, Context::getContext()->shop->getID());
+ if (!$object->active)
+ {
+ $admin_dir = dirname($_SERVER['PHP_SELF']);
+ $admin_dir = substr($admin_dir, strrpos($admin_dir,'/') + 1);
+ $token = Tools::encrypt('PreviewProduct'.$object->id);
+ if (strpos($preview_url, '?') === false)
+ $preview_url .= '?';
+ else
+ $preview_url .= '&';
+ $preview_url .= 'adtoken='.$token.'&ad='.$admin_dir;
+ }
+ Tools::redirectAdmin($preview_url);
+ } else if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') || ($id_image && $id_image !== true)) // Save and stay on same form
+ // Save and stay on same form
+ if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$object->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&addproduct&conf=4&tabs='.(int)(Tools::getValue('tabs')).'&token='.($token ? $token : $this->token));
+
+ // Default behavior (save and back)
+ Tools::redirectAdmin(self::$currentIndex.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&conf=4&token='.($token ? $token : $this->token).'&onredirigeici');
+ }
+ }
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while updating object.').'
'.$this->table.' ('.Db::getInstance()->getMsgError().')';
+ }
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while updating object.').'
'.$this->table.' ('.Tools::displayError('Cannot load object').')';
+ }
+
+ /* Add a new product */
+ else
+ {
+ $object = new $this->className();
+ $this->_removeTaxFromEcotax();
+ $this->copyFromPost($object, $this->table);
+ if ($object->add())
+ {
+ $this->updateAssoShop((int)$object->id);
+ $this->updateAccessories($object);
+ if (!$this->updatePackItems($object))
+ $this->_errors[] = Tools::displayError('An error occurred while adding products to the pack.');
+ $this->updateDownloadProduct($object);
+ if (!sizeof($this->_errors))
+ {
+ if (!$object->updateCategories($_POST['categoryBox']))
+ $this->_errors[] = Tools::displayError('An error occurred while linking object.').'
'.$this->table.' '.Tools::displayError('To categories');
+ else if (!$this->updateTags($languages, $object))
+ $this->_errors[] = Tools::displayError('An error occurred while adding tags.');
+ else if ($id_image = $this->addProductImage($object))
+ {
+ Hook::addProduct($object);
+ Search::indexation(false, $object->id);
+
+ // Save and preview
+ if (Tools::isSubmit('submitAddProductAndPreview'))
+ {
+ $preview_url = ($this->context->link->getProductLink($this->getFieldValue($object, 'id'), $this->getFieldValue($object, 'link_rewrite', $this->context->language->id), Category::getLinkRewrite($this->getFieldValue($object, 'id_category_default'), $this->context->language->id)));
+ if (!$object->active)
+ {
+ $admin_dir = dirname($_SERVER['PHP_SELF']);
+ $admin_dir = substr($admin_dir, strrpos($admin_dir,'/') + 1);
+ $token = Tools::encrypt('PreviewProduct'.$object->id);
+ $preview_url .= '&adtoken='.$token.'&ad='.$admin_dir;
+ }
+
+ Tools::redirectAdmin($preview_url);
+ }
+
+ if (Tools::getValue('resizer') == 'man' && isset($id_image) && is_int($id_image) && $id_image)
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$object->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&id_image='.$id_image.'&imageresize&toconf=3&submitAddAndStay='.(Tools::isSubmit('submitAdd'.$this->table.'AndStay') ? 'on' : 'off').'&token='.(($token ? $token : $this->token)));
+ // Save and stay on same form
+ if (Tools::isSubmit('submitAdd'.$this->table.'AndStay'))
+ Tools::redirectAdmin(self::$currentIndex.'&id_product='.$object->id.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&addproduct&conf=3&tabs='.(int)(Tools::getValue('tabs')).'&token='.($token ? $token : $this->token));
+ // Default behavior (save and back)
+ Tools::redirectAdmin(self::$currentIndex.'&id_category='.(!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1').'&conf=3&token='.($token ? $token : $this->token));
+ }
+ }
+ else
+ $object->delete();
+ }
+ else
+ $this->_errors[] = Tools::displayError('An error occurred while creating object.').'
'.$this->table.'';
+ }
+ }
+
+ }
+
+ private function _removeTaxFromEcotax()
+ {
+ $ecotaxTaxRate = Tax::getProductEcotaxRate();
+ if ($ecotax = Tools::getValue('ecotax'))
+ $_POST['ecotax'] = Tools::ps_round(Tools::getValue('ecotax') / (1 + $ecotaxTaxRate / 100), 6);
+ }
+
+ private function _applyTaxToEcotax($product)
+ {
+ $ecotaxTaxRate = Tax::getProductEcotaxRate();
+ if ($product->ecotax)
+ $product->ecotax = Tools::ps_round($product->ecotax * (1 + $ecotaxTaxRate / 100), 2);
+ }
+
+ /**
+ * Update product download
+ *
+ * @param object $product Product
+ * @return bool
+ */
+ public function updateDownloadProduct($product, $edit = 0, $id_product_attribute = null)
+ {
+ $is_virtual_file = (int) Tools::getValue('is_virtual_file');
+
+ /* add or update a virtual product */
+ if (Tools::getValue('is_virtual_good') == 'true')
+ {
+ if (!Tools::getValue('virtual_product_name') && !Tools::getValue('virtual_product_name_attribute') && !empty($is_virtual_file))
+ {
+ if (!Tools::getValue('virtual_product_name'))
+ {
+ if (!Tools::getValue('virtual_product_name_attribute') && !empty($id_product_attribute))
+ {
+ $this->_errors[] = $this->l('the field').'
'.$this->l('display filename attribute').' '.$this->l('is required');
+ return false;
+ }
+ else if (!empty($id_product_attribute))
+ {
+ $this->_errors[] = $this->l('the field').'
'.$this->l('display filename').' '.$this->l('is required');
+ return false;
+ }
+ }
+ }
+
+ if (Tools::getValue('virtual_product_nb_days') === false && Tools::getValue('virtual_product_nb_days_attribute') === false && !empty($is_virtual_file))
+ {
+ if (!Tools::getValue('virtual_product_nb_days'))
+ {
+ if (!Tools::getValue('virtual_product_nb_days_attribute'))
+ {
+ if (!empty($edit) && !empty($id_product_attribute))
+ {
+ $this->_errors[] = $this->l('the field').'
'.$this->l('number of days attribute').' '.$this->l('is required');
+ return false;
+ }
+ }
+ else if (!empty($id_product_attribute))
+ {
+ $this->_errors[] = $this->l('the field').'
'.$this->l('number of days').' '.$this->l('is required');
+ return false;
+ }
+ }
+ }
+
+ if (Tools::getValue('virtual_product_expiration_date') && !Validate::isDate(Tools::getValue('virtual_product_expiration_date') && !empty($is_virtual_file))
+ && Tools::getValue('virtual_product_expiration_date_attribute') && !Validate::isDate(Tools::getValue('virtual_product_expiration_date_attribute')))
+ {
+ if (!Tools::getValue('virtual_product_expiration_date'))
+ {
+ if (!Tools::getValue('virtual_product_expiration_date_attribute'))
+ {
+ $this->_errors[] = $this->l('the field').'
'.$this->l('expiration date attribute').' '.$this->l('is required');
+ return false;
+ }
+ else if (!empty($id_product_attribute))
+ {
+ $this->_errors[] = $this->l('the field').'
'.$this->l('expiration date').' '.$this->l('is not valid');
+ return false;
+ }
+ }
+ }
+
+ // The oos behavior MUST be "Deny orders" for virtual products
+ if (Tools::getValue('out_of_stock') != 0)
+ {
+ $this->_errors[] = $this->l('The "when out of stock" behavior selection must be "deny order" for virtual products');
+ return false;
+ }
+
+ // Trick's
+ if ($edit == 1)
+ {
+ $id_product_download_attibute = ProductDownload::getIdFromIdAttribute((int) $product->id, $id_product_attribute);
+ $id_product_download = ($id_product_download_attibute) ? (int) $id_product_download_attibute : (int) Tools::getValue('virtual_product_id');
+ }
+
+ $is_shareable = Tools::getValue('virtual_product_is_shareable');
+ $virtual_product_name = Tools::getValue('virtual_product_name');
+ $virtual_product_filename = Tools::getValue('virtual_product_filename');
+ $virtual_product_nb_days = Tools::getValue('virtual_product_nb_days');
+ $virtual_product_nb_downloable = Tools::getValue('virtual_product_nb_downloable');
+ $virtual_product_expiration_date = Tools::getValue('virtual_product_expiration_date');
+
+ $is_shareable_attribute = Tools::getValue('virtual_product_is_shareable_attribute');
+ $virtual_product_name_attribute = Tools::getValue('virtual_product_name_attribute');
+ $virtual_product_filename_attribute = Tools::getValue('virtual_product_filename_attribute');
+ $virtual_product_nb_days_attribute = Tools::getValue('virtual_product_nb_days_attribute');
+ $virtual_product_nb_downloable_attribute = Tools::getValue('virtual_product_nb_downloable_attribute');
+ $virtual_product_expiration_date_attribute = Tools::getValue('virtual_product_expiration_date_attribute');
+
+ if (!empty($is_shareable_attribute))
+ $is_shareable = $is_shareable_attribute;
+
+ if (!empty($virtual_product_name_attribute))
+ $virtual_product_name = $virtual_product_name_attribute;
+
+ if (!empty($virtual_product_nb_days_attribute))
+ $virtual_product_nb_days = $virtual_product_nb_days_attribute;
+
+ if (!empty($virtual_product_nb_downloable_attribute))
+ $virtual_product_nb_downloable = $virtual_product_nb_downloable_attribute;
+
+ if (!empty($virtual_product_expiration_date_attribute))
+ $virtual_product_expiration_date = $virtual_product_expiration_date_attribute;
+
+ if (!empty($virtual_product_filename_attribute))
+ $filename = $virtual_product_filename_attribute;
+ else if ($virtual_product_filename)
+ $filename = $virtual_product_filename;
+ else
+ $filename = ProductDownload::getNewFilename();
+
+ $download = new ProductDownload($id_product_download);
+ $download->id_product = (int) $product->id;
+ $download->id_product_attribute = (int) $id_product_attribute;
+ $download->display_filename = $virtual_product_name;
+ $download->filename = $filename;
+ $download->date_add = date('Y-m-d H:i:s');
+ $download->date_expiration = $virtual_product_expiration_date ? $virtual_product_expiration_date.' 23:59:59' : '';
+ $download->nb_days_accessible = (int) $virtual_product_nb_days;
+ $download->nb_downloadable = (int) $virtual_product_nb_downloable;
+ $download->active = 1;
+ $download->is_shareable = (int) $is_shareable;
+
+ if ($download->save())
+ return true;
+ }
+ else
+ {
+ /* unactive download product if checkbox not checked */
+ if ($edit == 1)
+ {
+ $id_product_download_attibute = ProductDownload::getIdFromIdAttribute((int) $product->id, $id_product_attribute);
+ $id_product_download = ($id_product_download_attibute) ? (int) $id_product_download_attibute : (int) Tools::getValue('virtual_product_id');
+ }
+ else
+ $id_product_download = ProductDownload::getIdFromIdProduct($product->id);
+
+ if (!empty($id_product_download))
+ {
+ $productDownload = new ProductDownload($id_product_download);
+ $productDownload->date_expiration = date('Y-m-d H:i:s', time()-1);
+ $productDownload->active = 0;
+ return $productDownload->save();
+ }
+ }
+ return false;
+ }
+
+ public function deleteDownloadProduct($id_product_attribute = NULL)
+ {
+ if (!empty($id_product_attribute))
+ {
+ $productDownload = new ProductDownload($id_product_attribute);
+ $productDownload->date_expiration = date('Y-m-d H:i:s', time()-1);
+ $productDownload->active = 0;
+ return $productDownload->save();
+ }
+ return false;
+ }
+
+ /**
+ * Update product accessories
+ *
+ * @param object $product Product
+ */
+ public function updateAccessories($product)
+ {
+ $product->deleteAccessories();
+ if ($accessories = Tools::getValue('inputAccessories'))
+ {
+ $accessories_id = array_unique(explode('-', $accessories));
+ if (sizeof($accessories_id))
+ {
+ array_pop($accessories_id);
+ $product->changeAccessories($accessories_id);
+ }
+ }
+ }
+
+ /**
+ * Update product tags
+ *
+ * @param array Languages
+ * @param object $product Product
+ * @return boolean Update result
+ */
+ public function updateTags($languages, $product)
+ {
+ $tagError = true;
+ /* Reset all tags for THIS product */
+ if (!Db::getInstance()->Execute('
+ DELETE FROM `'._DB_PREFIX_.'product_tag`
+ WHERE `id_product` = '.(int)($product->id)))
+ return false;
+ /* Assign tags to this product */
+ foreach ($languages as $language)
+ if ($value = Tools::getValue('tags_'.$language['id_lang']))
+ $tagError &= Tag::addTags($language['id_lang'], (int)($product->id), $value);
+ return $tagError;
+ }
+
+ public function initContent($token = null)
+ {
+ if (Tools::getValue('id_product') || ((Tools::isSubmit('submitAddproduct') OR Tools::isSubmit('submitAddproductAndPreview') OR Tools::isSubmit('submitAddproductAndStay') OR Tools::isSubmit('submitSpecificPricePriorities') OR Tools::isSubmit('submitPriceAddition') OR Tools::isSubmit('submitPricesModification')) AND sizeof($this->_errors)) OR Tools::isSubmit('updateproduct') OR Tools::isSubmit('addproduct'))
+ {
+ if ($this->ajax)
+ {
+ if ($this->action && method_exists($this, 'initForm'.$this->action))
+ {
+ $this->template = 'products/'.strtolower($this->action).'.tpl';
+ $this->content_only = true;
+ $languages = Language::getLanguages(false);
+ $defaultLanguage = (int)(Configuration::get('PS_LANG_DEFAULT'));
+ $product = new Product((int)(Tools::getValue('id_product')));
+ $this->initForm();
+ return $this->{'initForm'.$this->action}($product, $languages, $defaultLanguage);
+ }
+ }
+ else
+ $this->displayForm();
+ }
+ else
+ {
+ $this->display = 'list';
+ if ($id_category = (int)Tools::getValue('id_category'))
+ AdminTab::$currentIndex .= '&id_category='.$id_category;
+ $this->getList($this->context->language->id, !$this->context->cookie->__get($this->table.'Orderby') ? 'position' : null, !$this->context->cookie->__get($this->table.'Orderway') ? 'ASC' : null, 0, null, $this->context->shop->getID(true));
+
+ $id_category = Tools::getValue('id_category', 1);
+ if (!$id_category)
+ $id_category = 1;
+ $this->content .= '
'.(!$this->_listTotal ? ($this->l('No products found')) : ($this->_listTotal.' '.($this->_listTotal > 1 ? $this->l('products') : $this->l('product')))).'
';
+ ////////////////////////
+ // @todo lot of ergonomy works around here
+ $this->content .= '
'.$this->l('Go to category');
+ $select_child = ' ';
+ $this->content .= $select_child;
+ $this->content .= '
+ ';
+ ////////////////////////
+ $this->l('in category').' "'.stripslashes($this->_category->getName()).'"';
+ if ($this->tabAccess['add'] === '1')
+ $this->content .= '
'.$this->l('Add a new product').'';
+ $this->content .= '
';
+ // $this->displayList($token);
+// $this->display = 'list';
+ $this->content .= '
';
+ }
+ parent::initContent();
+ }
+
+ public function ajaxProcessProductManufacturers()
+ {
+ $manufacturers = Manufacturer::getManufacturers();
+ if ($manufacturers)
+ {
+ $jsonArray = array();
+ foreach ($manufacturers AS $manufacturer)
+ $jsonArray[] = '{"optionValue": "'.$manufacturer['id_manufacturer'].'", "optionDisplay": "'.htmlspecialchars(trim($manufacturer['name'])).'"}';
+ die('['.implode(',', $jsonArray).']');
+ }
+ }
+
+ public function ajaxProcessProductSuppliers()
+ {
+ $suppliers = Supplier::getSuppliers();
+ if ($suppliers)
+ {
+ $jsonArray = array();
+ foreach ($suppliers AS $supplier)
+ $jsonArray[] = '{"optionValue": "'.$supplier['id_supplier'].'", "optionDisplay": "'.htmlspecialchars(trim($supplier['name'])).'"}';
+ die('['.implode(',', $jsonArray).']');
+ }
+ }
+ /**
+ * displayList show ordered list of current category
+ *
+ * @param mixed $token
+ * @return void
+ */
+ public function displayList($token = null)
+ {
+ /* Display list header (filtering, pagination and column names) */
+ // $this->displayListHeader($token);
+ if (!sizeof($this->_list))
+ echo '
| '.$this->l('No items found').' |
';
+
+ /* Show the content of the table */
+ $this->displayListContent($token);
+
+ /* Close list table and submit button */
+ $this->displayListFooter($token);
+ }
+
+ /**
+ * Build a categories tree
+ *
+ * @param array $indexedCategories Array with categories where product is indexed (in order to check checkbox)
+ * @param array $categories Categories to list
+ * @param array $current Current category
+ * @param integer $id_category Current category id
+ */
+ public static function recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $current, $id_category = 1, $id_category_default = null, $has_suite = array())
+ {
+ global $done;
+ static $irow;
+ $content = '';
+ if (!isset($done[$current['infos']['id_parent']]))
+ $done[$current['infos']['id_parent']] = 0;
+ $done[$current['infos']['id_parent']] += 1;
+
+ $todo = sizeof($categories[$current['infos']['id_parent']]);
+ $doneC = $done[$current['infos']['id_parent']];
+
+ $level = $current['infos']['level_depth'] + 1;
+
+ $content .= '
+
+ |
+
+ |
+
+ '.$id_category.'
+ |
+ ';
+ for ($i = 2; $i < $level; $i++)
+ $content .= ' ';
+ $content .= '
+ |
+
';
+
+ if ($level > 1)
+ $has_suite[] = ($todo == $doneC ? 0 : 1);
+ if (isset($categories[$id_category]))
+ foreach ($categories[$id_category] as $key => $row)
+ if ($key != 'infos')
+ $content .= self::recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $categories[$id_category][$key], $key, $id_category_default, $has_suite);
+ return $content;
+ }
+
+ public function displayErrors()
+ {
+ if ($this->includeSubTab('displayErrors'))
+ ;
+ else if ($nbErrors = sizeof($this->_errors))
+ {
+ $this->content .= '
+

+ '.$nbErrors.' '.($nbErrors > 1 ? $this->l('errors') : $this->l('error')).'
+
';
+ foreach ($this->_errors as $error)
+ $this->content .= '- '.$error.'
';
+ $this->content .= '
+
+
';
+ }
+ }
+
+ private function _displayDraftWarning($active)
+ {
+ $content = '
';
+ $this->context->smarty->assign('draft_warning',$content);
+ }
+
+ public function initForm()
+ {
+ parent::initForm();
+ $this->addJqueryUI('ui.datepicker');
+ $this->context->smarty->assign('pos_select', (($tab = Tools::getValue('tabs')) ? $tab : '0'));
+ $this->context->smarty->assign('token',$this->token);
+ $this->context->smarty->assign('combinationImagesJs', $this->getCombinationImagesJs());
+ $id_product = Tools::getvalue('id_product');
+ $this->context->smarty->assign('form_action', $this->context->link->getAdminLink('AdminProducts').'&id_product='.$id_product);
+ $this->context->smarty->assign('id_product',$id_product);
+
+ if (!($obj = $this->loadObject(true)))
+ throw new Exception('object not loaded');
+ $this->_displayDraftWarning($obj->active);
+ }
+
+ public function displayForm($isMainTab = true)
+ {
+ parent::displayForm();
+ if (!($obj = $this->loadObject(true)))
+ throw new Exception('object not loaded');
+ $smarty = $this->context->smarty;
+ $product_tabs = array();
+ foreach($this->available_tabs as $product_tab)
+ {
+ $product_tabs[$product_tab] = array(
+ 'name' => $product_tab,
+ 'href' => $this->context->link->getAdminLink('AdminProducts').'&id_product='.Tools::getValue('id_product').'&action='.$product_tab,
+ );
+ }
+ $smarty->assign('product_tabs', $product_tabs);
+
+ if ($id_category_back = (int)(Tools::getValue('id_category')))
+ self::$currentIndex .= '&id_category='.$id_category_back;
+
+ if (!($obj = $this->loadObject(true)))
+ return;
+
+ $currency = Tools::setCurrency($this->context->cookie);
+// if ($obj->id)
+// self::$currentIndex .= '&id_product='.$obj->id;
+
+
+ // $this->addJqueryPlugin('tabpane');
+
+ $action = $this->action;
+ if (empty($action) || !method_exists($this,'initForm'.$action))
+ $action = 'informations';
+ $this->initForm();
+ $this->{'initForm'.$action}($obj, null);
+ /* Tabs */
+/*
+switch ($this->action)
+ {
+ default:
+ $this->initFormInformations($obj, $currency);
+// $this->initFormImages($obj, $this->token);
+ }
+ */
+ if (Combination::isFeatureActive())
+ $smarty->assign('countAttributes', Db::getInstance()->getValue('SELECT COUNT(id_product) FROM '._DB_PREFIX_.'product_attribute WHERE id_product = '.(int)$obj->id));
+
+ $smarty->assign('countAttachments', Db::getInstance()->getValue('SELECT COUNT(id_product) FROM '._DB_PREFIX_.'product_attachment WHERE id_product = '.(int)$obj->id));
+
+ if (Tools::getValue('id_category') > 1)
+ {
+ $productIndex = preg_replace('/(&id_product=[0-9]*)/', '', self::$currentIndex);
+/** @TODO
+ $this->content .= '
+
+
+
'.$this->l('Back to the category').'
+ ';
+*/
+ }
+ }
+
+ function initFormPrices($obj, $languages, $defaultLanguage)
+ {
+ $content = '';
+ if ($obj->id)
+ {
+ $this->context->smarty->assign('shops', $shops = Shop::getShops());
+ $this->context->smarty->assign('currencies', $currencies = Currency::getCurrencies());
+ $this->context->smarty->assign('countries', $countries = Country::getCountries($this->context->language->id));
+ $this->context->smarty->assign('groups', $groups = Group::getGroups($this->context->language->id));
+// $currencies = Currency::getCurrencies();
+// $countries = Country::getCountries($this->context->language->id);
+ //$groups = Group::getGroups($this->context->language->id);
+ $content .= $this->_displaySpecificPriceAdditionForm( $this->context->currency, $shops, $currencies, $countries, $groups);
+ $content .= $this->_displaySpecificPriceModificationForm( $this->context->currency, $shops, $currencies, $countries, $groups);
+ }
+ else
+ $content .= '
'.$this->l('You must save this product before adding specific prices').'.';
+ $this->context->smarty->assign('content',$content);
+ $this->content = $this->context->smarty->fetch('products/prices.tpl');
+ }
+
+ private function _getFinalPrice($specificPrice, $productPrice, $taxRate)
+ {
+ $price = Tools::ps_round((float)($specificPrice['price']) ? $specificPrice['price'] : $productPrice, 2);
+ if (!(float)($specificPrice['reduction']))
+ return (float)($specificPrice['price']);
+ return ($specificPrice['reduction_type'] == 'amount') ? ($price - $specificPrice['reduction'] / (1 + $taxRate / 100)) : ($price - $price * $specificPrice['reduction']);
+ }
+
+ protected function _displaySpecificPriceModificationForm($defaultCurrency, $shops, $currencies, $countries, $groups)
+ {
+ $content = '';
+ if (!($obj = $this->loadObject()))
+ return;
+ $specificPrices = SpecificPrice::getByProductId((int)($obj->id));
+ $specificPricePriorities = SpecificPrice::getPriority((int)($obj->id));
+
+ $taxRate = $obj->getTaxesRate(Address::initialize());
+
+ $tmp = array();
+ foreach ($shops as $shop)
+ $tmp[$shop['id_shop']] = $shop;
+ $shops = $tmp;
+ $tmp = array();
+ foreach ($currencies as $currency)
+ $tmp[$currency['id_currency']] = $currency;
+ $currencies = $tmp;
+
+ $tmp = array();
+ foreach ($countries as $country)
+ $tmp[$country['id_country']] = $country;
+ $countries = $tmp;
+
+ $tmp = array();
+ foreach ($groups as $group)
+ $tmp[$group['id_group']] = $group;
+ $groups = $tmp;
+
+ $content .= '
+
'.$this->l('Current specific prices').'
+
+
+
+
+ | '.$this->l('Shop').' |
+ '.$this->l('Currency').' |
+ '.$this->l('Country').' |
+ '.$this->l('Group').' |
+ '.$this->l('Price').' '.($this->context->country->display_tax_label ? $this->l('(tax excl.)') : '').' |
+ '.$this->l('Reduction').' |
+ '.$this->l('Period').' |
+ '.$this->l('From (quantity)').' |
+ '.$this->l('Final price').' '.($this->context->country->display_tax_label ? $this->l('(tax excl.)') : '').' |
+ '.$this->l('Action').' |
+
+
+ ';
+ if (!is_array($specificPrices) || !sizeof($specificPrices))
+ $content .= '
+
+ | '.$this->l('No specific prices').' |
+
';
+ else
+ {
+ $i = 0;
+ foreach ($specificPrices as $specificPrice)
+ {
+ $current_specific_currency = $currencies[($specificPrice['id_currency'] ? $specificPrice['id_currency'] : $defaultCurrency->id)];
+ if ($specificPrice['reduction_type'] == 'percentage')
+ $reduction = ($specificPrice['reduction'] * 100).' %';
+ else
+ $reduction = Tools::displayPrice(Tools::ps_round($specificPrice['reduction'], 2), $current_specific_currency);
+
+ if ($specificPrice['from'] == '0000-00-00 00:00:00' && $specificPrice['to'] == '0000-00-00 00:00:00')
+ $period = $this->l('Unlimited');
+ else
+ $period = $this->l('From').' '.($specificPrice['from'] != '0000-00-00 00:00:00' ? $specificPrice['from'] : '0000-00-00 00:00:00').'
'.$this->l('To').' '.($specificPrice['to'] != '0000-00-00 00:00:00' ? $specificPrice['to'] : '0000-00-00 00:00:00');
+ $content .= '
+
+ | '.($specificPrice['id_shop'] ? $shops[$specificPrice['id_shop']]['name'] : $this->l('All shops')).' |
+ '.($specificPrice['id_currency'] ? $currencies[$specificPrice['id_currency']]['name'] : $this->l('All currencies')).' |
+ '.($specificPrice['id_country'] ? $countries[$specificPrice['id_country']]['name'] : $this->l('All countries')).' |
+ '.($specificPrice['id_group'] ? $groups[$specificPrice['id_group']]['name'] : $this->l('All groups')).' |
+ '.Tools::displayPrice((float)$specificPrice['price'], $current_specific_currency).' |
+ '.$reduction.' |
+ '.$period.' |
+ '.$specificPrice['from_quantity'].'
+ | '.Tools::displayPrice(Tools::ps_round((float)($this->_getFinalPrice($specificPrice, (float)($obj->price), $taxRate)), 2), $current_specific_currency).' |
+  |
+
';
+ $i++;
+ }
+ }
+ $content .= '
+
+
';
+
+ $content .= '
+
+ ';
+
+ $content .= '
+
+
'.$this->l('Priorities management').'
+
+ '.$this->l('Sometimes one customer could fit in multiple rules, priorities allows you to define which rule to apply.').'
+
+
+
+
+
+
+ >
+
+ >
+
+
+
+
+
+
+
+
+
+
+ ';
+ return $content;
+ }
+
+ protected function _displaySpecificPriceAdditionForm($defaultCurrency, $shops, $currencies, $countries, $groups)
+ {
+ if (!($product = $this->loadObject()))
+ return;
+ $content = '';
+ $this->context->smarty->assign('country_display_tax_label', $this->context->country->display_tax_label);
+
+ $content .= '
+
+
+
+
+
+
+ '.$this->l('(if set to "amount", the tax is included)').'
+
+
+
+
+
+
+ ';
+ return $content;
+ }
+
+ private function _getCustomizationFieldIds($labels, $alreadyGenerated, $obj)
+ {
+ $customizableFieldIds = array();
+ if (isset($labels[Product::CUSTOMIZE_FILE]))
+ foreach ($labels[Product::CUSTOMIZE_FILE] as $id_customization_field => $label)
+ $customizableFieldIds[] = 'label_'.Product::CUSTOMIZE_FILE.'_'.(int)($id_customization_field);
+ if (isset($labels[Product::CUSTOMIZE_TEXTFIELD]))
+ foreach ($labels[Product::CUSTOMIZE_TEXTFIELD] as $id_customization_field => $label)
+ $customizableFieldIds[] = 'label_'.Product::CUSTOMIZE_TEXTFIELD.'_'.(int)($id_customization_field);
+ $j = 0;
+ for ($i = $alreadyGenerated[Product::CUSTOMIZE_FILE]; $i < (int)($this->getFieldValue($obj, 'uploadable_files')); $i++)
+ $customizableFieldIds[] = 'newLabel_'.Product::CUSTOMIZE_FILE.'_'.$j++;
+ $j = 0;
+ for ($i = $alreadyGenerated[Product::CUSTOMIZE_TEXTFIELD]; $i < (int)($this->getFieldValue($obj, 'text_fields')); $i++)
+ $customizableFieldIds[] = 'newLabel_'.Product::CUSTOMIZE_TEXTFIELD.'_'.$j++;
+ return implode('¤', $customizableFieldIds);
+ }
+
+ private function _displayLabelField(&$label, $languages, $defaultLanguage, $type, $fieldIds, $id_customization_field)
+ {
+ $fieldsName = 'label_'.$type.'_'.(int)($id_customization_field);
+ $fieldsContainerName = 'labelContainer_'.$type.'_'.(int)($id_customization_field);
+ $this->content .= '
';
+ }
+
+ private function _displayLabelFields(&$obj, &$labels, $languages, $defaultLanguage, $type)
+ {
+ $type = (int)($type);
+ $labelGenerated = array(Product::CUSTOMIZE_FILE => (isset($labels[Product::CUSTOMIZE_FILE]) ? count($labels[Product::CUSTOMIZE_FILE]) : 0), Product::CUSTOMIZE_TEXTFIELD => (isset($labels[Product::CUSTOMIZE_TEXTFIELD]) ? count($labels[Product::CUSTOMIZE_TEXTFIELD]) : 0));
+
+ $fieldIds = $this->_getCustomizationFieldIds($labels, $labelGenerated, $obj);
+ if (isset($labels[$type]))
+ foreach ($labels[$type] as $id_customization_field => $label)
+ $this->_displayLabelField($label, $languages, $defaultLanguage, $type, $fieldIds, (int)($id_customization_field));
+ }
+
+ function initFormCustomization($obj, $languages, $defaultLanguage)
+ {
+ $this->content .= parent::displayForm();
+ $labels = $obj->getCustomizationFields();
+ $defaultIso = Language::getIsoById($defaultLanguage);
+
+ $hasFileLabels = (int)($this->getFieldValue($obj, 'uploadable_files'));
+ $hasTextLabels = (int)($this->getFieldValue($obj, 'text_fields'));
+
+ $this->content .= '
+
';
+ }
+
+ function initFormAttachments($obj, $languages, $defaultLanguage)
+ {
+ if (!($obj = $this->loadObject(true)))
+ return;
+ $languages = Language::getLanguages(false);
+ $attach1 = Attachment::getAttachments($this->context->language->id, $obj->id, true);
+ $attach2 = Attachment::getAttachments($this->context->language->id, $obj->id, false);
+
+ $this->content .= '
+ '.($obj->id ? '
';
+ }
+
+ function initFormInformations($obj, $currency)
+ {
+ $content = '';
+ $smarty = $this->context->smarty;
+ $content .= parent::displayForm();
+
+ $has_attribute = $obj->hasAttributes();
+ // @FIXME Stock, need to use StockManagerFactory
+ $qty = 0;
+ $cover = Product::getCover($obj->id);
+ $this->_applyTaxToEcotax($obj);
+
+ /*
+ * Form for add a virtual product like software, mp3, etc...
+ */
+ $productDownload = new ProductDownload();
+ if ($id_product_download = $productDownload->getIdFromIdProduct($this->getFieldValue($obj, 'id')))
+ $productDownload = new ProductDownload($id_product_download);
+
+ $hidden = $display_filename = $check = '';
+ $this->displayInitInformationAndAttachment();
+ if(!$productDownload->id || !$productDownload->active)
+ $hidden = 'style="display:none;"';
+
+ $cache_default_attribute = (int) $this->getFieldValue($obj, 'cache_default_attribute');
+ $is_virtual = (int) $this->getFieldValue($obj, 'is_virtual');
+
+ if($is_virtual && $productDownload->active)
+ $check = 'checked="checked"';
+
+ if($is_virtual)
+ $virtual = 1;
+ else
+ $virtual = 0;
+
+ $preview_url = '';
+ if (isset($obj->id))
+ {
+ $preview_url = ($this->context->link->getProductLink($this->getFieldValue($obj, 'id'), $this->getFieldValue($obj, 'link_rewrite', $this->_defaultFormLanguage), Category::getLinkRewrite($this->getFieldValue($obj, 'id_category_default'), $this->context->language->id)));
+ if (!$obj->active)
+ {
+ $admin_dir = dirname($_SERVER['PHP_SELF']);
+ $admin_dir = substr($admin_dir, strrpos($admin_dir,'/') + 1);
+ $token = Tools::encrypt('PreviewProduct'.$obj->id);
+
+ $preview_url .= $obj->active ? '' : '&adtoken='.$token.'&ad='.$admin_dir;
+ }
+
+ $content .= '
+
';
+
+ if (file_exists(_PS_MODULE_DIR_.'statsproduct/statsproduct.php'))
+ $content .= ' -