大家好,我对这个问题有疑问,prestashop 1.6。
我在信息页面的上添加了一个自定义日期字段:
我们将其称为“ customfield”,它工作正常,我可以在数据库中填写DATE和prestashop商店。
现在,我想在组合中添加相同的字段,每个组合可以具有相同或不同的null值或空字段。
这是我对组合所做的:
<div class="form-group">
<label class="control-label col-lg-3" for="attribute_customfield">
{l s='Customfield'}
</label>
<div class="col-lg-3">
<input maxlength="12" type="date" id="attribute_customfield" name="attribute_customfield" value="" />
</div>
</div>
class Combination extends CombinationCore
{
public $customfield;
/**
* @see ObjectModel::$definition
*/
public static $definition = array(
'table' => 'product_attribute',
'primary' => 'id_product_attribute',
'fields' => array(
'id_product' => array('type' => self::TYPE_INT, 'shop' => 'both', 'validate' => 'isUnsignedId', 'required' => true),
'location' => array('type' => self::TYPE_STRING, 'validate' => 'isGenericName', 'size' => 64),
'ean13' => array('type' => self::TYPE_STRING, 'validate' => 'isEan13', 'size' => 13),
'upc' => array('type' => self::TYPE_STRING, 'validate' => 'isUpc', 'size' => 12),
'quantity' => array('type' => self::TYPE_INT, 'validate' => 'isInt', 'size' => 10),
'reference' => array('type' => self::TYPE_STRING, 'size' => 32),
'supplier_reference' => array('type' => self::TYPE_STRING, 'size' => 32),
/* Shop fields */
'wholesale_price' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice', 'size' => 27),
'price' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isNegativePrice', 'size' => 20),
'ecotax' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isPrice', 'size' => 20),
'weight' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isFloat'),
'unit_price_impact' => array('type' => self::TYPE_FLOAT, 'shop' => true, 'validate' => 'isNegativePrice', 'size' => 20),
'minimal_quantity' => array('type' => self::TYPE_INT, 'shop' => true, 'validate' => 'isUnsignedId', 'required' => true),
'default_on' => array('type' => self::TYPE_BOOL, 'allow_null' => true, 'shop' => true, 'validate' => 'isBool'),
'available_date' => array('type' => self::TYPE_DATE, 'shop' => true, 'validate' => 'isDateFormat'),
/*added*/
'customfield' => array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat'),
),
);
}
class Product extends ProductCore
{
public $second_reference;
public $customfield;
public function __construct($id_product = null, $full = false, $id_lang = null, $id_shop = null, Context $context = null)
{
self::$definition['fields']['second_reference'] = array('type' => self::TYPE_STRING, 'validate' => 'isString');
self::$definition['fields']['customfield'] = array('type' => self::TYPE_DATE, 'validate' => 'isDateFormat');
parent::__construct($id_product, $full, $id_lang, $id_shop);
}
/**
* @param int $quantity DEPRECATED
* @param string $supplier_reference DEPRECATED
*/
public function addCombinationEntity($wholesale_price, $price, $weight, $unit_impact, $ecotax, $quantity,
$id_images, $reference, $id_supplier, $ean13, $customfield, $default, $location = null, $upc = null, $minimal_quantity = 1, array $id_shop_list = array(), $available_date = null)
{
$id_product_attribute = $this->addAttribute(
$price, $weight, $unit_impact, $ecotax, $id_images,
$reference, $ean13, $customfield, $default, $location, $upc, $minimal_quantity, $id_shop_list, $available_date);
$this->addSupplierReference($id_supplier, $id_product_attribute);
$result = ObjectModel::updateMultishopTable('Combination', array(
'wholesale_price' => (float)$wholesale_price,
), 'a.id_product_attribute = '.(int)$id_product_attribute);
if (!$id_product_attribute || !$result)
return false;
return $id_product_attribute;
}
/**
* Update a product attribute
*
*/
public function updateAttribute($id_product_attribute, $wholesale_price, $price, $weight, $unit, $ecotax,
$id_images, $reference, $ean13, $customfield, $default, $location = null, $upc = null, $minimal_quantity = null, $available_date = null, $update_all_fields = true, array $id_shop_list = array())
{
$combination = new Combination($id_product_attribute);
if (!$update_all_fields)
$combination->setFieldsToUpdate(array(
'price' => !is_null($price),
'wholesale_price' => !is_null($wholesale_price),
'ecotax' => !is_null($ecotax),
'weight' => !is_null($weight),
'unit_price_impact' => !is_null($unit),
'default_on' => !is_null($default),
'minimal_quantity' => !is_null($minimal_quantity),
'available_date' => !is_null($available_date),
));
$price = str_replace(',', '.', $price);
$weight = str_replace(',', '.', $weight);
$combination->price = (float)$price;
$combination->wholesale_price = (float)$wholesale_price;
$combination->ecotax = (float)$ecotax;
$combination->weight = (float)$weight;
$combination->unit_price_impact = (float)$unit;
$combination->reference = pSQL($reference);
$combination->location = pSQL($location);
$combination->ean13 = pSQL($ean13);
$combination->customfield = pSQL($customfield);
$combination->upc = pSQL($upc);
$combination->default_on = (int)$default;
$combination->minimal_quantity = (int)$minimal_quantity;
$combination->available_date = $available_date ? pSQL($available_date) : '0000-00-00';
if (count($id_shop_list))
$combination->id_shop_list = $id_shop_list;
$combination->save();
if (is_array($id_images) && count($id_images))
$combination->setImages($id_images);
$id_default_attribute = (int)Product::updateDefaultAttribute($this->id);
if ($id_default_attribute)
$this->cache_default_attribute = $id_default_attribute;
// Sync stock Reference, EAN13 and UPC for this attribute
if (Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT') && StockAvailable::dependsOnStock($this->id, Context::getContext()->shop->id))
Db::getInstance()->update('stock', array(
'reference' => pSQL($reference),
'ean13' => pSQL($ean13),
'customfield' => pSQL($customfield),
'upc' => pSQL($upc),
), 'id_product = '.$this->id.' AND id_product_attribute = '.(int)$id_product_attribute);
Hook::exec('actionProductAttributeUpdate', array('id_product_attribute' => (int)$id_product_attribute));
Tools::clearColorListCache($this->id);
return true;
}
/**
* Add a product attribute
* @since 1.5.0.1
*
* @param float $price Additional price
* @param float $weight Additional weight
* @param float $ecotax Additional ecotax
* @param int $id_images Image ids
* @param string $reference Reference
* @param string $location Location
* @param string $ean13 Ean-13 barcode
* @param bool $default Is default attribute for product
* @param int $minimal_quantity Minimal quantity to add to cart
* @return mixed $id_product_attribute or false
*/
public function addAttribute($price, $weight, $unit_impact, $ecotax, $id_images, $reference, $ean13, $customfield,
$default, $location = null, $upc = null, $minimal_quantity = 1, array $id_shop_list = array(), $available_date = null)
{
if (!$this->id)
return;
$price = str_replace(',', '.', $price);
$weight = str_replace(',', '.', $weight);
$combination = new Combination();
$combination->id_product = (int)$this->id;
$combination->price = (float)$price;
$combination->ecotax = (float)$ecotax;
$combination->quantity = 0;
$combination->weight = (float)$weight;
$combination->unit_price_impact = (float)$unit_impact;
$combination->reference = pSQL($reference);
$combination->location = pSQL($location);
$combination->ean13 = pSQL($ean13);
$combination->customfield = pSQL($customfield);
$combination->upc = pSQL($upc);
$combination->default_on = (int)$default;
$combination->minimal_quantity = (int)$minimal_quantity;
$combination->available_date = $available_date;
if (count($id_shop_list))
$combination->id_shop_list = array_unique($id_shop_list);
$combination->add();
if (!$combination->id)
return false;
$total_quantity = (int)Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
SELECT SUM(quantity) as quantity
FROM '._DB_PREFIX_.'stock_available
WHERE id_product = '.(int)$this->id.'
AND id_product_attribute <> 0 '
);
if (!$total_quantity)
Db::getInstance()->update('stock_available', array('quantity' => 0), '`id_product` = '.$this->id);
$id_default_attribute = Product::updateDefaultAttribute($this->id);
if ($id_default_attribute)
{
$this->cache_default_attribute = $id_default_attribute;
if (!$combination->available_date)
$this->setAvailableDate();
}
if (!empty($id_images))
$combination->setImages($id_images);
Tools::clearColorListCache($this->id);
if (Configuration::get('PS_DEFAULT_WAREHOUSE_NEW_PRODUCT') != 0 && Configuration::get('PS_ADVANCED_STOCK_MANAGEMENT'))
{
$warehouse_location_entity = new WarehouseProductLocation();
$warehouse_location_entity->id_product = $this->id;
$warehouse_location_entity->id_product_attribute = (int)$combination->id;
$warehouse_location_entity->id_warehouse = Configuration::get('PS_DEFAULT_WAREHOUSE_NEW_PRODUCT');
$warehouse_location_entity->location = pSQL('');
$warehouse_location_entity->save();
}
return (int)$combination->id;
}
/**
* Get all available attribute groups
*
* @param int $id_lang Language id
* @return array Attribute groups
*/
public function getAttributesGroups($id_lang)
{
if (!Combination::isFeatureActive())
return array();
$sql = 'SELECT ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, agl.`public_name` AS public_group_name,
a.`id_attribute`, al.`name` AS attribute_name, a.`color` AS attribute_color, product_attribute_shop.`id_product_attribute`,
IFNULL(stock.quantity, 0) as quantity, product_attribute_shop.`price`, product_attribute_shop.`ecotax`, product_attribute_shop.`weight`,
product_attribute_shop.`default_on`, pa.`reference`, pa.`customfield`, product_attribute_shop.`unit_price_impact`,
product_attribute_shop.`minimal_quantity`, product_attribute_shop.`available_date`, ag.`group_type`
FROM `'._DB_PREFIX_.'product_attribute` pa
'.Shop::addSqlAssociation('product_attribute', 'pa').'
'.Product::sqlStock('pa', 'pa').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON (pac.`id_product_attribute` = pa.`id_product_attribute`)
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON (a.`id_attribute` = pac.`id_attribute`)
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON (ag.`id_attribute_group` = a.`id_attribute_group`)
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute`)
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group`)
'.Shop::addSqlAssociation('attribute', 'a').'
WHERE pa.`id_product` = '.(int)$this->id.'
AND al.`id_lang` = '.(int)$id_lang.'
AND agl.`id_lang` = '.(int)$id_lang.'
GROUP BY id_attribute_group, id_product_attribute
ORDER BY ag.`position` ASC, a.`position` ASC, agl.`name` ASC';
return Db::getInstance()->executeS($sql);
}
/**
* Get product attribute combination by id_product_attribute
* @return array Product attribute combination by id_product_attribute
*/
public function getAttributeCombinationsById($id_product_attribute, $id_lang)
{
if (!Combination::isFeatureActive())
return array();
$sql = 'SELECT pa.*, product_attribute_shop.*, ag.`id_attribute_group`, ag.`is_color_group`, agl.`name` AS group_name, al.`name` AS attribute_name,
a.`id_attribute`
FROM `'._DB_PREFIX_.'product_attribute` pa
'.Shop::addSqlAssociation('product_attribute', 'pa').'
LEFT JOIN `'._DB_PREFIX_.'product_attribute_combination` pac ON pac.`id_product_attribute` = pa.`id_product_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute` a ON a.`id_attribute` = pac.`id_attribute`
LEFT JOIN `'._DB_PREFIX_.'attribute_group` ag ON ag.`id_attribute_group` = a.`id_attribute_group`
LEFT JOIN `'._DB_PREFIX_.'attribute_lang` al ON (a.`id_attribute` = al.`id_attribute` AND al.`id_lang` = '.(int)$id_lang.')
LEFT JOIN `'._DB_PREFIX_.'attribute_group_lang` agl ON (ag.`id_attribute_group` = agl.`id_attribute_group` AND agl.`id_lang` = '.(int)$id_lang.')
WHERE pa.`id_product` = '.(int)$this->id.'
AND pa.`id_product_attribute` = '.(int)$id_product_attribute.'
GROUP BY pa.`id_product_attribute`, ag.`id_attribute_group`
ORDER BY pa.`id_product_attribute`';
$res = Db::getInstance()->executeS($sql);
//Get quantity of each variations
foreach ($res as $key => $row)
{
$cache_key = $row['id_product'].'_'.$row['id_product_attribute'].'_quantity';
if (!Cache::isStored($cache_key))
{
$result = StockAvailable::getQuantityAvailableByProduct($row['id_product'], $row['id_product_attribute']);
Cache::store(
$cache_key,
$result
);
$res[$key]['quantity'] = $result;
}
else
$res[$key]['quantity'] = Cache::retrieve($cache_key);
}
return $res;
}
}
class ProductController extends ProductControllerCore
{
/**
* Assign template vars related to attribute groups and colors
*/
protected function assignAttributesGroups()
{
$colors = array();
$groups = array();
// @todo (RM) should only get groups and not all declination ?
$attributes_groups = $this->product->getAttributesGroups($this->context->language->id);
if (is_array($attributes_groups) && $attributes_groups)
{
$combination_images = $this->product->getCombinationImages($this->context->language->id);
$combination_prices_set = array();
foreach ($attributes_groups as $k => $row)
{
// Color management
if (isset($row['is_color_group']) && $row['is_color_group'] && (isset($row['attribute_color']) && $row['attribute_color']) || (file_exists(_PS_COL_IMG_DIR_.$row['id_attribute'].'.jpg')))
{
$colors[$row['id_attribute']]['value'] = $row['attribute_color'];
$colors[$row['id_attribute']]['name'] = $row['attribute_name'];
if (!isset($colors[$row['id_attribute']]['attributes_quantity']))
$colors[$row['id_attribute']]['attributes_quantity'] = 0;
$colors[$row['id_attribute']]['attributes_quantity'] += (int)$row['quantity'];
}
...
}
}
<?php
class AdminProductsController extends AdminProductsControllerCore
{
public function processProductAttribute()
{
// Don't process if the combination fields have not been submitted
if (!Combination::isFeatureActive() || !Tools::getValue('attribute_combination_list'))
return;
if (Validate::isLoadedObject($product = $this->object))
{
if ($this->isProductFieldUpdated('attribute_price') && (!Tools::getIsset('attribute_price') || Tools::getIsset('attribute_price') == null))
$this->errors[] = Tools::displayError('The price attribute is required.');
if (!Tools::getIsset('attribute_combination_list') || Tools::isEmpty(Tools::getValue('attribute_combination_list')))
$this->errors[] = Tools::displayError('You must add at least one attribute.');
$array_checks = array(
'reference' => 'isReference',
'supplier_reference' => 'isReference',
'location' => 'isReference',
'ean13' => 'isEan13',
'upc' => 'isUpc',
'wholesale_price' => 'isPrice',
'price' => 'isPrice',
'ecotax' => 'isPrice',
'quantity' => 'isInt',
'weight' => 'isUnsignedFloat',
'unit_price_impact' => 'isPrice',
'default_on' => 'isBool',
'minimal_quantity' => 'isUnsignedInt',
'available_date' => 'isDateFormat'
);
foreach ($array_checks as $property => $check)
if (Tools::getValue('attribute_'.$property) !== false && !call_user_func(array('Validate', $check), Tools::getValue('attribute_'.$property)))
...
$this->isProductFieldUpdated('attribute_ecotax') ? Tools::getValue('attribute_ecotax') : null,
Tools::getValue('id_image_attr'),
Tools::getValue('attribute_reference'),
Tools::getValue('attribute_ean13'),
Tools::getValue('customfield'),
$this->isProductFieldUpdated('attribute_default') ? Tools::getValue('attribute_default') : null,
Tools::getValue('attribute_location'),
Tools::getValue('attribute_upc'),
$this->isProductFieldUpdated('attribute_minimal_quantity') ? Tools::getValue('attribute_minimal_quantity') : null,
$this->isProductFieldUpdated('available_date_attribute') ? Tools::getValue('available_date_attribute') : null, false);
StockAvailable::setProductDependsOnStock((int)$product->id, $product->depends_on_stock, null, (int)$id_product_attribute);
StockAvailable::setProductOutOfStock((int)$product->id, $product->out_of_stock, null, (int)$id_product_attribute);
}
}
else
$this->errors[] = Tools::displayError('You do not have permission to add this.');
}
// Add new
else
{
if ($this->tabAccess['add'] === '1')
{
if ($product->productAttributeExists(Tools::getValue('attribute_combination_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'),
0,
Tools::getValue('id_image_attr'),
Tools::getValue('attribute_reference'),
null,
Tools::getValue('attribute_ean13'),
Tools::getValue('attribute_default'),
Tools::getValue('attribute_location'),
Tools::getValue('customfield'),
...
}
}
}
/**
* @param Product $product
* @throws Exception
* @throws SmartyException
*/
public function initFormInformations($product)
{
if (!$this->default_form_language)
$this->getLanguages();
$data = $this->createTemplate($this->tpl_form);
$currency = $this->context->currency;
$data->assign(array(
'languages' => $this->_languages,
'default_form_language' => $this->default_form_language,
'currency' => $currency
));
$this->object = $product;
//$this->display = 'edit';
$data->assign('product_name_redirected', Product::getProductName((int)$product->id_product_redirected, null, (int)$this->context->language->id));
/*
* Form for adding a virtual product like software, mp3, etc...
*/
$product_download = new ProductDownload();
if ($id_product_download = $product_download->getIdFromIdProduct($this->getFieldValue($product, 'id')))
$product_download = new ProductDownload($id_product_download);
$product->{'productDownload'} = $product_download;
$product_props = array();
// global informations
array_push($product_props, 'reference', 'ean13', 'customfield', 'upc',
'available_for_order', 'show_price', 'online_only',
'id_manufacturer'
);
// specific / detailled information
array_push($product_props,
// physical product
'width', 'height', 'weight', 'active',
// virtual product
'is_virtual', 'cache_default_attribute',
// customization
'uploadable_files', 'text_fields'
);
// prices
array_push($product_props,
'price', 'wholesale_price', 'id_tax_rules_group', 'unit_price_ratio', 'on_sale',
'unity', 'minimum_quantity', 'additional_shipping_cost',
'available_now', 'available_later', 'available_date'
);
...
}
/**
* @param Product $product
* @param Currency|array|int $currency
* @return string
*/
public function renderListAttributes($product, $currency)
{
$this->bulk_actions = array('delete' => array('text' => $this->l('Delete selected'), 'confirm' => $this->l('Delete selected items?')));
$this->addRowAction('edit');
$this->addRowAction('default');
$this->addRowAction('delete');
$default_class = 'highlighted';
$this->fields_list = array(
'attributes' => array('title' => $this->l('Attribute - value pair'), 'align' => 'left'),
'price' => array('title' => $this->l('Impact on price'), 'type' => 'price', 'align' => 'left'),
'weight' => array('title' => $this->l('Impact on weight'), 'align' => 'left'),
'reference' => array('title' => $this->l('Reference'), 'align' => 'left'),
'ean13' => array('title' => $this->l('EAN-13'), 'align' => 'left'),
'upc' => array('title' => $this->l('UPC'), 'align' => 'left')
);
if ($product->id)
{
/* Build attributes combinations */
$combinations = $product->getAttributeCombinations($this->context->language->id);
$groups = array();
$comb_array = array();
if (is_array($combinations))
{
$combination_images = $product->getCombinationImages($this->context->language->id);
foreach ($combinations as $k => $combination)
{
$price_to_convert = Tools::convertPrice($combination['price'], $currency);
$price = Tools::displayPrice($price_to_convert, $currency);
$comb_array[$combination['id_product_attribute']]['id_product_attribute'] = $combination['id_product_attribute'];
$comb_array[$combination['id_product_attribute']]['attributes'][] = array($combination['group_name'], $combination['attribute_name'], $combination['id_attribute']);
$comb_array[$combination['id_product_attribute']]['wholesale_price'] = $combination['wholesale_price'];
$comb_array[$combination['id_product_attribute']]['price'] = $price;
$comb_array[$combination['id_product_attribute']]['weight'] = $combination['weight'].Configuration::get('PS_WEIGHT_UNIT');
$comb_array[$combination['id_product_attribute']]['unit_impact'] = $combination['unit_price_impact'];
$comb_array[$combination['id_product_attribute']]['reference'] = $combination['reference'];
$comb_array[$combination['id_product_attribute']]['ean13'] = $combination['ean13'];
$comb_array[$combination['id_product_attribute']]['customfield'] = $combination['customfield'];
$comb_array[$combination['id_product_attribute']]['upc'] = $combination['upc'];
$comb_array[$combination['id_product_attribute']]
...
}
}
function editProductAttribute (url, parent){
$.ajax({...
success: function(data) {
// color the selected line
parent.siblings().removeClass('selected-line');
parent.addClass('selected-line');
$('#add_new_combination').show();
$('#attribute_quantity').show();
$('#product_att_list').html('');
self.removeButtonCombination('update');
scroll_if_anchor('#add_new_combination');
var wholesale_price = Math.abs(data[0]['wholesale_price']);
var price = data[0]['price'];
var weight = data[0]['weight'];
var unit_impact = data[0]['unit_price_impact'];
var reference = data[0]['reference'];
var ean = data[0]['ean13'];
//MIO
var customfield = data[0]['customfield'];
.....
.....
self.fillCombination(
wholesale_price,
price,
weight,
unit_impact,
reference,
ean,
customfield,
...
);
/**AND LATER**/
this.fillCombination = function(wholesale_price, price_impact, weight_impact, unit_impact, reference,
ean, customfield, quantity, image, old_attr, id_product_attribute, default_attribute, eco_tax, upc, minimal_quantity, available_date)
{
var link = '';
self.init_elems();
$('#stock_mvt_attribute').show();
$('#initial_stock_attribute').hide();
...
getE('attribute_customfield').value = customfield;
这些都是我覆盖和修改的所有文件
当然这是行不通的,它不会将信息正确地保存到数据库中,有时,如果设置了信息中的一个,它会复制该信息。
我做错了什么?而我应该怎么做