如何在 Prestashop 的 table 中的自定义字段中插入值?
How do I insert a value in a custom field in a table in Prestashop?
我在 "ps_orders" table 中添加了一个名为 "deldate" 的自定义字段,并在 "OPC" 结帐页面上添加了一个文本框。现在,当我点击订单确认按钮时,文本框中的值应该保存在 "ps_orders" table 的 "deldate" 字段中。
文本框显示完美,但我需要在哪些文件中进行更改以将文本框值保存在 table 中?
(主题是默认主题。)
class/order/order.php
class OrderCore extends ObjectModel
{
public $deldate;
}
和
public static $definition = array(
'fields' => array(
'deldate'=> array('type' => self::TYPE_STRING),
),
)
购物-cart.tpl
<div class="box">
<div class="required form-group">
<form method="post">
<label for="Fecha de entrega deseada">{l s='Desired delivery date' mod='deldate'}</label>
<input type="text" id="deldate" name="deldate" class="form-control" value="hello" />
</form>
</div>
</div>
在 class 订单
的覆盖中试试这个
class Order extends OrderCore
{
public function __construct($id = null, $id_lang = null)
{
parent::__construct($id, $id_lang);
self::$definition['fields']['deldate'] = array('type' => self::TYPE_STRING);
Cache::clean('objectmodel_def_Order');
}
}
Cache::clean 是必需的,因为 getDefinition 尝试从缓存中检索,并且设置缓存时没有覆盖 parent::__construct
然后我尝试创建一个新的空订单并获取定义字段并显示在那里,因此它应该保存到 mysql
$order = new Order();
var_dump(ObjectModel::getDefinition($order));exit;
好的,我想出了解决办法...
如果您想在结帐过程中向订单添加一些信息,您必须将这些信息保存在其他地方,如果您看到购物车 table 与订单 table 非常相似。
为什么你必须这样做?因为在客户确认之前您没有订单,所以在结帐未完成之前无法将信息保存在订单中table。
所以,首先,在数据库中创建字段,在这种情况下,您必须在 ps_orders
和 ps_cart
中添加。
(在你的情况下,我建议使用 DATETIME 字段)
其次,覆盖订单class:
class Order extends OrderCore
{
public function __construct($id = null, $id_lang = null)
{
self::$definition['fields']['deldate'] = array('type' => self::TYPE_DATE);
parent::__construct($id, $id_lang);
}
}
和 Cart
class:
class Cart extends CartCore
{
public function __construct($id = null, $id_lang = null)
{
self::$definition['fields']['deldate'] = array('type' => self::TYPE_DATE);
parent::__construct($id, $id_lang);
}
}
现在我们必须在结帐过程中保存该字段,所以我们覆盖 OrderController
:
class OrderController extends OrderControllerCore
{
public function processAddress()
{
parent::processAddress();
// Here we begin our story
if(Tools::getIsset('deldate')) // Check if the field isn't empty
{
$deldate = Tools::getValue('deldate');
// Here you must parse and check data validity (I leave to you the code)
/* ... */
// Assign the data to context cart
$this->context->cart->deldate = $deldate;
// Save information
$this->context->cart->update();
}
}
}
现在您必须 'transport' 从购物车到订单的这些信息,这将通过 PaymentModule
class,特别是 validateOrder
方法完成。
所以,另一个覆盖:
class PaymentModule extends PaymentModuleCore
{
public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, Shop $shop = null)
{
$result = parent::validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method, $message, $extra_vars, $currency_special, $dont_touch_amount, $secure_key, $shop);
if($result)
{
$oldcart = new Cart($id_cart);
$neworder = new Order($this->currentOrder);
$neworder->deldate = $oldcart->deldate;
$neworder->update();
return true; // important
}
else
{
return $result;
}
}
}
完成所有这些后,您就可以保存 deldate
字段。但是,我绝对不建议使用这种方法,它使用模块和钩子更加安全和简单......但这是另一回事:)
这仅适用于五步结帐。
对于接下来的代码行,上帝保佑我...
如果你想使用 OPC,你必须用 JS 弄脏你的手并覆盖 OrderOpcController
。
从JS开始,在启用主题的js文件夹中编辑order-opc.js
,找到bindInputs
函数并添加这行代码:
function bindInputs()
{
/* ... */
$('#deldate').on('change', function(e){
updateDelDateInput(); // custom function to update deldate
});
}
然后将您的自定义函数附加到文件中:
function updateDelDateInput()
{
$.ajax({
type: 'POST',
headers: { "cache-control": "no-cache" },
url: orderOpcUrl + '?rand=' + new Date().getTime(),
async: false,
cache: false,
dataType : "json",
data: 'ajax=true&method=updateDelDate&deldate=' + encodeURIComponent($('#deldate').val()) + '&token=' + static_token ,
success: function(jsonData)
{
if (jsonData.hasError)
{
var errors = '';
for(var error in jsonData.errors)
//IE6 bug fix
if(error !== 'indexOf')
errors += $('<div />').html(jsonData.errors[error]).text() + "\n";
alert(errors);
}
// Here you can add code to display the correct updating of field
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if (textStatus !== 'abort')
alert("TECHNICAL ERROR: unable to save message \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus);
}
});
}
然后覆盖OrderOpcController
,复制所有init
方法并更改代码行如下:
class OrderOpcController extends OrderOpcControllerCore
{
public function init()
{
// parent::init(); // comment or delete this line
FrontController::init(); // Very important!
// Then in this switch `switch (Tools::getValue('method'))` add your case
/* ... */
case 'updateDelDate':
if(Tools::isSubmit('deldate'))
{
$deldate = urldecode(Tools::getValue('deldate'));
// Here you must parse and check data validity (I leave to you the code)
/* ... */
// Assign the data to context cart
$this->context->cart->deldate = $deldate;
// Save information
$this->context->cart->update();
$this->ajaxDie(true);
}
break;
/* ... */
}
}
显然,Order
、Cart
和 PaymentModule
的覆盖也是必要的。
PS: 希望我没有忘记什么。
你也可以试试这个模块
https://www.prestashop.com/forums/topic/589259-m%C3%B3dulo-selector-fecha-en-pedido/?p=2489523
我在 "ps_orders" table 中添加了一个名为 "deldate" 的自定义字段,并在 "OPC" 结帐页面上添加了一个文本框。现在,当我点击订单确认按钮时,文本框中的值应该保存在 "ps_orders" table 的 "deldate" 字段中。 文本框显示完美,但我需要在哪些文件中进行更改以将文本框值保存在 table 中? (主题是默认主题。)
class/order/order.php
class OrderCore extends ObjectModel
{
public $deldate;
}
和
public static $definition = array(
'fields' => array(
'deldate'=> array('type' => self::TYPE_STRING),
),
)
购物-cart.tpl
<div class="box">
<div class="required form-group">
<form method="post">
<label for="Fecha de entrega deseada">{l s='Desired delivery date' mod='deldate'}</label>
<input type="text" id="deldate" name="deldate" class="form-control" value="hello" />
</form>
</div>
</div>
在 class 订单
的覆盖中试试这个class Order extends OrderCore
{
public function __construct($id = null, $id_lang = null)
{
parent::__construct($id, $id_lang);
self::$definition['fields']['deldate'] = array('type' => self::TYPE_STRING);
Cache::clean('objectmodel_def_Order');
}
}
Cache::clean 是必需的,因为 getDefinition 尝试从缓存中检索,并且设置缓存时没有覆盖 parent::__construct
然后我尝试创建一个新的空订单并获取定义字段并显示在那里,因此它应该保存到 mysql
$order = new Order();
var_dump(ObjectModel::getDefinition($order));exit;
好的,我想出了解决办法... 如果您想在结帐过程中向订单添加一些信息,您必须将这些信息保存在其他地方,如果您看到购物车 table 与订单 table 非常相似。 为什么你必须这样做?因为在客户确认之前您没有订单,所以在结帐未完成之前无法将信息保存在订单中table。
所以,首先,在数据库中创建字段,在这种情况下,您必须在 ps_orders
和 ps_cart
中添加。
(在你的情况下,我建议使用 DATETIME 字段)
其次,覆盖订单class:
class Order extends OrderCore
{
public function __construct($id = null, $id_lang = null)
{
self::$definition['fields']['deldate'] = array('type' => self::TYPE_DATE);
parent::__construct($id, $id_lang);
}
}
和 Cart
class:
class Cart extends CartCore
{
public function __construct($id = null, $id_lang = null)
{
self::$definition['fields']['deldate'] = array('type' => self::TYPE_DATE);
parent::__construct($id, $id_lang);
}
}
现在我们必须在结帐过程中保存该字段,所以我们覆盖 OrderController
:
class OrderController extends OrderControllerCore
{
public function processAddress()
{
parent::processAddress();
// Here we begin our story
if(Tools::getIsset('deldate')) // Check if the field isn't empty
{
$deldate = Tools::getValue('deldate');
// Here you must parse and check data validity (I leave to you the code)
/* ... */
// Assign the data to context cart
$this->context->cart->deldate = $deldate;
// Save information
$this->context->cart->update();
}
}
}
现在您必须 'transport' 从购物车到订单的这些信息,这将通过 PaymentModule
class,特别是 validateOrder
方法完成。
所以,另一个覆盖:
class PaymentModule extends PaymentModuleCore
{
public function validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method = 'Unknown', $message = null, $extra_vars = array(), $currency_special = null, $dont_touch_amount = false, $secure_key = false, Shop $shop = null)
{
$result = parent::validateOrder($id_cart, $id_order_state, $amount_paid, $payment_method, $message, $extra_vars, $currency_special, $dont_touch_amount, $secure_key, $shop);
if($result)
{
$oldcart = new Cart($id_cart);
$neworder = new Order($this->currentOrder);
$neworder->deldate = $oldcart->deldate;
$neworder->update();
return true; // important
}
else
{
return $result;
}
}
}
完成所有这些后,您就可以保存 deldate
字段。但是,我绝对不建议使用这种方法,它使用模块和钩子更加安全和简单......但这是另一回事:)
这仅适用于五步结帐。
对于接下来的代码行,上帝保佑我...
如果你想使用 OPC,你必须用 JS 弄脏你的手并覆盖 OrderOpcController
。
从JS开始,在启用主题的js文件夹中编辑order-opc.js
,找到bindInputs
函数并添加这行代码:
function bindInputs()
{
/* ... */
$('#deldate').on('change', function(e){
updateDelDateInput(); // custom function to update deldate
});
}
然后将您的自定义函数附加到文件中:
function updateDelDateInput()
{
$.ajax({
type: 'POST',
headers: { "cache-control": "no-cache" },
url: orderOpcUrl + '?rand=' + new Date().getTime(),
async: false,
cache: false,
dataType : "json",
data: 'ajax=true&method=updateDelDate&deldate=' + encodeURIComponent($('#deldate').val()) + '&token=' + static_token ,
success: function(jsonData)
{
if (jsonData.hasError)
{
var errors = '';
for(var error in jsonData.errors)
//IE6 bug fix
if(error !== 'indexOf')
errors += $('<div />').html(jsonData.errors[error]).text() + "\n";
alert(errors);
}
// Here you can add code to display the correct updating of field
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
if (textStatus !== 'abort')
alert("TECHNICAL ERROR: unable to save message \n\nDetails:\nError thrown: " + XMLHttpRequest + "\n" + 'Text status: ' + textStatus);
}
});
}
然后覆盖OrderOpcController
,复制所有init
方法并更改代码行如下:
class OrderOpcController extends OrderOpcControllerCore
{
public function init()
{
// parent::init(); // comment or delete this line
FrontController::init(); // Very important!
// Then in this switch `switch (Tools::getValue('method'))` add your case
/* ... */
case 'updateDelDate':
if(Tools::isSubmit('deldate'))
{
$deldate = urldecode(Tools::getValue('deldate'));
// Here you must parse and check data validity (I leave to you the code)
/* ... */
// Assign the data to context cart
$this->context->cart->deldate = $deldate;
// Save information
$this->context->cart->update();
$this->ajaxDie(true);
}
break;
/* ... */
}
}
显然,Order
、Cart
和 PaymentModule
的覆盖也是必要的。
PS: 希望我没有忘记什么。
你也可以试试这个模块 https://www.prestashop.com/forums/topic/589259-m%C3%B3dulo-selector-fecha-en-pedido/?p=2489523