如何在 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_ordersps_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;
        /* ... */
    }
}

显然,OrderCartPaymentModule 的覆盖也是必要的。

PS: 希望我没有忘记什么。

你也可以试试这个模块 https://www.prestashop.com/forums/topic/589259-m%C3%B3dulo-selector-fecha-en-pedido/?p=2489523