* @copyright 2007-2011 PrestaShop SA * @version Release: $Revision: 7793 $ * @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'); class AdminProducts extends AdminTab { protected $maxImageSize = 2000000; protected $maxFileSize = 10000000; private $_category; public function __construct() { global $currentIndex; $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->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' => 220, 'filter_key' => 'b!name'), 'reference' => array('title' => $this->l('Reference'), 'align' => 'center', 'width' => 20), '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'), 'position' => array('title' => $this->l('Position'), 'width' => 40,'filter_key' => 'cp!position', 'align' => 'center', 'position' => 'position'), 'a!active' => array('title' => $this->l('Displayed'), 'active' => 'status', 'filter_key' => 'a!active', 'align' => 'center', 'type' => 'bool', 'orderby' => false)); /* Join categories table */ $this->_category = AdminCatalog::getCurrentCategory(); $this->_join = ' 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)Country::getDefaultCountryId().' 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 = 'cp.`position`, i.`id_image`, (a.`price` * ((100 + (t.`rate`))/100)) AS price_final'; 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) { global $cookie; $orderByPriceFinal = (empty($orderBy) ? ($cookie->__get($this->table.'Orderby') ? $cookie->__get($this->table.'Orderby') : 'id_'.$this->table) : $orderBy); $orderWayPriceFinal = (empty($orderWay) ? ($cookie->__get($this->table.'Orderway') ? $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); /* update product quantity with attributes ...*/ if ($this->_list) { $nb = count ($this->_list); for ($i = 0; $i < $nb; $i++) Attribute::updateQtyProduct($this->_list[$i]); /* 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 AND $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(intval(Tools::getValue('id_product'))))) 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) { global $cookie, $currentIndex; /* Add a new product */ if (Tools::isSubmit('submitAddproduct') OR Tools::isSubmit('submitAddproductAndStay') OR Tools::isSubmit('submitAddProductAndPreview')) { if ((Tools::getValue('id_product') AND $this->tabAccess['edit'] === '1') OR ($this->tabAccess['add'] === '1' AND !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 */ if (Tools::getValue('deleteVirtualProduct')) { if ($this->tabAccess['delete'] === '1') $this->deleteVirtualProduct(); else $this->_errors[] = Tools::displayError('You do not have permission to delete here.'); } /* Update attachments */ elseif (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'); elseif (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']) AND 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']); } } elseif ((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) OR 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($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.'); } elseif (Tools::isSubmit('submitAttachments')) { if ($this->tabAccess['edit'] === '1') if ($id = (int)(Tools::getValue($this->identifier))) if (Attachment::attachToProduct($id, $_POST['attachments'])) Tools::redirectAdmin($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 */ elseif (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() AND Category::duplicateProductCategories($id_product_old, $product->id) AND ($combinationImages = Product::duplicateAttributes($id_product_old, $product->id)) !== false AND Product::duplicateAccessories($id_product_old, $product->id) AND Product::duplicateFeatures($id_product_old, $product->id) AND Product::duplicateSpecificPrices($id_product_old, $product->id) AND Pack::duplicate($id_product_old, $product->id) AND Product::duplicateCustomizationFields($id_product_old, $product->id) AND Product::duplicateTags($id_product_old, $product->id) AND Product::duplicateDownload($id_product_old, $product->id)) { if ($product->hasAttributes()) Product::updateDefaultAttribute($product->id); if (!Tools::getValue('noimage') AND !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($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) */ elseif (isset($_GET['status']) AND Tools::getValue($this->identifier)) { if ($this->tabAccess['edit'] === '1') { if (Validate::isLoadedObject($object = $this->loadObject())) { if ($object->toggleStatus()) Tools::redirectAdmin($currentIndex.'&conf=5'.((($id_category = (!empty($_REQUEST['id_category'])?$_REQUEST['id_category']:'1')) AND 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 */ elseif (isset($_GET['delete'.$this->table])) { if ($this->tabAccess['delete'] === '1') { if (Validate::isLoadedObject($object = $this->loadObject()) AND isset($this->fieldImageSettings)) { // check if request at least one object with noZeroObject if (isset($object->noZeroObject) AND 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($currentIndex.'&conf=1&token='.($token ? $token : $this->token).$category_url); } elseif ($object->delete()) Tools::redirectAdmin($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 */ elseif (Tools::getValue('submitDel'.$this->table)) { if ($this->tabAccess['delete'] === '1') { if (isset($_POST[$this->table.'Box'])) { $object = new $this->className(); if (isset($object->noZeroObject) AND // Check if all object will be deleted (sizeof(call_user_func(array($this->className, $object->noZeroObject))) <= 1 OR 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 AND $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($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 */ elseif (($id_image = (int)(Tools::getValue('id_image'))) AND Validate::isUnsignedId($id_image) AND Validate::isLoadedObject($image = new Image($id_image))) { if ($this->tabAccess['edit'] === '1') { /* Delete product image */ if (isset($_GET['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'); 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 */ elseif (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; $this->displayForm(); } /* Choose product cover image */ elseif (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($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 */ elseif (isset($_GET['imgPosition']) AND isset($_GET['imgDirection'])) { $image->positionImage((int)(Tools::getValue('imgPosition')), (int)(Tools::getValue('imgDirection'))); 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)); } } else $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); } /* Product attributes management */ elseif (Tools::isSubmit('submitProductAttribute')) { if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product'))))) { if (!isset($_POST['attribute_price']) OR $_POST['attribute_price'] == NULL) $this->_errors[] = Tools::displayError('Attribute price required.'); if (!isset($_POST['attribute_combinaison_list']) OR !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 { $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')); if ($id_reason = (int)Tools::getValue('id_mvt_reason') AND (int)Tools::getValue('attribute_mvt_quantity') > 0 AND $id_reason > 0) { $reason = new StockMvtReason((int)$id_reason); $qty = Tools::getValue('attribute_mvt_quantity') * $reason->sign; if (!$product->addStockMvt($qty, $id_reason, (int)$id_product_attribute, NULL, $cookie->id_employee)) $this->_errors[] = Tools::displayError('An error occurred while updating qty.'); } Hook::updateProductAttribute((int)$id_product_attribute); } } 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')); } 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); Tools::redirectAdmin($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)); } } } } elseif (Tools::isSubmit('deleteProductAttribute')) { if ($this->tabAccess['delete'] === '1') { if (($id_product = (int)(Tools::getValue('id_product'))) AND Validate::isUnsignedId($id_product) AND Validate::isLoadedObject($product = new Product($id_product))) { $product->deleteAttributeCombinaison((int)(Tools::getValue('id_product_attribute'))); $product->checkDefaultAttributes(); $product->updateQuantityProductWithAttributeQuantity(); if (!$product->hasAttributes()) { $product->cache_default_attribute = 0; $product->update(); }else Product::updateDefaultAttribute($id_product); Tools::redirectAdmin($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.'); } elseif (Tools::isSubmit('deleteAllProductAttributes')) { if ($this->tabAccess['delete'] === '1') { if (($id_product = (int)(Tools::getValue('id_product'))) AND Validate::isUnsignedId($id_product) AND 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($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.'); } elseif (Tools::isSubmit('defaultProductAttribute')) { if (Validate::isLoadedObject($product = new Product((int)(Tools::getValue('id_product'))))) { $product->deleteDefaultAttributes(); $product->setDefaultAttribute((int)(Tools::getValue('id_product_attribute'))); Tools::redirectAdmin($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 */ elseif (Tools::isSubmit('submitProductFeature')) { 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($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 */ elseif (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($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.'); } elseif (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($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.'); } elseif (Tools::isSubmit('deleteSpecificPrice')) { if ($this->tabAccess['delete'] === '1') { if (!($obj = $this->loadObject())) return; if (!$id_specific_price = Tools::getValue('id_specific_price') OR !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($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.'); } elseif (Tools::isSubmit('submitSpecificPricePriorities')) { if (!($obj = $this->loadObject())) return; if (!$priorities = Tools::getValue('specificPricePriority')) $this->_errors[] = Tools::displayError('Please specify priorities'); elseif (Tools::isSubmit('specificPricePriorityToAll')) { if (!SpecificPrice::setPriorities($priorities)) $this->_errors[] = Tools::displayError('An error occurred while updating priorities.'); else Tools::redirectAdmin($currentIndex.'&id_product='.$obj->id.'&add'.$this->table.'&tabs=2&conf=4&token='.($token ? $token : $this->token)); } elseif (!SpecificPrice::setSpecificPriority((int)($obj->id), $priorities)) $this->_errors[] = Tools::displayError('An error occurred while setting priorities.'); else Tools::redirectAdmin($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 */ elseif (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) AND !$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 OR (int)($_POST['text_fields']) > 0) ? 1 : 0; if (!sizeof($this->_errors) AND !$product->update()) $this->_errors[] = Tools::displayError('An error occurred while updating customization configuration.'); if (!sizeof($this->_errors)) Tools::redirectAdmin($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.'); } elseif (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 AND !Validate::isLabel($value)) $this->_errors[] = Tools::displayError('Label fields are invalid'); if (!sizeof($this->_errors) AND !$product->updateLabels()) $this->_errors[] = Tools::displayError('An error occurred while updating customization.'); if (!sizeof($this->_errors)) Tools::redirectAdmin($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.'); } elseif (isset($_GET['position'])) { if ($this->tabAccess['edit'] !== '1') $this->_errors[] = Tools::displayError('You do not have permission to edit here.'); elseif (!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($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('AdminCatalog')); } else parent::postProcess(true); } protected function _validateSpecificPrice($id_shop, $id_currency, $id_country, $id_group, $price, $from_quantity, $reduction, $reduction_type, $from, $to) { if (!Validate::isUnsignedId($id_shop) OR !Validate::isUnsignedId($id_currency) OR !Validate::isUnsignedId($id_country) OR !Validate::isUnsignedId($id_group)) $this->_errors[] = Tools::displayError('Wrong ID\'s'); elseif ((empty($price) AND empty($reduction)) OR (!empty($price) AND !Validate::isPrice($price)) OR (!empty($reduction) AND !Validate::isPrice($reduction))) $this->_errors[] = Tools::displayError('Invalid price/reduction amount'); elseif (!Validate::isUnsignedInt($from_quantity)) $this->_errors[] = Tools::displayError('Invalid quantity'); elseif ($reduction AND !Validate::isReductionType($reduction_type)) $this->_errors[] = Tools::displayError('Please select a reduction type (amount or percentage)'); elseif ($from AND $to AND (!Validate::isDateFormat($from) OR !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; elseif (!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) OR !$image->update()) $this->_errors[] = Tools::displayError('An error occurred while updating image.'); elseif (isset($_FILES['image_product']['tmp_name']) AND $_FILES['image_product']['tmp_name'] != NULL) $this->copyImage($product->id, $image->id, $method); } } /* Adding a new product image */ elseif (isset($_FILES['image_product']['name']) && $_FILES['image_product']['name'] != NULL ) { if ($error = checkImageUploadError($_FILES['image_product'])) $this->_errors[] = $error; if (!sizeof($this->_errors) AND isset($_FILES['image_product']['tmp_name']) AND $_FILES['image_product']['tmp_name'] != NULL) { if (!Validate::isLoadedObject($product)) $this->_errors[] = Tools::displayError('Cannot add image because product add failed.'); elseif (substr($_FILES['image_product']['name'], -4) == '.zip') return $this->uploadImageZip($product); else { $image = new Image(); $image->id_product = (int)($product->id); $_POST['id_product'] = $image->id_product; $image->position = Image::getHighestPosition($product->id) + 1; if (($cover = Tools::getValue('cover')) == 1) Image::deleteCover($product->id); $image->cover = !$cover ? !sizeof($product->getImages(Configuration::get('PS_LANG_DEFAULT'))) : true; $this->validateRules('Image', 'image'); $this->copyFromPost($image, 'image'); if (!sizeof($this->_errors)) { if (!$image->add()) $this->_errors[] = Tools::displayError('Error while creating additional image'); else $this->copyImage($product->id, $image->id, $method); $id_image = $image->id; } } } } if (isset($image) AND Validate::isLoadedObject($image) AND !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) AND is_int($id_image) AND $id_image) ? $id_image : true); } public function uploadImageZip($product) { // Move the ZIP file to the img/tmp directory if (!$zipfile = tempnam(_PS_TMP_IMG_DIR_, 'PS') OR !move_uploaded_file($_FILES['image_product']['tmp_name'], $zipfile)) { $this->_errors[] = Tools::displayError('An error occurred during the ZIP file upload.'); return false; } // Unzip the file to a subdirectory $subdir = _PS_TMP_IMG_DIR_.uniqid().'/'; try { if (!Tools::ZipExtract($zipfile, $subdir)) throw new Exception(Tools::displayError('An error occurred while unzipping your file.')); $types = array('.gif' => 'image/gif', '.jpeg' => 'image/jpeg', '.jpg' => 'image/jpg', '.png' => 'image/png'); $_POST['id_product'] = (int)$product->id; $imagesTypes = ImageType::getImagesTypes('products'); $highestPosition = Image::getHighestPosition($product->id); foreach (scandir($subdir) as $file) { if ($file[0] == '.') continue; // Create image object $image = new Image(); $image->id_product = (int)$product->id; $image->position = ++$highestPosition; $image->cover = ($highestPosition == 1 ? true : false); // Call automated copy function $this->validateRules('Image', 'image'); $this->copyFromPost($image, 'image'); if (sizeof($this->_errors)) throw new Exception(''); if (!$image->add()) throw new Exception(Tools::displayError('Error while creating additional image')); if (filesize($subdir.$file) > $this->maxImageSize) { $image->delete(); throw new Exception(Tools::displayError('Image is too large').' ('.(filesize($subdir.$file) / 1000).Tools::displayError('kB').'). '.Tools::displayError('Maximum allowed:').' '.($this->maxImageSize / 1000).Tools::displayError('kB')); } $ext = substr($file, -4); $type = (isset($types[$ext]) ? $types[$ext] : ''); if (!isPicture(array('tmp_name' => $subdir.$file, 'type' => $type))) { $image->delete(); throw new Exception(Tools::displayError('Image format not recognized, allowed formats are: .gif, .jpg, .png')); } if (!$new_path = $image->getPathForCreation()) throw new Exception(Tools::displayError('An error occurred during new folder creation')); if (!imageResize($subdir.$file, $new_path.'.'.$image->image_format)) { $image->delete(); throw new Exception(Tools::displayError('An error occurred while resizing image.')); } foreach ($imagesTypes AS $k => $imageType) if (!imageResize($subdir.$file, _PS_PROD_IMG_DIR_.$image->getImgPath().'-'.stripslashes($imageType['name']).'.jpg', $imageType['width'], $imageType['height'])) { $image->delete(); throw new Exception(Tools::displayError('An error occurred while copying image.').' '.stripslashes($imageType['name'])); } Module::hookExec('watermark', array('id_image' => $image->id, 'id_product' => $image->id_product)); } } catch (Exception $e) { if ($error = $e->getMessage()); $this->_errors[] = $error; Tools::deleteDirectory($subdir); return false; } Tools::deleteDirectory($subdir); return 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->maxImageSize)) $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') OR !move_uploaded_file($_FILES['image_product']['tmp_name'], $tmpName)) $this->_errors[] = Tools::displayError('An error occurred during the image upload'); elseif (!imageResize($tmpName, $new_path.'.'.$image->image_format)) $this->_errors[] = Tools::displayError('An error occurred while copying image.'); elseif ($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 * * @global string $currentIndex Current URL in order to keep current Tab */ public function submitAddProduct($token = NULL) { global $cookie, $currentIndex, $link; $className = 'Product'; $rules = call_user_func(array($this->className, 'getValidationRules'), $this->className); $defaultLanguage = new Language((int)(Configuration::get('PS_LANG_DEFAULT'))); $languages = Language::getLanguages(false); /* Check required fields */ foreach ($rules['required'] AS $field) if (($value = Tools::getValue($field)) == false AND $value != '0') { if (Tools::getValue('id_'.$this->table) AND $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) AND 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 */ foreach ($languages AS $language) if ($value = Tools::getValue('description_short_'.$language['id_lang'])) if (Tools::strlen(strip_tags($value)) > 400) $this->_errors[] = $this->l('the field').' '.call_user_func(array($className, 'displayFieldName'), 'description_short').' ('.$language['name'].') '.$this->l('is too long').' : 400 '.$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']) AND 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') OR !sizeof(Tools::getValue('categoryBox'))) $this->_errors[] = $this->l('product must be in at least one Category'); if (!is_array(Tools::getValue('categoryBox')) OR !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) AND !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') AND (int)Tools::getValue('mvt_quantity') > 0 AND $id_reason > 0) { $reason = new StockMvtReason((int)$id_reason); $qty = Tools::getValue('mvt_quantity') * $reason->sign; if (!$object->addStockMvt($qty, (int)$id_reason, NULL, NULL, (int)$cookie->id_employee)) $this->_errors[] = Tools::displayError('An error occurred while updating qty.'); } $this->updateAccessories($object); $this->updateDownloadProduct($object); if (!$this->updatePackItems($object)) $this->_errors[] = Tools::displayError('An error occurred while adding products to the pack.'); elseif (!$object->updateCategories($_POST['categoryBox'], true)) $this->_errors[] = Tools::displayError('An error occurred while linking object.').' '.$this->table.' '.Tools::displayError('To categories'); elseif (!$this->updateTags($languages, $object)) $this->_errors[] = Tools::displayError('An error occurred while adding tags.'); elseif ($id_image = $this->addProductImage($object, Tools::getValue('resizer'))) { $currentIndex .= '&image_updated='.(int)Tools::getValue('id_image'); Hook::updateProduct($object); Search::indexation(false, $object->id); if (Tools::getValue('resizer') == 'man' && isset($id_image) AND is_int($id_image) AND $id_image) Tools::redirectAdmin($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') OR Tools::getValue('productCreated') == 'on') ? 'on' : 'off').'&token='.(($token ? $token : $this->token))); // Save and preview if (Tools::isSubmit('submitAddProductAndPreview')) { $preview_url = ($link->getProductLink($this->getFieldValue($object, 'id'), $this->getFieldValue($object, 'link_rewrite', (int)($cookie->id_lang)), Category::getLinkRewrite($this->getFieldValue($object, 'id_category_default'), (int)($cookie->id_lang)))); 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); } elseif (Tools::isSubmit('submitAdd'.$this->table.'AndStay') OR ($id_image AND $id_image !== true)) // Save and stay on same form // Save and stay on same form if (Tools::isSubmit('submitAdd'.$this->table.'AndStay')) Tools::redirectAdmin($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($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->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'); elseif (!$this->updateTags($languages, $object)) $this->_errors[] = Tools::displayError('An error occurred while adding tags.'); elseif ($id_image = $this->addProductImage($object)) { Hook::addProduct($object); Search::indexation(false, $object->id); // Save and preview if (Tools::isSubmit('submitAddProductAndPreview')) { $preview_url = ($link->getProductLink($this->getFieldValue($object, 'id'), $this->getFieldValue($object, 'link_rewrite', (int)($cookie->id_lang)), Category::getLinkRewrite($this->getFieldValue($object, 'id_category_default'), (int)($cookie->id_lang)))); 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) AND is_int($id_image) AND $id_image) Tools::redirectAdmin($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($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($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 */ public function updateDownloadProduct($product) { /* add or update a virtual product */ if (Tools::getValue('is_virtual_good') == 'true') { if (!Tools::getValue('virtual_product_name')) { $this->_errors[] = $this->l('the field').' '.$this->l('display filename').' '.$this->l('is required'); return false; } if (Tools::getValue('virtual_product_nb_days') === false) { $this->_errors[] = $this->l('the field').' '.$this->l('number of days').' '.$this->l('is required'); return false; } if (Tools::getValue('virtual_product_expiration_date') AND !Validate::isDate(Tools::getValue('virtual_product_expiration_date'))) { $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; } $download = new ProductDownload(Tools::getValue('virtual_product_id')); $download->id_product = $product->id; $download->display_filename = Tools::getValue('virtual_product_name'); $download->physically_filename = Tools::getValue('virtual_product_filename') ? Tools::getValue('virtual_product_filename') : ProductDownload::getNewFilename(); $download->date_deposit = date('Y-m-d H:i:s'); $download->date_expiration = Tools::getValue('virtual_product_expiration_date') ? Tools::getValue('virtual_product_expiration_date').' 23:59:59' : ''; $download->nb_days_accessible = Tools::getValue('virtual_product_nb_days'); $download->nb_downloadable = Tools::getValue('virtual_product_nb_downloable'); $download->active = 1; if ($download->save()) return true; } else { /* unactive download product if checkbox not checked */ if ($id_product_download = ProductDownload::getIdFromIdProduct($product->id)) { $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; } /** * 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 display($token = NULL) { global $currentIndex, $cookie; if (($id_category = (int)Tools::getValue('id_category'))) $currentIndex .= '&id_category='.$id_category; $this->getList((int)($cookie->id_lang), !$cookie->__get($this->table.'Orderby') ? 'position' : NULL, !$cookie->__get($this->table.'Orderway') ? 'ASC' : NULL); $id_category = (Tools::getValue('id_category',1)); if (!$id_category) $id_category = 1; echo '

'.(!$this->_listTotal ? ($this->l('No products found')) : ($this->_listTotal.' '.($this->_listTotal > 1 ? $this->l('products') : $this->l('product')))).' '. $this->l('in category').' "'.stripslashes($this->_category->getName()).'"

'; if ($this->tabAccess['add'] === '1') echo ' '.$this->l('Add a new product').''; echo '
'; $this->displayList($token); echo '
'; } /** * displayList show ordered list of current category * * @param mixed $token * @return void */ public function displayList($token = NULL) { global $currentIndex; /* 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; 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; echo ' '.$id_category.' '; for ($i = 2; $i < $level; $i++) echo ''; echo '   '; if ($level > 1) $has_suite[] = ($todo == $doneC ? 0 : 1); if (isset($categories[$id_category])) foreach ($categories[$id_category] AS $key => $row) if ($key != 'infos') self::recurseCategoryForInclude($id_obj, $indexedCategories, $categories, $categories[$id_category][$key], $key, $id_category_default, $has_suite); } public function displayErrors() { if ($this->includeSubTab('displayErrors')) ; elseif ($nbErrors = sizeof($this->_errors)) { echo '
'.$nbErrors.' '.($nbErrors > 1 ? $this->l('errors') : $this->l('error')).'
    '; foreach ($this->_errors AS $error) echo '
  1. '.$error.'
  2. '; echo '
'; } } private function _displayDraftWarning($active) { return '

'.$this->l('Your product will be saved as draft').' '.$this->l('Save and preview').'

'; } public function displayForm($isMainTab = true) { global $currentIndex, $link, $cookie; parent::displayForm(); if ($id_category_back = (int)(Tools::getValue('id_category'))) $currentIndex .= '&id_category='.$id_category_back; if (!($obj = $this->loadObject(true))) return; $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); if ($obj->id) $currentIndex .= '&id_product='.$obj->id; echo '

'.$this->l('Current product:').' '.$this->l('no name').'

'.$this->_displayDraftWarning($obj->active).'
'; /* Tabs */ $this->displayFormInformations($obj, $currency); $this->displayFormImages($obj, $this->token); $countAttributes = (int)Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'product_attribute WHERE id_product = '.(int)$obj->id); $countAttachments = (int)Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'product_attachment WHERE id_product = '.(int)$obj->id); if ($obj->id) echo '

3. '.$this->l('Prices').'

4. '.$this->l('Combinations').' ('.$countAttributes.')

5. '.$this->l('Features').'

6. '.$this->l('Customization').'

7. '.$this->l('Attachments').' ('.$countAttachments.')

'; echo '

'.$this->_displayDraftWarning($obj->active).'
'; if (Tools::getValue('id_category') > 1) { $productIndex = preg_replace('/(&id_product=[0-9]*)/', '', $currentIndex); echo '

'.$this->l('Back to the category').'
'; } } function displayFormPrices($obj, $languages, $defaultLanguage) { global $cookie, $currentIndex; if ($obj->id) { $shops = Shop::getShops(); $currencies = Currency::getCurrencies(); $countries = Country::getCountries((int)($cookie->id_lang)); $groups = Group::getGroups((int)($cookie->id_lang)); $defaultCurrency = new Currency((int)(Configuration::get('PS_CURRENCY_DEFAULT'))); $this->_displaySpecificPriceAdditionForm($defaultCurrency, $shops, $currencies, $countries, $groups); $this->_displaySpecificPriceModificationForm($defaultCurrency, $shops, $currencies, $countries, $groups); } else echo ''.$this->l('You must save this product before adding specific prices').'.'; } 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) { global $currentIndex; if (!($obj = $this->loadObject())) return; $specificPrices = SpecificPrice::getByProductId((int)($obj->id)); $specificPricePriorities = SpecificPrice::getPriority((int)($obj->id)); $default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT')); $taxRate = TaxRulesGroup::getTaxesRate($obj->id_tax_rules_group, Configuration::get('PS_COUNTRY_DEFAULT'), 0, 0); $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; echo '

'.$this->l('Current specific prices').'

'; if (!is_array($specificPrices) OR !sizeof($specificPrices)) echo ' '; 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' AND $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'); echo ' '; $i++; } } echo '
'.$this->l('Currency').' '.$this->l('Country').' '.$this->l('Group').' '.$this->l('Price').' '.($default_country->display_tax_label ? $this->l('(tax excl.)') : '').' '.$this->l('Reduction').' '.$this->l('Period').' '.$this->l('From (quantity)').' '.$this->l('Final price').' '.($default_country->display_tax_label ? $this->l('(tax excl.)') : '').' '.$this->l('Action').'
'.$this->l('No specific prices').'
'.($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).' '.$this->l('Delete').'
'; echo ' '; echo '

'.$this->l('Priorities management').'

'.$this->l('Sometimes one customer could fit in multiple rules, priorities allows you to define which rule to apply.').'

> >
'; } protected function _displaySpecificPriceAdditionForm($defaultCurrency, $shops, $currencies, $countries, $groups) { if (!($product = $this->loadObject())) return; $default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT')); echo ' '.$this->l('Add a new specific price').'
'; include_once('functions.php'); includeDatepicker(array('sp_from', 'sp_to'), true); } private function _getCustomizationFieldIds($labels, $alreadyGenerated, $obj) { $customizableFieldIds = array(); if (isset($labels[_CUSTOMIZE_FILE_])) foreach ($labels[_CUSTOMIZE_FILE_] AS $id_customization_field => $label) $customizableFieldIds[] = 'label_'._CUSTOMIZE_FILE_.'_'.(int)($id_customization_field); if (isset($labels[_CUSTOMIZE_TEXTFIELD_])) foreach ($labels[_CUSTOMIZE_TEXTFIELD_] AS $id_customization_field => $label) $customizableFieldIds[] = 'label_'._CUSTOMIZE_TEXTFIELD_.'_'.(int)($id_customization_field); $j = 0; for ($i = $alreadyGenerated[_CUSTOMIZE_FILE_]; $i < (int)($this->getFieldValue($obj, 'uploadable_files')); $i++) $customizableFieldIds[] = 'newLabel_'._CUSTOMIZE_FILE_.'_'.$j++; $j = 0; for ($i = $alreadyGenerated[_CUSTOMIZE_TEXTFIELD_]; $i < (int)($this->getFieldValue($obj, 'text_fields')); $i++) $customizableFieldIds[] = 'newLabel_'._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); echo '
'; foreach ($languages as $language) { $fieldName = 'label_'.$type.'_'.(int)($id_customization_field).'_'.(int)($language['id_lang']); $text = (isset($label[(int)($language['id_lang'])])) ? $label[(int)($language['id_lang'])]['name'] : ''; echo '
#'.(int)($id_customization_field).'
'; } $required = (isset($label[(int)($language['id_lang'])])) ? $label[(int)($language['id_lang'])]['required'] : false; echo '
'; } private function _displayLabelFields(&$obj, &$labels, $languages, $defaultLanguage, $type) { $type = (int)($type); $labelGenerated = array(_CUSTOMIZE_FILE_ => (isset($labels[_CUSTOMIZE_FILE_]) ? count($labels[_CUSTOMIZE_FILE_]) : 0), _CUSTOMIZE_TEXTFIELD_ => (isset($labels[_CUSTOMIZE_TEXTFIELD_]) ? count($labels[_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 displayFormCustomization($obj, $languages, $defaultLanguage) { parent::displayForm(); $labels = $obj->getCustomizationFields(); $defaultIso = Language::getIsoById($defaultLanguage); $hasFileLabels = (int)($this->getFieldValue($obj, 'uploadable_files')); $hasTextLabels = (int)($this->getFieldValue($obj, 'text_fields')); echo '
'.$this->l('Add or modify customizable properties').'


'; if ($hasFileLabels) { echo ' '; } if ($hasTextLabels) { echo ' '; } echo '
'.$this->l('File fields:').'

'.$this->l('Number of upload file fields displayed').'

'.$this->l('Text fields:').'

'.$this->l('Number of text fields displayed').'


'.$this->l('Files fields:').' '; $this->_displayLabelFields($obj, $labels, $languages, $defaultLanguage, _CUSTOMIZE_FILE_); echo '

'.$this->l('Text fields:').' '; $this->_displayLabelFields($obj, $labels, $languages, $defaultLanguage, _CUSTOMIZE_TEXTFIELD_); echo '
'; if ($hasFileLabels OR $hasTextLabels) echo ''; echo '
'; } function displayFormAttachments($obj, $languages, $defaultLanguage) { global $currentIndex, $cookie; if (!($obj = $this->loadObject(true))) return; $languages = Language::getLanguages(false); $attach1 = Attachment::getAttachments($cookie->id_lang, $obj->id, true); $attach2 = Attachment::getAttachments($cookie->id_lang, $obj->id, false); echo ' '.($obj->id ? '' : '').'
'.$this->l('Attachment').'
'; foreach ($languages as $language) echo '
*
'; $this->displayFlags($languages, $defaultLanguage, 'attachment_name¤attachment_description', 'attachment_name'); echo '
 
'; foreach ($languages as $language) echo '
'; $this->displayFlags($languages, $defaultLanguage, 'attachment_name¤attachment_description', 'attachment_description'); echo '
 

'.$this->l('Upload file from your computer').'

 
* '.$this->l('Required field').'
 

'.$this->l('Attachments for this product:').'



'.$this->l('Remove').' >>

'.$this->l('Available attachments:').'



<< '.$this->l('Add').'
 
'; } function displayFormInformations($obj, $currency) { parent::displayForm(false); global $currentIndex, $cookie, $link; $default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT')); $iso = Language::getIsoById((int)($cookie->id_lang)); $has_attribute = false; $qty_state = 'readonly'; $qty = Attribute::getAttributeQty($this->getFieldValue($obj, 'id_product')); if ($qty === false) { if (Validate::isLoadedObject($obj)) $qty = $this->getFieldValue($obj, 'quantity'); else $qty = 1; $qty_state = ''; } else $has_attribute = true; $cover = Product::getCover($obj->id); $this->_applyTaxToEcotax($obj); echo '

1. '.$this->l('Info.').'

'.$this->l('Product global information').' - '; $preview_url = ''; if (isset($obj->id)) { $preview_url = ($link->getProductLink($this->getFieldValue($obj, 'id'), $this->getFieldValue($obj, 'link_rewrite', $this->_defaultFormLanguage), Category::getLinkRewrite($this->getFieldValue($obj, 'id_category_default'), (int)($cookie->id_lang)))); 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; } echo ' '.$this->l('Delete this product').' '.$this->l('Delete this product').' '.$this->l('View product in shop').' '.$this->l('View product in shop').''; if (file_exists(_PS_MODULE_DIR_.'statsproduct/statsproduct.php')) echo ' - '.$this->l('View product sales').' '.$this->l('View product sales').''; } echo '

'.$this->l('Name:').' '; foreach ($this->_languages as $language) echo '
id) ? ' onkeyup="if (isArrowKey(event)) return; copy2friendlyURL();"' : '').' onkeyup="if (isArrowKey(event)) return; updateCurrentText();" onchange="updateCurrentText();" /> * '.$this->l('Invalid characters:').' <>;=#{} 
'; echo '
'.$this->l('Reference:').' '.$this->l('Special characters allowed:').' .-_#\ 
'.$this->l('Supplier Reference:').' '.$this->l('Special characters allowed:').' .-_#\ 
'.$this->l('EAN13 or JAN:').' '.$this->l('(Europe, Japan)').'
'.$this->l('UPC:').' '.$this->l('(US, Canada)').'
'.$this->l('Location (warehouse):').'
'.$this->l('Width ( package ) :').' '.Configuration::get('PS_DIMENSION_UNIT').'
'.$this->l('Height ( package ) :').' '.Configuration::get('PS_DIMENSION_UNIT').'
'.$this->l('Deep ( package ) :').' '.Configuration::get('PS_DIMENSION_UNIT').'
'.$this->l('Weight ( package ) :').' '.Configuration::get('PS_WEIGHT_UNIT').'
active ? 'style="display:none"' : '').'>
'.$this->l('Status:').' getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
'.$this->l('Options:').' getFieldValue($obj, 'available_for_order') ? 'checked="checked" ' : '').' onclick="if ($(this).is(\':checked\')){$(\'#show_price\').attr(\'checked\', \'checked\');$(\'#show_price\').attr(\'disabled\', \'disabled\');}else{$(\'#show_price\').attr(\'disabled\', \'\');}"/>
getFieldValue($obj, 'show_price') ? 'checked="checked" ' : '').' />
getFieldValue($obj, 'online_only') ? 'checked="checked" ' : '').' />
'.$this->l('Condition:').'
'.$this->l('Manufacturer:').'    '.$this->l('Create').' '.$this->l('Create').'
'.$this->l('Supplier:').'    '.$this->l('Create').' '.$this->l('Create').'
'; $this->displayPack($obj); echo ' '; /* * 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); ?> '; ?> '; echo ' '; $tax_rules_groups = TaxRulesGroup::getTaxRulesGroups(true); $taxesRatesByGroup = TaxRulesGroup::getAssociatedTaxRatesByIdCountry(Country::getDefaultCountryId()); $ecotaxTaxRate = Tax::getProductEcotaxRate(); echo ''; echo ' '; if (Configuration::get('PS_USE_ECOTAX')) echo ' '; if ($default_country->display_tax_label) { echo ' '; } else { echo ''; } echo ' '; if ((int)Configuration::get('PS_STOCK_MANAGEMENT')) { if (!$has_attribute) { if ($obj->id) { echo ' '; } else echo ''; echo ''; } if ($obj->id) echo ' '; if ($has_attribute) echo ''; } else echo ''; echo ' '; echo ' '; $accessories = Product::getAccessoriesLight((int)($cookie->id_lang), $obj->id); if ($postAccessories = Tools::getValue('inputAccessories')) { $postAccessoriesTab = explode('-', Tools::getValue('inputAccessories')); foreach ($postAccessoriesTab AS $accessoryId) if (!$this->haveThisAccessory($accessoryId, $accessories) AND $accessory = Product::getAccessoryById($accessoryId)) $accessories[] = $accessory; } echo '


id OR Tools::getValue('is_virtual_good')=='true') AND $productDownload->active) echo 'checked="checked"' ?> />

id OR !$productDownload->active) echo 'style="display:none;"' ?> >

l('Your download repository is not writable.'); ?>

id) echo '' ?>

