* @copyright PrestaShop
* @license http://www.opensource.org/licenses/osl-3.0.php Open-source licence 3.0
* @version 1.2
*/
include_once(PS_ADMIN_DIR.'/../classes/AdminTab.php');
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),
'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'),
'active' => array('title' => $this->l('Displayed'), 'active' => 'status', '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` t ON (t.`id_tax` = a.`id_tax`)';
$this->_filter = 'AND cp.`id_category` = '.intval($this->_category->id);
$this->_select = 'cp.`position`, i.`id_image`, (a.`price` * ((100 + (t.`rate`))/100) - IF((DATEDIFF(a.`reduction_from`, CURDATE()) <= 0 AND DATEDIFF(a.`reduction_to`, CURDATE()) >=0) OR a.`reduction_from` = a.`reduction_to`, IF(a.`reduction_price` > 0, a.`reduction_price`, (a.`price` * ((100 + (t.`rate`))/100) * a.`reduction_percent` / 100)),0)) AS price_final';
parent::__construct();
}
protected function copyFromPost(&$object, $table)
{
parent::copyFromPost($object, $table);
if (get_class($object) != 'Product')
return;
/* Additional fields */
$languages = Language::getLanguages();
foreach ($languages as $language)
if (isset($_POST['meta_keywords_'.$language['id_lang']]))
$_POST['meta_keywords_'.$language['id_lang']] = preg_replace('/ *,? +,*/', ',', strtolower($_POST['meta_keywords_'.$language['id_lang']]));
$_POST['weight'] = empty($_POST['weight']) ? '0' : str_replace(',', '.', $_POST['weight']);
if ($_POST['reduction_price'] != NULL) $object->reduction_price = str_replace(',', '.', $_POST['reduction_price']);
if ($_POST['reduction_percent'] != NULL) $object->reduction_percent = str_replace(',', '.', $_POST['reduction_percent']);
if ($_POST['ecotax'] != NULL) $object->ecotax = str_replace(',', '.', $_POST['ecotax']);
$object->active = (!isset($_POST['active']) OR $_POST['active']) ? true : false;
$object->on_sale = (!isset($_POST['on_sale']) ? false : true);
}
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(Tools::getValue('id_product'))))
return false;
$productDownload = new ProductDownload(intval($id_product_download));
return $productDownload->deleteFile();
}
public function postProcess($token = NULL)
{
global $currentIndex;
/* Add a new product */
if (Tools::isSubmit('submitAddproduct') OR Tools::isSubmit('submitAddproductAndStay'))
{
if (Tools::getValue('id_product') AND $this->tabAccess['edit'] === '1')
$this->submitAddproduct($token);
elseif ($this->tabAccess['add'] === '1' AND !Tools::isSubmit('id_product'))
$this->submitAddproduct($token);
else
$this->_errors[] = Tools::displayError('You do not have permission to add anything 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 anything here.');
}
/* Update attachments */
elseif (Tools::isSubmit('submitAttachments'))
{
if ($this->tabAccess['edit'] === '1')
if ($id = intval(Tools::getValue($this->identifier)))
if (Attachment::attachToProduct($id, $_POST['attachments']))
Tools::redirectAdmin($currentIndex.'&id_product='.$id.'&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(intval(Tools::getValue('id_product')))))
{
$id_product_old = $product->id;
unset($product->id);
unset($product->id_product);
$product->indexed = 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::duplicateQuantityDiscount($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 (!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);
Tools::redirectAdmin($currentIndex.'&id_category='.intval(Tools::getValue('id_category')).'&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 anything 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 = intval(Tools::getValue('id_category'))) 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 anything 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 them');
else
{
$this->deleteImage($object->id);
if ($this->deleted)
{
$object->deleted = 1;
if ($object->update())
Tools::redirectAdmin($currentIndex.'&conf=1&token='.($token ? $token : $this->token));
}
elseif ($object->delete())
Tools::redirectAdmin($currentIndex.'&conf=1&token='.($token ? $token : $this->token));
$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.');
}
/* Product images management */
elseif (($id_image = intval(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();
deleteImage($image->id_product, $image->id);
if (!Image::getCover($image->id_product))
{
$first_img = Db::getInstance()->getRow('
SELECT `id_image` FROM `'._DB_PREFIX_.'image`
WHERE `id_product` = '.intval($image->id_product));
Db::getInstance()->Execute('
UPDATE `'._DB_PREFIX_.'image`
SET `cover` = 1
WHERE `id_image` = '.intval($first_img['id_image']));
}
@unlink(dirname(__FILE__).'/../../img/tmp/product_'.$image->id_product.'.jpg');
@unlink(dirname(__FILE__).'/../../img/tmp/product_mini_'.$image->id_product.'.jpg');
Tools::redirectAdmin($currentIndex.'&id_product='.$image->id_product.'&id_category='.intval(Tools::getValue('id_category')).'&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();
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('Impossible to change the product cover');
else
{
$productId = intval(Tools::getValue('id_product'));
@unlink(dirname(__FILE__).'/../../img/tmp/product_'.$productId.'.jpg');
@unlink(dirname(__FILE__).'/../../img/tmp/product_mini_'.$productId.'.jpg');
Tools::redirectAdmin($currentIndex.'&id_product='.$image->id_product.'&id_category='.intval(Tools::getValue('id_category')).'&addproduct&tabs=1'.'&token='.($token ? $token : $this->token));
}
}
/* Choose product image position */
elseif (isset($_GET['imgPosition']) AND isset($_GET['imgDirection']))
{
$image->positionImage(intval(Tools::getValue('imgPosition')), intval(Tools::getValue('imgDirection')));
Tools::redirectAdmin($currentIndex.'&id_product='.$image->id_product.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=1&token='.($token ? $token : $this->token));
}
}
else
$this->_errors[] = Tools::displayError('You do not have permission to edit anything here.');
}
/* Product attributes management */
elseif (Tools::isSubmit('submitProductAttribute'))
{
if (Validate::isLoadedObject($product = new Product(intval(Tools::getValue('id_product')))))
{
if (!isset($_POST['attribute_quantity']) OR $_POST['attribute_quantity'] == NULL)
$this->_errors[] = Tools::displayError('attribute quantity is required');
if (!isset($_POST['attribute_price']) OR $_POST['attribute_price'] == NULL)
$this->_errors[] = Tools::displayError('attribute price is 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 = intval(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_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'));
}
else
$this->_errors[] = Tools::displayError('You do not have permission to add anything 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_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'));
}
else
$this->_errors[] = Tools::displayError('You do not have permission to').'
'.Tools::displayError('edit something here.');
}
if (!sizeof($this->_errors))
{
$product->addAttributeCombinaison($id_product_attribute, Tools::getValue('attribute_combinaison_list'));
$product->checkDefaultAttributes();
}
if (!sizeof($this->_errors))
Tools::redirectAdmin($currentIndex.'&id_product='.$product->id.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=2&token='.($token ? $token : $this->token));
}
}
}
elseif (Tools::isSubmit('deleteProductAttribute'))
{
if ($this->tabAccess['delete'] === '1')
{
if (($id_product = intval(Tools::getValue('id_product'))) AND Validate::isUnsignedId($id_product) AND Validate::isLoadedObject($product = new Product($id_product)))
{
$product->deleteAttributeCombinaison(intval(Tools::getValue('id_product_attribute')));
$product->checkDefaultAttributes();
Tools::redirectAdmin($currentIndex.'&add'.$this->table.'&id_category='.intval(Tools::getValue('id_category')).'&tabs=2&id_product='.$product->id.'&token='.($token ? $token : $this->token));
}
else
$this->_errors[] = Tools::displayError('impossible to 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 = intval(Tools::getValue('id_product'))) AND Validate::isUnsignedId($id_product) AND Validate::isLoadedObject($product = new Product($id_product)))
{
$product->deleteProductAttributes();
Tools::redirectAdmin($currentIndex.'&add'.$this->table.'&id_category='.intval(Tools::getValue('id_category')).'&tabs=2&id_product='.$product->id.'&token='.($token ? $token : $this->token));
}
else
$this->_errors[] = Tools::displayError('impossible to delete attributes');
}
else
$this->_errors[] = Tools::displayError('You do not have permission to delete here.');
}
/* Product features management */
elseif (Tools::isSubmit('submitProductFeature'))
{
if ($this->tabAccess['edit'] === '1')
{
if (Validate::isLoadedObject($product = new Product(intval(Tools::getValue('id_product')))))
{
// delete all objects
$product->deleteFeatures();
// add new objects
$languages = Language::getLanguages();
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, $language['id_lang']);
foreach ($languages AS $language)
{
if ($cust = Tools::getValue('custom_'.$match[1].'_'.$language['id_lang']))
$product->addFeaturesCustomToDB($id_value, $language['id_lang'], $cust);
else
$product->addFeaturesCustomToDB($id_value, $language['id_lang'], $default_value);
}
}
}
}
}
if (!sizeof($this->_errors))
Tools::redirectAdmin($currentIndex.'&id_product='.$product->id.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=3&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 anything here.');
}
/* Product quantity discount management */
elseif (Tools::isSubmit('submitQuantityDiscount'))
{
$_POST['tabs'] = 5;
if ($this->tabAccess['add'] === '1')
{
if (Validate::isLoadedObject($product = new Product(intval(Tools::getValue('id_product')))))
{
if (!($id_discount_type = intval(Tools::getValue('id_discount_type'))))
$this->_errors[] = Tools::displayError('discount type not selected');
elseif (!($quantity_discount = intval(Tools::getValue('quantity_discount'))) OR $quantity_discount <= 1)
$this->_errors[] = Tools::displayError('quantity is required and must be superior of 1');
elseif (!($value_discount = floatval(Tools::getValue('value_discount'))))
$this->_errors[] = Tools::displayError('value is required');
elseif ($value_discount > 100 AND $id_discount_type == 1)
$this->_errors[] = Tools::displayError('value is incorrect');
else
{
$qD = new QuantityDiscount();
$qD->id_product = $product->id;
$qD->id_discount_type = $id_discount_type;
$qD->quantity = $quantity_discount;
$qD->value = $value_discount;
if ($qD->add() AND !sizeof($this->_errors) AND $qD->validateFields())
Tools::redirectAdmin($currentIndex.'&id_product='.$product->id.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=5&conf=3&token='.($token ? $token : $this->token));
$this->_errors[] = Tools::displayError('an error occurred while creating object');
}
}
else
$this->_errors[] = Tools::displayError('product must be created before adding quantity discounts');
}
else
$this->_errors[] = Tools::displayError('You do not have permission to add anything here.');
}
elseif (isset($_GET['deleteQuantityDiscount']))
{
if ($this->tabAccess['delete'] === '1')
{
if (Validate::isLoadedObject($product = new Product(intval(Tools::getValue('id_product')))))
{
if (Validate::isLoadedObject($qD = new QuantityDiscount(intval(Tools::getValue('id_quantity_discount')))))
{
$qD->delete();
if (!sizeof($this->_errors))
Tools::redirectAdmin($currentIndex.'&id_product='.$product->id.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=5&conf=1&token='.($token ? $token : $this->token));
}
else
$this->_errors[] = Tools::displayError('not a valid quantity discount');
} else
$this->_errors[] = Tools::displayError('product must be created before delete quantity discounts');
$qD = new QuantityDiscount();
}
else
$this->_errors[] = Tools::displayError('You do not have permission to delete here.');
}
/* Customization management */
elseif (Tools::isSubmit('submitCustomizationConfiguration'))
{
if ($this->tabAccess['edit'] === '1')
{
if (Validate::isLoadedObject($product = new Product(intval(Tools::getValue('id_product')))))
{
if (!$product->createLabels(intval($_POST['uploadable_files']) - intval($product->uploadable_files), intval($_POST['text_fields']) - intval($product->text_fields)))
$this->_errors[] = Tools::displayError('an error occured while creating customization fields');
if (!sizeof($this->_errors) AND !$product->updateLabels())
$this->_errors[] = Tools::displayError('an error occured while updating customization');
$product->uploadable_files = intval($_POST['uploadable_files']);
$product->text_fields = intval($_POST['text_fields']);
$product->customizable = (intval($_POST['uploadable_files']) > 0 OR intval($_POST['text_fields']) > 0) ? 1 : 0;
if (!sizeof($this->_errors) AND !$product->update())
$this->_errors[] = Tools::displayError('an error occured while updating customization configuration');
if (!sizeof($this->_errors))
Tools::redirectAdmin($currentIndex.'&id_product='.$product->id.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=4&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 anything here.');
}
elseif (Tools::isSubmit('submitProductCustomization'))
{
if ($this->tabAccess['edit'] === '1')
{
if (Validate::isLoadedObject($product = new Product(intval(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 occured while updating customization');
if (!sizeof($this->_errors))
Tools::redirectAdmin($currentIndex.'&id_product='.$product->id.'&id_category='.intval(Tools::getValue('id_category')).'&add'.$this->table.'&tabs=4&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 anything here.');
}
else
parent::postProcess(true);
}
// 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 = (intval(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']['tmp_name']) AND $_FILES['image_product']['tmp_name'] != NULL)
{
if (!Validate::isLoadedObject($product))
$this->_errors[] = Tools::displayError('cannot add image because product add failed');
else
{
$image = new Image();
$image->id_product = intval($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_IMG_DIR_.'p/'.$image->id_product.'-'.$image->id.'.jpg'))
$image->delete();
if (sizeof($this->_errors))
return false;
@unlink(dirname(__FILE__).'/../../img/tmp/product_'.$product->id.'.jpg');
@unlink(dirname(__FILE__).'/../../img/tmp/product_mini_'.$product->id.'.jpg');
return ((isset($id_image) AND is_int($id_image) AND $id_image) ? $id_image : true);
}
/**
* Copy a product image
*
* @param integer $id_product Product Id for product image filename
* @param integer $id_image Image Id for product image filename
*/
public function copyImage($id_product, $id_image, $method = 'auto')
{
if (!isset($_FILES['image_product']['tmp_name']) OR !file_exists($_FILES['image_product']['tmp_name']))
return false;
if ($error = checkImage($_FILES['image_product'], $this->maxImageSize))
$this->_errors[] = $error;
else
{
if (!$tmpName = tempnam(_PS_TMP_IMG_DIR_, 'PS') OR !move_uploaded_file($_FILES['image_product']['tmp_name'], $tmpName))
$this->_errors[] = Tools::displayError('An error occured during the image upload');
elseif (!imageResize($tmpName, _PS_IMG_DIR_.'p/'.$id_product.'-'.$id_image.'.jpg'))
$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, _PS_IMG_DIR_.'p/'.$id_product.'-'.$id_image.'-'.stripslashes($imageType['name']).'.jpg', $imageType['width'], $imageType['height']))
$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 $currentIndex;
$className = 'Product';
$rules = call_user_func(array($this->className, 'getValidationRules'), $this->className);
$defaultLanguage = new Language(intval(Configuration::get('PS_LANG_DEFAULT')));
$languages = Language::getLanguages();
/* 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');
$productCats = '';
if (!isset($_POST['categoryBox']) OR !sizeof($_POST['categoryBox']))
$this->_errors[] = $this->l('product must be in at least one Category');
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 = intval(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->copyFromPost($object, $this->table);
if ($object->update())
{
$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='.intval(Tools::getValue('id_image'));
Hook::updateProduct($object);
Search::indexation(false);
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='.intval(Tools::getValue('id_category')).'&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 stay on same form
if (Tools::isSubmit('submitAdd'.$this->table.'AndStay') OR ($id_image AND $id_image !== true))
Tools::redirectAdmin($currentIndex.'&id_product='.$object->id.'&id_category='.intval(Tools::getValue('id_category')).'&addproduct&conf=4&tabs='.intval(Tools::getValue('tabs')).'&token='.($token ? $token : $this->token));
// Default behavior (save and back)
Tools::redirectAdmin($currentIndex.'&id_category='.intval(Tools::getValue('id_category')).'&conf=4&token='.($token ? $token : $this->token));
}
}
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->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');
else if (!$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);
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='.intval(Tools::getValue('id_category')).'&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='.intval(Tools::getValue('id_category')).'&addproduct&conf=3&tabs='.intval(Tools::getValue('tabs')).'&token='.($token ? $token : $this->token));
// Default behavior (save and back)
Tools::redirectAdmin($currentIndex.'&id_category='.intval(Tools::getValue('id_category')).'&conf=3&token='.($token ? $token : $this->token));
}
}
else
$object->delete();
}
else
$this->_errors[] = Tools::displayError('an error occurred while creating object').' '.$this->table.' ';
}
}
}
/**
* 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'))
{
$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` = '.intval($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'], intval($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(intval($cookie->id_lang), !$cookie->__get($this->table.'Orderby') ? 'position' : NULL, !$cookie->__get($this->table.'Orderway') ? 'ASC' : NULL);
$id_category = intval(Tools::getValue('id_category'));
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(Category::hideCategoryPosition($this->_category->getName())).'" ';
echo ' '.$this->l('Add a new product').'
';
$this->displayList($token);
echo '
';
}
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
*/
function recurseCategoryForInclude($indexedCategories, $categories, $current, $id_category = 1, $id_category_default = NULL)
{
global $done;
static $irow;
$id_obj = intval(Tools::getValue($this->identifier));
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;
$img = $level == 1 ? 'lv1.gif' : 'lv'.$level.'_'.($todo == $doneC ? 'f' : 'b').'.gif';
echo '
'.$id_category.'
'.stripslashes(Category::hideCategoryPosition($current['infos']['name'])).'
';
if (isset($categories[$id_category]))
foreach ($categories[$id_category] AS $key => $row)
if ($key != 'infos')
$this->recurseCategoryForInclude($indexedCategories, $categories, $categories[$id_category][$key], $key);
}
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 ''.$error.' ';
echo '
';
}
}
public function displayForm($isMainTab = true)
{
global $currentIndex, $link, $cookie;
parent::displayForm();
if ($id_category_back = intval(Tools::getValue('id_category')))
$currentIndex .= '&id_category='.$id_category_back;
$obj = $this->loadObject(true);
$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').'
';
if (Tools::getValue('id_category') > 1)
{
$productIndex = preg_replace('/(&id_product=[0-9]*)/', '', $currentIndex);
echo '
'.$this->l('Back to the category').'
';
}
}
function displayFormQuantityDiscount($obj, $languages, $defaultLanguage)
{
global $cookie, $currentIndex;
if ($obj->id)
{
$quantityDiscounts = QuantityDiscount::getQuantityDiscounts($obj->id, false);
$defaultCurrency = new Currency(Configuration::get('PS_CURRENCY_DEFAULT'));
echo '
'.$this->l('Add quantity discount to this product').'
';
}
else
echo ''.$this->l('You must save this product before adding quantity discounts').'. ';
}
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_.'_'.intval($id_customization_field);
if (isset($labels[_CUSTOMIZE_TEXTFIELD_]))
foreach ($labels[_CUSTOMIZE_TEXTFIELD_] AS $id_customization_field => $label)
$customizableFieldIds[] = 'label_'._CUSTOMIZE_TEXTFIELD_.'_'.intval($id_customization_field);
$j = 0;
for ($i = $alreadyGenerated[_CUSTOMIZE_FILE_]; $i < intval($this->getFieldValue($obj, 'uploadable_files')); $i++)
$customizableFieldIds[] = 'newLabel_'._CUSTOMIZE_FILE_.'_'.$j++;
$j = 0;
for ($i = $alreadyGenerated[_CUSTOMIZE_TEXTFIELD_]; $i < intval($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.'_'.intval($id_customization_field);
$fieldsContainerName = 'labelContainer_'.$type.'_'.intval($id_customization_field);
echo '';
foreach ($languages as $language)
{
$fieldName = 'label_'.$type.'_'.intval($id_customization_field).'_'.intval($language['id_lang']);
echo '
';
}
echo '
'.$this->l('required').'
';
}
private function _displayLabelFields(&$obj, &$labels, $languages, $defaultLanguage, $type)
{
$type = intval($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, intval($id_customization_field));
}
function displayFormCustomization($obj, $languages, $defaultLanguage)
{
parent::displayForm(false);
$labels = $obj->getCustomizationFields();
$defaultIso = Language::getIsoById($defaultLanguage);
$hasFileLabels = intval($this->getFieldValue($obj, 'uploadable_files'));
$hasTextLabels = intval($this->getFieldValue($obj, 'text_fields'));
echo '
'.$this->l('Add or modify customizable properties').'
';
}
function displayFormAttachments($obj, $languages, $defaultLanguage)
{
global $currentIndex, $cookie;
$obj = $this->loadObject(true);
$languages = Language::getLanguages();
$attach1 = Attachment::getAttachments($cookie->id_lang, $obj->id, true);
$attach2 = Attachment::getAttachments($cookie->id_lang, $obj->id, false);
echo '
'.$this->l('Upload new attachment').'
';
}
function displayFormInformations($obj, $currency)
{
parent::displayForm();
global $currentIndex, $cookie;
$iso = Language::getIsoById(intval($cookie->id_lang));
$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 = '';
}
$cover = Product::getCover($obj->id);
$link = new Link();
//includeDatepicker(array('reduction_from', 'reduction_to'));
echo '
1. '.$this->l('Info.').'
'.$this->l('Product global informations').' - ';
if (isset($obj->id))
{
echo '
'.$this->l('View product in shop').'';
if (file_exists(_PS_MODULE_DIR_.'statsproduct/statsproduct.php'))
echo ' -
'.$this->l('View product sales').'';
}
echo '
'.$this->l('Name:').'
';
foreach ($this->_languages as $language)
echo '
id) ? ' onkeyup="copy2friendlyURL();"' : '').' onkeyup="updateCurrentText();" onchange="updateCurrentText();" /> *
'.$this->l('Invalid characters:').' <>;=#{}
';
echo '
'.$this->l('Status:').'
getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
'.$this->l('Enabled').'
getFieldValue($obj, 'active') ? 'checked="checked" ' : '').'/>
'.$this->l('Disabled').'
'.$this->l('Manufacturer:').'
-- '.$this->l('Choose (optional)').' -- ';
if ($id_manufacturer = $this->getFieldValue($obj, 'id_manufacturer'))
echo ' '.Manufacturer::getNameById($id_manufacturer).'
---------- ';
echo '
'.$this->l('Create').'
'.$this->l('Supplier:').'
-- '.$this->l('Choose (optional)').' -- ';
if ($id_supplier = $this->getFieldValue($obj, 'id_supplier'))
echo ' '.Supplier::getNameById($id_supplier).'
---------- ';
echo '
'.$this->l('Create').'
'.$this->l('Reference:').'
'.$this->l('EAN13:').'
'.$this->l('Special characters allowed:').' .-_#\
'.$this->l('Supplier Reference:').'
'.$this->l('Location:').'
'.$this->l('Special characters allowed:').' .-_#\
'.$this->l('Weight:').'
'.Configuration::get('PS_WEIGHT_UNIT').'
';
$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);
?>
var newLabel = \''.$this->l('New label').'\';
var choose_language = \''.$this->l('Choose language:').'\';
var required = \''.$this->l('required').'\';
var customizationUploadableFileNumber = '.intval($this->getFieldValue($obj, 'uploadable_files')).';
var customizationTextFieldNumber = '.intval($this->getFieldValue($obj, 'text_fields')).';
var uploadableFileLabel = 0;
var textFieldLabel = 0;
';
?>
id OR Tools::getValue('is_virtual_good')=='true') AND $productDownload->active) echo 'checked="checked"' ?> />
l('Is this a downloadable product?') ?>
'.$this->l('Pre-tax wholesale price:').'
'.($currency->format == 1 ? $currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').'
'.$this->l('The wholesale price at which you bought this product').'
';
echo '
'.$this->l('Pre-tax retail price:').'
'.($currency->format == 1 ? $currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').' *
'.$this->l('The pre-tax retail price to sell this product').'
';
$taxes = Tax::getTaxes(intval($cookie->id_lang));
echo '';
echo '
'.$this->l('Tax:').'
getFieldValue($obj, 'id_tax') == 0) ? ' selected="selected"' : '').'>'.$this->l('No tax').' ';
foreach ($taxes AS $k => $tax)
echo '
getFieldValue($obj, 'id_tax') == $tax['id_tax']) ? ' selected="selected"' : '').'>'.stripslashes($tax['name']).' ('.$tax['rate'].'%) ';
echo '
';
if (Tax::excludeTaxeOption())
{
echo ''.$this->l('Taxes are currently disabled').' ('.$this->l('Tax options').' )';
echo ' ';
}
echo '
'.$this->l('Retail price with tax:').'
'.($currency->format == 1 ? ' '.$currency->sign : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').'
'.$this->l('Eco-tax:').'
'.($currency->format == 1 ? $currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').'
('.$this->l('already included in price').')
'.$this->l('Reduction amount:').'
'.($currency->format == 1 ? ' '.$currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').'
'.$this->l('OR').'
%
'.$this->l('available from').'
'.$this->l('to').'
'.$this->l('Leave same dates for undefined duration').'
getFieldValue($obj, 'on_sale') ? 'checked="checked"' : '').'value="1" /> '.$this->l('Display "on sale" icon on product page and text on product listing').'
'.$this->l('Final retail price:').'
'.($currency->format == 1 ? $currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').'
'.$this->l('Quantity:').'
l('Quantity is already defined by Attributes').'. '.$this->l('Delete attributes first').'.\');" readonly="readonly" ' : '').'/> * ('.$this->l('If you use combinations, you can\'t edit this information').')
'.$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"' : '').'/> '.$this->l('Deny orders').'
getFieldValue($obj, 'out_of_stock') == 1 ? 'checked="checked"' : '').'/> '.$this->l('Allow orders').'
getFieldValue($obj, 'out_of_stock') == 2 ? 'checked="checked"' : '').'/> '.$this->l('Default:').' '.$this->l((intval(Configuration::get('PS_ORDER_OUT_OF_STOCK')) ? 'Allow orders' : 'Deny orders')).' ('.$this->l('as set in').' '.$this->l('Preferences').' )
'.$this->l('Default category:').'
';
$categories = Category::getCategories(intval($cookie->id_lang), false);
Category::recurseCategory($categories, $categories[0][1], 1, ($this->getFieldValue($obj, 'id_category_default') ? $this->getFieldValue($obj, 'id_category_default') : Tools::getValue('id_category', 1)));
echo '
'.$this->l('Catalog:').'
'.$this->l('Mark all checkbox(es) of categories in which product is to appear').' *
'.$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 '
';
echo '
'.$this->l('Tags:').'
';
foreach ($this->_languages as $language)
{
echo '
'.$this->l('Forbidden characters:').' !<>;?=+#"°{}_$%
';
}
echo ' '.$this->l('Tags separated by commas (e.g., dvd, dvd player, hifi)').'
';
$accessories = Product::getAccessoriesLight(intval($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 '
'.$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 '
';
}
function displayFormImages($obj, $token = NULL)
{
global $cookie, $currentIndex, $attributeJs, $images;
echo '
2. '.$this->l('Images').'
'.$this->l('Add a new image to this product').'
';
echo '
';
}
public function initCombinationImagesJS()
{
global $cookie;
$content = 'var combination_images = new Array();';
if (!$allCombinationImages = $this->loadObject(true)->getCombinationImages(intval($cookie->id_lang)))
return $content;
foreach ($allCombinationImages AS $id_product_attribute => $combinationImages)
{
$i = 0;
$content .= 'combination_images['.intval($id_product_attribute).'] = new Array();';
foreach ($combinationImages AS $combinationImage)
$content .= 'combination_images['.intval($id_product_attribute).']['.$i++.'] = '.intval($combinationImage['id_image']).';';
}
return $content;
}
function displayFormAttributes($obj, $languages, $defaultLanguage)
{
global $currentIndex, $cookie;
$attributeJs = array();
$attributes = Attribute::getAttributes(intval($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(intval($cookie->id_lang));
$images = Image::getImages(intval($cookie->id_lang), $obj->id);
if ($obj->id)
{
echo '
'.$this->l('Group:').'
';
if (isset($attributes_groups))
foreach ($attributes_groups AS $k => $attribute_group)
if (isset($attributeJs[$attribute_group['id_attribute_group']]))
echo '
'.htmlentities(stripslashes($attribute_group['name']), ENT_COMPAT, 'UTF-8').' ';
echo '
'.$this->l('Attribute:').'
---
'.$this->l('Reference:').'
'.$this->l('EAN13:').'
'.$this->l('Special characters allowed:').' .-_#
'.$this->l('Supplier Reference:').'
'.$this->l('Location:').'
'.$this->l('Special characters allowed:').' .-_#
'.$this->l('Wholesale price:').'
'.($currency->format == 1 ? $currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').' ('.$this->l('overrides Wholesale price on Information tab').')
'.$this->l('Impact on price:').'
'.$this->l('None').'
'.$this->l('Increase').'
'.$this->l('Reduction').'
*
'.$this->l('of').' '.($currency->format == 1 ? $currency->sign.' ' : '').'
'.($currency->format == 2 ? ' '.$currency->sign : '').'
'.$this->l('Impact on weight:').'
'.$this->l('None').'
'.$this->l('Increase').'
'.$this->l('Reduction').'
'.$this->l('of').'
'.Configuration::get('PS_WEIGHT_UNIT').'
'.$this->l('Eco-tax:').'
'.($currency->format == 1 ? $currency->sign.' ' : '').' '.($currency->format == 2 ? ' '.$currency->sign : '').' ('.$this->l('overrides Eco-tax on Information tab').')
'.$this->l('Quantity:').'
('.$this->l('overrides Quantity on Information tab').')
* '.$this->l('included tax').'
'.$this->l('Image:').'
'.$this->l('Default:').'
'.$this->l('Make the default combination for this product').'
'.$this->l('Attributes').'
'.$this->l('Impact').'
'.$this->l('Weight').'
'.$this->l('Reference').'
'.$this->l('EAN13').'
'.$this->l('Quantity').'
'.$this->l('Actions').'
';
if ($obj->id)
{
/* Build attributes combinaisons */
$combinaisons = $obj->getAttributeCombinaisons(intval($cookie->id_lang));
$groups = array();
if (is_array($combinaisons))
{
$combinationImages = $obj->getCombinationImages(intval($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']]['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']]['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 = '';
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 '
'.stripslashes($list).'
'.($currency->format == 1 ? $currency->sign.' ' : '').$product_attribute['price'].($currency->format == 2 ? ' '.$currency->sign : '').'
'.$product_attribute['weight'].Configuration::get('PS_WEIGHT_UNIT').'
'.$product_attribute['reference'].'
'.$product_attribute['ean13'].'
'.$product_attribute['quantity'].'
';
}
echo ' '.$this->l('Delete all combinations').' ';
}
else
echo ''.$this->l('No combination yet').'. ';
}
echo '
'.$this->l('The row in blue is the default combination.').'
'.$this->l('A default combination must be designated for each product.').'
';
}
else
echo ''.$this->l('You must save this product before adding combinations').'. ';
}
function displayFormFeatures($obj)
{
global $cookie, $currentIndex;
parent::displayForm(false);
if ($obj->id)
{
$feature = Feature::getFeatures(intval($cookie->id_lang));
$ctab = '';
foreach ($feature AS $tab)
$ctab .= 'ccustom_'.$tab['id_feature'].'¤';
$ctab = rtrim($ctab, '¤');
echo '
'.$this->l('Assign features to this product').'
';
// Header
$nb_feature = Feature::nbFeatures(intval($cookie->id_lang));
echo '
'.$this->l('Features').'
'.$this->l('Value').'
'.$this->l('Customized').'
';
if (!$nb_feature)
echo ''.$this->l('No features defined').' ';
echo '
';
// Listing
if ($nb_feature)
{
echo '
';
}
else
echo ''.$this->l('You must save this product before adding features').'. ';
}
public function haveThisAccessory($accessoryId, $accessories)
{
foreach ($accessories AS $accessory)
if (intval($accessory['id_product']) == intval($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 '
'.$this->l('Pack').'
';
}
private function fillPackItems($obj)
{
global $currentIndex, $cookie;
return '
function fillPackItems()
{
$.getJSON("'.dirname($currentIndex).'/ajax.php",{ajaxProductPackItems:1,id_lang:'.intval($cookie->id_lang).',id_product:'.($obj->id ? intval($obj->id) : 0).'},
function(result) {
for (var i = 0; i < result.length; i++)
packItems[i] = new Array(result[i].value, result[i].text);
formProduct = document.layers ? document.forms.product : document.product;
formProduct.selectPackItems.length = packItems.length + 1;
for (i = 0, j = 1; i < packItems.length; i++)
{
if (formProduct.filterPack.value)
if (packItems[i][1].toLowerCase().indexOf(formProduct.filterPack.value.toLowerCase()) == -1)
continue;
formProduct.selectPackItems.options[j].value = packItems[i][0];
formProduct.selectPackItems.options[j].text = packItems[i][1];
j++;
}
if (j == 1)
{
formProduct.selectPackItems.length = 2;
formProduct.selectPackItems.options[1].value = -1;
formProduct.selectPackItems.options[1].text = \''.$this->l('No match found').'\';
formProduct.selectPackItems.options.selectedIndex = 1;
}
else
{
formProduct.selectPackItems.length = j;
formProduct.selectPackItems.options.selectedIndex = (formProduct.filterPack.value == \'\' ? 0 : 1);
}
}
);
}';
}
private function packItemJsInit()
{
return '
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(\'selectPackItems\');
var select_quantity = getE(\'quantityPackItems\');';
}
private function addPackItem()
{
return '
function addPackItem()
{
'.$this->packItemJsInit().'
if (select.value == \'0\')
return;
var cut = select.value.split(reg);
var inputCut = input.value.split(reg);
for (var i = 0; i < inputCut.length; ++i)
if (inputCut[i])
{
var inputQty = inputCut[i].split(regx);
if (inputQty[1] == cut[0])
return false;
}
for (i = 0; i < select.length; ++i)
if (select.options[i].selected == true)
select.options[i] = null;
select.selectedIndex = 0;
var nameStr = \'\';
for (i = 1; i < cut.length; ++i)
nameStr += select_quantity.value + \' x \' + cut[i];
input.value += select_quantity.value + \'x\' + cut[0] + \'-\';
name.value += nameStr + \'¤\';
div.innerHTML += nameStr + \' \';
}';
}
private function delPackItem()
{
return '
function delPackItem(id)
{
'.$this->packItemJsInit().'
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] + \' \';
}
}
}';
}
public function updatePackItems($product)
{
Pack::deleteItems($product->id);
if (Tools::getValue('ppack') AND $items = Tools::getValue('inputPackItems') AND sizeof($ids = array_unique(explode('-', $items))))
if (!Pack::addItems($product->id, $ids))
return false;
return true;
}
}
?>