Search code examples
javascriptphpajaxprestashopcart

Add new variable to Prestashop Cart object


In Cart (I use 5 step cart) I've added radiobox "stock_action" and I need to send this value to the Cart object because based on the value I would like to add some extra costs to order.

In Cart Override I've added $stock_action variable:

public $stock_action;

    /**
     * @see ObjectModel::$definition
     */
    public static $definition = array(
        'table' => 'cart',
        'primary' => 'id_cart',
        'fields' => array(
            'id_shop_group' =>            array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_shop' =>                array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_address_delivery' =>    array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_address_invoice' =>    array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_carrier' =>            array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_currency' =>            array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
            'id_customer' =>            array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_guest' =>                array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'stock_action' =>            array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId'),
            'id_lang' =>                array('type' => self::TYPE_INT, 'validate' => 'isUnsignedId', 'required' => true),
            'recyclable' =>            array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
            'gift' =>                    array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
            'gift_message' =>            array('type' => self::TYPE_STRING, 'validate' => 'isMessage'),
            'mobile_theme' =>            array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
            'delivery_option' =>        array('type' => self::TYPE_STRING),
            'secure_key' =>            array('type' => self::TYPE_STRING, 'size' => 32),
            'allow_seperated_package' =>array('type' => self::TYPE_BOOL, 'validate' => 'isBool'),
            'date_add' =>                array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
            'date_upd' =>                array('type' => self::TYPE_DATE, 'validate' => 'isDate'),
        ),
    );

But the value of the stock_action radio isn't sending after clicking the button to the next step in Cart.

Then I've tried to send that value using AJAX but I'm not sure how to send it correctly and catch it on the other side to assign to a Cart object. I've tried various combination of other functions in cart-summary.js and I came up with something like this:

function setStockAction() {
  var val = $('input[name=stock_action]:checked').val();
  $.ajax({
    type: 'POST',
    headers: {'cache-control': 'no-cache'},
    url: baseUri + '?rand=' + new Date().getTime(),
    async: true,
    cache: false,
    dataType: 'json',
    data: 'controller=cart'
    + '&ajax=true'
    + '&stock_action=' + val
    + '&token=' + static_token
    + '&allow_refresh=1',
    success: function(jsonData) {
      alert('ok!');
    }
  });
}

Am I on the right track or is there an easier way to do it in Prestashop? Thank you.


Solution

  • You need to add 'stock_action' field to cart table in your DB. And then this property will be available in your cart class instance as well as other properties. If you don't you'll get an error in all cart-related events Unknown column 'stock_action' in 'field list', to see it just turn on Dev mode in config/defines.inc.php set define('_PS_MODE_DEV_', false); to true.

    UPD: To make your AJAX works follow next steps(in addition to previous) 1. Override/modify controllers/front/OrderController.php method initContent() and add a next code
    if (Tools::isSubmit('ajax') && Tools::getValue('method') == 'updateStockAction') { $this->context->cart->stock_action = (int)Tools::getValue('stock_action'); $this->context->cart->save(); }
    just after
    if (Tools::isSubmit('ajax') && Tools::getValue('method') == 'updateExtraCarrier') { .... } block
    2. Go to your theme js folder and add to global.js your AJAX code

    $(document).on('change', 'input[name="stock_action"]', function() {
        var val = $('input[name=stock_action]:checked').val();
        $.ajax({
            type: 'POST',
            headers: {'cache-control': 'no-cache'},
            url: baseUri + '?rand=' + new Date().getTime(),
            async: true,
            cache: false,
            dataType: 'json',
            data: 'controller=order'
            + '&ajax=true'
            + '&stock_action=' + val
            + '&method=updateStockAction'
            + '&token=' + static_token
            + '&allow_refresh=1',
            success: function(jsonData) {
                alert('ok!');
            }
        });
    });
    

    3. Go to your theme template file shopping-cart.tpl and add somwhere your radio input

    <input type="radio" name="stock_action" value="1" />
    <input type="radio" name="stock_action" value="0" />
    

    I checked it out and it works! On all the next pages you will have the correct value of stock_action and it will be relevant until your cart exists or you change it to different