checkFile()): ?>

id): ?>

l('This product is missing') ?>:
physically_filename ?>

l('Your server\'s maximum upload file size is') . ': ' . ini_get('upload_max_filesize') ?>

l('This is the link').': '.$productDownload->getHtmlLink(false, true) ?> l('Delete this file') ?>

l('Format: YYYY-MM-DD'); ?>

*


'.$this->l('Pre-tax wholesale price:').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' '.$this->l('The wholesale price at which you bought this product').'
'.$this->l('Pre-tax retail price:').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' * '.$this->l('The pre-tax retail price to sell this product').'
'.$this->l('Tax rule:').' '.$this->l('Create').' '.$this->l('Create').' '; if (Tax::excludeTaxeOption()) { echo ''.$this->l('Taxes are currently disabled').' ('.$this->l('Tax options').')'; echo ''; } echo '
'.$this->l('Eco-tax (tax incl.):').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' ('.$this->l('already included in price').')
'.$this->l('Retail price with tax:').' '.($currency->format % 2 != 0 ? ' '.$currency->sign : '').' '.($currency->format % 2 == 0 ? ' '.$currency->sign : '').'
'.$this->l('Unit price without tax:').' '.($currency->format % 2 != 0 ? ' '.$currency->sign : '').' '.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' '.$this->l('per').' '. (Configuration::get('PS_TAX') && $default_country->display_tax_label ? ''.$this->l('or').' '.($currency->format % 2 != 0 ? ' '.$currency->sign : '').'0.00'.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' '.$this->l('per').' '.$this->getFieldValue($obj, 'unity').' '.$this->l('with tax') : '').'

