shopwareshopware6shopware6-app

How can I set lineItem data payload in shopware6 using html inputs


i'm using some inputs to create a cart line item:

<input type="hidden" name="lineItems[{{ id }}][id]" value="{{ id }}">
<input type="hidden" name="lineItems[{{ id }}][type]" value="product">
<input type="hidden" name="lineItems[{{ id }}][quantity]" value="1">

how can I set the payload to this to use with getPayload() or getPayloadValue() in cart collector/processor because using

<input type="hidden" name="lineItems[{{ id }}][payload][key]" value="value">

or

<input type="hidden" name="lineItems[{{ id }}][payloadData]" value="value">

does not work


Solution

  • The payload of line items is not fed by request parameters by default.

    One possible approach would be to decorate the CartItemAddRoute and inject RequestStack to set the payload from the request parameters. You'll need to create a plugin to do so.

    Service definition:

    <service id="My\Plugin\Decorator\CartItemAddRouteDecorator" decorates="Shopware\Core\Checkout\Cart\SalesChannel\CartItemAddRoute">
        <argument type="service" id="My\Plugin\Decorator\CartItemAddRouteDecorator.inner"/>
        <argument type="service" id="request_stack"/>
    </service>
    

    Decorator:

    class CartItemAddRouteDecorator extends AbstractCartItemAddRoute
    {
        private AbstractCartItemAddRoute $decorated;
    
        private RequestStack $requestStack;
    
        public function __construct(
            AbstractCartItemAddRoute $decorated,
            RequestStack $requestStack
        ) {
            $this->decorated = $decorated;
            $this->requestStack = $requestStack;
        }
    
        public function getDecorated(): AbstractCartItemAddRoute
        {
            return $this->decorated;
        }
    
        /**
         * @param array<LineItem>|null $items
         */
        public function add(Request $request, Cart $cart, SalesChannelContext $context, ?array $items): CartResponse
        {
            $params = $this->requestStack->getCurrentRequest()->request->all();
    
            if ($items) {
                foreach ($items as $item) {
                    if (empty($params['lineItems'][$item->getReferencedId()]['payload']['myKey'])) {
                        continue;
                    }
    
                    $item->setPayloadValue(
                        'myKey',
                        $params['lineItems'][$item->getReferencedId()]['payload']['myKey']
                    );
                }
            }
    
            return $this->getDecorated()->add($request, $cart, $context, $items);
        }
    }
    

    Template:

    <input type="text" name="lineItems[{{ product.id }}][payload][myKey]" />