Prestashop: add customized product to cart

2020-02-09 05:29发布

I'm writnig a custom controller for Prestashop. It is suposed to do a simple task: 1. Create a new cart if it wasn't created (working fine) 2. Get attribute ID from database (working fine) 3. Assign customization (one text field) 4. Add this product to cart.

My current code:

$idProduct = 1; // for me it's always one
$qty= 1; // always add one item
$text = (string)Tools::getValue('textField9'); // string of text customization
$attribute = (int)Tools::getValue('sel_combination'); // atribute combination ID

// get cart id if exists
if ($this->context->cookie->id_cart)
{
    $cart = new Cart($this->context->cookie->id_cart);
}

// create new cart if needed
if (!isset($cart) OR !$cart->id)
{
    $cart = new Cart();
    $cart->id_customer = (int)($this->context->cookie->id_customer);
    $cart->id_address_delivery = (int)  (Address::getFirstCustomerAddressId($cart->id_customer));
    $cart->id_address_invoice = $cart->id_address_delivery;
    $cart->id_lang = (int)($this->context->cookie->id_lang);
    $cart->id_currency = (int)($this->context->cookie->id_currency);
    $cart->id_carrier = 1;
    $cart->recyclable = 0;
    $cart->gift = 0;
    $cart->add();
    $this->context->cookie->id_cart = (int)($cart->id);    
    $cart->update();
}



// get product to add into cart
$productToAdd = new Product(1, true, (int)($this->context->cookie->id_lang));

// default attributes
// $default_id_product_attribute = Product::getDefaultAttribute($productToAdd->id, $minimumQuantity);

// assign real attributes
$attributes =  $attribute;
$cart->update();
// add customizatated text
$customization = $this->context->cart->addTextFieldToProduct((int)($idProduct), 9, Product::CUSTOMIZE_TEXTFIELD, $text );

$exising_customization = Db::getInstance()->executeS('SELECT id_customization FROM '._DB_PREFIX_.'customized_data ORDER BY id_customization DESC LIMIT 0,1');


$customization = $exising_customization[0]['id_customization'];



Db::getInstance()->execute('UPDATE ps_customization SET in_cart = 1, id_product_attribute = '.$attributes.' WHERE id_customization = ' .$customization);

// add product to cart
$cart->updateQty($qty, (int)($idProduct), (int)($attributes), (int)($customization), Tools::getValue('op', 'up'));
$prods = $cart->getProducts(true);
print_r ($prods[0]['id_customization']);
// update cart
$cart->update();

The cart is created and a product is added to it. The cart says, that there is one product - but it's not displayed. After reload of the above code, the cart shows 2 items with proper customization data.

From what I could find the problem lies in in the customization. The first time it is not assigned ($cart->getProducts(true); shows ['id_customization'] to be null), but the second time everything is working fine. Even the first product is fixed.

2条回答
叛逆
2楼-- · 2020-02-09 06:10

I managed to fix the problem.

  1. Proper way to create a cart:

    if (!$this->context->cart->id)
    {
        if (Context::getContext()->cookie->id_guest)
        {
            $guest = new Guest(Context::getContext()->cookie->id_guest);
            $this->context->cart->mobile_theme = $guest->mobile_theme;
        }
        $this->context->cart->add();
        if ($this->context->cart->id)
            $this->context->cookie->id_cart = (int)$this->context->cart->id;
    }
    
  2. Add customization

    $this->product = new Product(1, true, (int)($this->context->cookie->id_lang));
    
    $authorized_text_fields = array();
    
    if (!$field_ids = $this->product->getCustomizationFieldIds())
            return false;
    
    foreach ($field_ids as $field_id)
        if ($field_id['type'] == Product::CUSTOMIZE_TEXTFIELD)
            $authorized_text_fields[(int)$field_id['id_customization_field']] = 'textField'.(int)$field_id['id_customization_field'];
    
        $indexes = array_flip($authorized_text_fields);
        foreach ($_POST as $field_name => $value)
            if (in_array($field_name, $authorized_text_fields) && !empty($value))
            {
                if (!Validate::isMessage($value))
                    $this->errors[] = Tools::displayError('Invalid message');
                else
                $this->context->cart->addTextFieldToProduct($this->product->id, $indexes[$field_name], Product::CUSTOMIZE_TEXTFIELD, $value);
            }
            else if (in_array($field_name, $authorized_text_fields) && empty($value))
                $this->context->cart->deleteCustomizationToProduct((int)$this->product->id, $indexes[$field_name]);
    
  3. Get the customizations

    $texts = $this->context->cart->getProductCustomization($this->product->id, Product::CUSTOMIZE_TEXTFIELD, true);
    $text_fields = array();
    foreach ($texts as $text_field)
        $text_fields['textFields_'.$this->product->id.'_'.$text_field['index']] = str_replace('<br />', "\n", $text_field['value']);
    
查看更多
劳资没心,怎么记你
3楼-- · 2020-02-09 06:20

The most simple to validate a cart:

// Validate the object cart $this->context->cart->save(); $this->context->cookie->id_cart = (int)$this->context->cart->id;

the save() method upate the cart if exists or create a new if not. Then force the cookie to have the same id.

查看更多
登录 后发表回答