'.$this->l('Eg. $15 per Lb').'

  getFieldValue($obj, 'on_sale') ? 'checked="checked"' : '').'value="1" /> 
'.$this->l('Final retail price:').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' ('.$this->l('tax incl.').') '; if ($default_country->display_tax_label) echo ' / '; echo ($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' '.($default_country->display_tax_label ? '('.$this->l('tax excl.').')' : '').'
 
'.$this->l('You can define many discounts and specific price rules in the Prices tab').'

'.$this->l('Stock Movement:').'   
 
'.$this->l('Choose the reason and enter the quantity that you want to increase or decrease in your stock').'
'.$this->l('Initial stock:').'
'.$this->l('Minimum quantity:').'

'.$this->l('The minimum quantity to buy this product (set to 1 to disable this feature)').'

'.$this->l('Quantity in stock:').' '.$qty.'
 
'.$this->l('You used combinations, for this reason you can\'t edit your stock quantity here, but in the Combinations tab').'
'.$this->l('The stock management is disabled').'

'.$this->l('Additional shipping cost:').' '.($currency->format % 2 == 0 ? ' '.$currency->sign : ''); if ($default_country->display_tax_label) echo ' ('.$this->l('tax excl.').')'; echo '

'.$this->l('Carrier tax will be applied.').'

'.$this->l('Displayed text when in-stock:').' '; foreach ($this->_languages as $language) echo '
'.$this->l('Forbidden characters:').' <>;=#{} 
'; echo '
'.$this->l('Displayed text when allowed to be back-ordered:').' '; foreach ($this->_languages as $language) echo '
'.$this->l('Forbidden characters:').' <>;=#{} 
'; echo '
'.$this->l('When out of stock:').' getFieldValue($obj, 'out_of_stock')) == 0 ? 'checked="checked"' : '').'/>
getFieldValue($obj, 'out_of_stock') == 1 ? 'checked="checked"' : '').'/>
getFieldValue($obj, 'out_of_stock') == 2 ? 'checked="checked"' : '').'/>

'; if (Tools::isSubmit('categoryBox')) { $postCat = Tools::getValue('categoryBox'); $selectedCat = Category::getSimpleCategories($this->_defaultFormLanguage, false, true, 'AND c.`id_category` IN ('.(empty($postCat) ? '1' : implode(',', $postCat)).')'); echo ''; } if ($obj->id) $selectedCat = Product::getProductCategoriesFull($obj->id, $this->_defaultFormLanguage); else if(!Tools::isSubmit('categoryBox')) $selectedCat[] = array('id_category' => 1, 'name' => $this->l('Home')); echo '
'; // Translations are not automatic for the moment ;) $trads = array( 'Home' => $this->l('Home'), 'selected' => $this->l('selected'), 'Collapse All' => $this->l('Collapse All'), 'Expand All' => $this->l('Expand All'), 'Check All' => $this->l('Check All'), 'Uncheck All' => $this->l('Uncheck All') ); echo Helper::renderAdminCategorieTree($trads, $selectedCat).'

'.$this->l('SEO').''.$this->l('Click here to improve product\'s rank in search engines (SEO)').'

'.$this->l('Short description:').'

('.$this->l('appears in search results').')
'; foreach ($this->_languages as $language) echo '
'; echo '
'.$this->l('Description:').' '; foreach ($this->_languages as $language) echo '
'; echo '
'.$this->l('Tags:').' '; if ($obj->id) $obj->tags = Tag::getProductTags((int)$obj->id); foreach ($this->_languages as $language) { echo '
'.$this->l('Forbidden characters:').' !<>;?=+#"°{}_$% 
'; } echo '

'.$this->l('Tags separated by commas (e.g., dvd, dvd player, hifi)').'

'.$this->l('Accessories:').'

'.$this->l('(Do not forget to Save the product afterward)').'
'; foreach ($accessories as $accessory) echo $accessory['name'].(!empty($accessory['reference']) ? ' ('.$accessory['reference'].')' : '').'
'; echo '

'.$this->l('Begin typing the first letters of the product name, then select the product from the drop-down list:').'

'.$this->l('Add an accessory').'

 

'; // TinyMCE global $cookie; $iso = Language::getIsoById((int)($cookie->id_lang)); $isoTinyMCE = (file_exists(_PS_ROOT_DIR_.'/js/tiny_mce/langs/'.$iso.'.js') ? $iso : 'en'); $ad = dirname($_SERVER["PHP_SELF"]); echo ' '; $categoryBox = Tools::getValue('categoryBox', array()); } function displayFormImages($obj, $token = NULL) { global $cookie, $currentIndex, $attributeJs, $images; $countImages = (int)Db::getInstance()->getValue('SELECT COUNT(*) FROM '._DB_PREFIX_.'image WHERE id_product = '.(int)$obj->id); echo '

2. '.$this->l('Images').' ('.$countImages.')

'.(Tools::getValue('id_image')?$this->l('Edit this product image'):$this->l('Add a new image to this product')).'


'; /* DEPRECATED FEATURE */ echo ' '; if (!sizeof($images) OR !isset($obj->id)) echo ''; else { echo '
'.$this->l('File:').'

'.$this->l('Format:').' JPG, GIF, PNG. '.$this->l('Filesize:').' '.($this->maxImageSize / 1000).''.$this->l('Kb max.').'
'.$this->l('You can also upload a ZIP file containing several images. Thumbnails will be resized automatically.').'

'.$this->l('Caption:').' '; foreach ($this->_languages as $language) { if (!Tools::getValue('legend_'.$language['id_lang'])) $legend = $this->getFieldValue($obj, 'name', $language['id_lang']); else $legend = Tools::getValue('legend_'.$language['id_lang']); echo '
* '.$this->l('Forbidden characters:').' <>;=#{}
'.$this->l('Forbidden characters will be automatically erased.').' 
'; } echo '

'.$this->l('Short description of the image').'

'.$this->l('Cover:').'

'.$this->l('If you want to select this image as a product cover').'

'.$this->l('Thumbnails resize method:').'

'.$this->l('Method you want to use to generate resized thumbnails').'

'; echo ''; $images = Image::getImages((int)($cookie->id_lang), $obj->id); $imagesTotal = Image::getImagesTotal($obj->id); if (isset($obj->id) AND sizeof($images)) { echo ''; echo '

'; } echo (Tools::getValue('id_image') ? '' : '').'

'.(Tools::isSubmit('id_category') ? '' : '').'  
'; foreach ($images AS $k => $image) { $image_obj = new Image($image['id_image']); $img_path = $image_obj->getExistingImgPath(); echo $this->_positionJS().' '; } } echo '
'.$this->l('Image').'   '.$this->l('Position').' '.$this->l('Cover').' '.$this->l('Action').'
'.htmlentities(stripslashes($image['legend']), ENT_COMPAT, 'UTF-8').' '.(int)($image['position']).' '; if ($image['position'] == 1) { echo '[ ]'; if ($image['position'] == $imagesTotal) echo '[ ]'; else echo '[ ]'; } elseif ($image['position'] == $imagesTotal) echo ' [ ] [ ]'; else echo ' [ ] [ ]'; echo ' '.$this->l('Modify this image').' '.$this->l('Delete this image').'
'; echo ' '; } public function initCombinationImagesJS() { global $cookie; if (!($obj = $this->loadObject(true))) return; $content = 'var combination_images = new Array();'; if (!$allCombinationImages = $obj->getCombinationImages((int)($cookie->id_lang))) return $content; foreach ($allCombinationImages AS $id_product_attribute => $combinationImages) { $i = 0; $content .= 'combination_images['.(int)($id_product_attribute).'] = new Array();'; foreach ($combinationImages AS $combinationImage) $content .= 'combination_images['.(int)($id_product_attribute).']['.$i++.'] = '.(int)($combinationImage['id_image']).';'; } return $content; } function displayFormAttributes($obj, $languages, $defaultLanguage) { global $currentIndex, $cookie; $attributeJs = array(); $attributes = Attribute::getAttributes((int)($cookie->id_lang), true); foreach ($attributes AS $k => $attribute) $attributeJs[$attribute['id_attribute_group']][$attribute['id_attribute']] = $attribute['name']; $currency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT')); $attributes_groups = AttributeGroup::getAttributesGroups((int)($cookie->id_lang)); $default_country = new Country((int)Configuration::get('PS_COUNTRY_DEFAULT')); $images = Image::getImages((int)($cookie->id_lang), $obj->id); if ($obj->id) { echo '
'.$this->l('Add or modify combinations for this product').' -  combinations_generator '.$this->l('Product combinations generator').'


'; if (Configuration::get('PS_USE_ECOTAX')) echo' '; echo'
'.$this->l('Group:').'
'.$this->l('Attribute:').'


'.$this->l('Reference:').' '.$this->l('EAN13:').' '.$this->l('UPC:').' '.$this->l('Special characters allowed:').' .-_# 
'.$this->l('Supplier Reference:').' '.$this->l('Location:').' '.$this->l('Special characters allowed:').' .-_# 

'.$this->l('Wholesale price:').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' ('.$this->l('overrides Wholesale price on Information tab').')
'.$this->l('Impact on price:').'   '.$this->l('of').'  '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').' '.($currency->format % 2 == 0 ? ' '.$currency->sign : ''); if ($default_country->display_tax_label) { echo ' '.$this->l('(tax excl.)').' '.$this->l('or').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').' '.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' '.$this->l('(tax incl.)').' '.$this->l('final product price will be set to').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').'0.00'.($currency->format % 2 == 0 ? $currency->sign.' ' : ''); } echo '
'.$this->l('Impact on weight:').'   '.$this->l('of').'   '.Configuration::get('PS_WEIGHT_UNIT').'
'.$this->l('Impact on unit price :').'   '.$this->l('of').'  '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').' '.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' / '.$this->getFieldValue($obj, 'unity').'
'.$this->l('Eco-tax:').' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').''.($currency->format % 2 == 0 ? ' '.$currency->sign : '').' ('.$this->l('overrides Eco-tax on Information tab').')
'.$this->l('Initial stock:').'
'.$this->l('Minimum quantity:').'

'.$this->l('The minimum quantity to buy this product (set to 1 to disable this feature)').'


'.$this->l('Image:').'
    '; $i = 0; $imageType = ImageType::getByNameNType('small', 'products'); $imageWidth = (isset($imageType['width']) ? (int)($imageType['width']) : 64) + 25; foreach ($images AS $image) { $imageObj = new Image($image['id_image']); echo '
  • '; ++$i; } echo '
'.$this->l('Default:').'

 '.$this->l('Make this the default combination for this product').'

 


'; if ($obj->id) { /* Build attributes combinaisons */ $combinaisons = $obj->getAttributeCombinaisons((int)($cookie->id_lang)); $groups = array(); if (is_array($combinaisons)) { $combinationImages = $obj->getCombinationImages((int)($cookie->id_lang)); foreach ($combinaisons AS $k => $combinaison) { $combArray[$combinaison['id_product_attribute']]['wholesale_price'] = $combinaison['wholesale_price']; $combArray[$combinaison['id_product_attribute']]['price'] = $combinaison['price']; $combArray[$combinaison['id_product_attribute']]['weight'] = $combinaison['weight']; $combArray[$combinaison['id_product_attribute']]['unit_impact'] = $combinaison['unit_price_impact']; $combArray[$combinaison['id_product_attribute']]['reference'] = $combinaison['reference']; $combArray[$combinaison['id_product_attribute']]['supplier_reference'] = $combinaison['supplier_reference']; $combArray[$combinaison['id_product_attribute']]['ean13'] = $combinaison['ean13']; $combArray[$combinaison['id_product_attribute']]['upc'] = $combinaison['upc']; $combArray[$combinaison['id_product_attribute']]['minimal_quantity'] = $combinaison['minimal_quantity']; $combArray[$combinaison['id_product_attribute']]['location'] = $combinaison['location']; $combArray[$combinaison['id_product_attribute']]['quantity'] = $combinaison['quantity']; $combArray[$combinaison['id_product_attribute']]['id_image'] = isset($combinationImages[$combinaison['id_product_attribute']][0]['id_image']) ? $combinationImages[$combinaison['id_product_attribute']][0]['id_image'] : 0; $combArray[$combinaison['id_product_attribute']]['default_on'] = $combinaison['default_on']; $combArray[$combinaison['id_product_attribute']]['ecotax'] = $combinaison['ecotax']; $combArray[$combinaison['id_product_attribute']]['attributes'][] = array($combinaison['group_name'], $combinaison['attribute_name'], $combinaison['id_attribute']); if ($combinaison['is_color_group']) $groups[$combinaison['id_attribute_group']] = $combinaison['group_name']; } } $irow = 0; if (isset($combArray)) { foreach ($combArray AS $id_product_attribute => $product_attribute) { $list = ''; $jsList = ''; /* In order to keep the same attributes order */ asort($product_attribute['attributes']); foreach ($product_attribute['attributes'] AS $attribute) { $list .= addslashes(htmlspecialchars($attribute[0])).' - '.addslashes(htmlspecialchars($attribute[1])).', '; $jsList .= '\''.addslashes(htmlspecialchars($attribute[0])).' : '.addslashes(htmlspecialchars($attribute[1])).'\', \''.$attribute[2].'\', '; } $list = rtrim($list, ', '); $jsList = rtrim($jsList, ', '); $attrImage = $product_attribute['id_image'] ? new Image($product_attribute['id_image']) : false; echo ' '; } echo ''; } else echo ''; } echo '
'.$this->l('Attributes').' '.$this->l('Impact').' '.$this->l('Weight').' '.$this->l('Reference').' '.$this->l('EAN13').' '.$this->l('UPC').' '.$this->l('Quantity').' '.$this->l('Actions').'
'.stripslashes($list).' '.($currency->format % 2 != 0 ? $currency->sign.' ' : '').$product_attribute['price'].($currency->format % 2 == 0 ? ' '.$currency->sign : '').' '.$product_attribute['weight'].Configuration::get('PS_WEIGHT_UNIT').' '.$product_attribute['reference'].' '.$product_attribute['ean13'].' '.$product_attribute['upc'].' '.$product_attribute['quantity'].' '.$this->l('Modify this combination').'  '.(!$product_attribute['default_on'] ? ' '.$this->l('Make this the default combination').'' : '').' '.$this->l('Delete this combination').'
'.$this->l('Delete this combination').' '.$this->l('Delete all combinations').'
'.$this->l('No combination yet').'.

'.$this->l('The row in blue is the default combination.').'
'.$this->l('A default combination must be designated for each product.').'

'.$this->l('Color picker:').'         '.$this->l('Color attribute management').'

'.$this->l('Activate the color choice by selecting a color attribute group.').'

'; } else echo ''.$this->l('You must save this product before adding combinations').'.'; } function displayFormFeatures($obj) { global $cookie, $currentIndex; parent::displayForm(); if ($obj->id) { $feature = Feature::getFeatures((int)($cookie->id_lang)); $ctab = ''; foreach ($feature AS $tab) $ctab .= 'ccustom_'.$tab['id_feature'].'¤'; $ctab = rtrim($ctab, '¤'); echo '
'.$this->l('Assign features to this product:').'
  • '.$this->l('You can specify a value for each relevant feature regarding this product, empty fields will not be displayed.').'
  • '.$this->l('You can either set a specific value, or select among existing pre-defined values you added previously.').'


'; // Header $nb_feature = Feature::nbFeatures((int)($cookie->id_lang)); echo ' '; if (!$nb_feature) echo ''; echo '
'.$this->l('Feature').' '.$this->l('Pre-defined value').' '.$this->l('or').' '.$this->l('Customized value').'
'.$this->l('No features defined').'
'; // Listing if ($nb_feature) { echo ' '; foreach ($feature AS $tab_features) { $current_item = false; $custom = true; foreach ($obj->getFeatures() as $tab_products) if ($tab_products['id_feature'] == $tab_features['id_feature']) $current_item = $tab_products['id_feature_value']; $featureValues = FeatureValue::getFeatureValuesWithLang((int)$cookie->id_lang, (int)$tab_features['id_feature']); echo ' '; } echo ' '; } echo '
'.$tab_features['name'].' '; if (sizeof($featureValues)) { echo ' '; } else echo ''.$this->l('N/A').' - '.$this->l('Add pre-defined values first').''; echo ' '; $tab_customs = ($custom ? FeatureValue::getFeatureValueLang($current_item) : array()); foreach ($this->_languages as $language) echo '
'; echo '

new_features '.$this->l('Add a new feature').'
'; } else echo ''.$this->l('You must save this product before adding features').'.'; } public function haveThisAccessory($accessoryId, $accessories) { foreach ($accessories AS $accessory) if ((int)($accessory['id_product']) == (int)($accessoryId)) return true; return false; } private function displayPack(Product $obj) { global $currentIndex, $cookie; $boolPack = (($obj->id AND Pack::isPack($obj->id)) OR Tools::getValue('ppack')) ? true : false; $packItems = $boolPack ? Pack::getItems($obj->id, $cookie->id_lang) : array(); echo ' '; // param multipleSeparator:'||' ajouté à cause de bug dans lib autocomplete echo ''; } private function addPackItem() { return ' function addPackItem() { if ($(\'#curPackItemId\').val() == \'\' || $(\'#curPackItemName\').val() == \'\') { alert(\''.$this->l('Thanks to select at least one product.').'\'); return false; } else if ($(\'#curPackItemId\').val() == \'\' || $(\'#curPackItemQty\').val() == \'\') { alert(\''.$this->l('Thanks to set a quantity to add a product.').'\'); return false; } var lineDisplay = $(\'#curPackItemQty\').val()+ \'x \' +$(\'#curPackItemName\').val(); var divContent = $(\'#divPackItems\').html(); divContent += lineDisplay; divContent += \'
\'; // QTYxID-QTYxID var line = $(\'#curPackItemQty\').val()+ \'x\' +$(\'#curPackItemId\').val(); $(\'#inputPackItems\').val($(\'#inputPackItems\').val() + line + \'-\'); $(\'#divPackItems\').html(divContent); $(\'#namePackItems\').val($(\'#namePackItems\').val() + lineDisplay + \'¤\'); $(\'#curPackItemId\').val(\'\'); $(\'#curPackItemName\').val(\'\'); $(\'#curPackItemName\').setOptions({ extraParams: {excludeIds : getSelectedIds()} }); } '; } private function delPackItem() { return ' function delPackItem(id) { var reg = new RegExp(\'-\', \'g\'); var regx = new RegExp(\'x\', \'g\'); var div = getE(\'divPackItems\'); var input = getE(\'inputPackItems\'); var name = getE(\'namePackItems\'); var select = getE(\'curPackItemId\'); var select_quantity = getE(\'curPackItemQty\'); var inputCut = input.value.split(reg); var nameCut = name.value.split(new RegExp(\'¤\', \'g\')); input.value = \'\'; name.value = \'\'; div.innerHTML = \'\'; for (var i = 0; i < inputCut.length; ++i) if (inputCut[i]) { var inputQty = inputCut[i].split(regx); if (inputQty[1] != id) { input.value += inputCut[i] + \'-\'; name.value += nameCut[i] + \'¤\'; div.innerHTML += nameCut[i] + \'
\'; } } $(\'#curPackItemName\').setOptions({ extraParams: {excludeIds : getSelectedIds()} }); }'; } private function _positionJS() { return ''; } public function updatePackItems($product) { Pack::deleteItems($product->id); // lines format: QTY x ID-QTY x ID if (Tools::getValue('ppack') AND $items = Tools::getValue('inputPackItems') AND sizeof($lines = array_unique(explode('-', $items)))) { foreach($lines as $line) { // line format QTY x ID list($qty, $item_id) = explode('x', $line); if ($qty > 0 && isset($item_id)) { if (!Pack::addItem((int)($product->id), (int)($item_id), (int)($qty))) return false; } } } return true; } public function getL($key) { $trad = array( 'Default category:' => $this->l('Default category:'), 'Catalog:' => $this->l('Catalog:'), 'Consider changing the default category.' => $this->l('Consider changing the default category.'), 'ID' => $this->l('ID'), 'Name' => $this->l('Name'), 'Mark all checkbox(es) of categories in which product is to appear' => $this->l('Mark all checkbox(es) of categories in which product is to appear') ); return $trad[$key]; } }