I'm using onPopulateLineItem in my plugin to dynamically set the price of products added to the cart based on user input on the front-end -

$lineItem = $event->params['lineItem'];

$size = craft()->request->getPost('size');
$colour = craft()->request->getPost('colour');
$finish = craft()->request->getPost('finish');

$options = array(
  'size' => $size,
  'colour' => $colour,
  'finish' => $finish

$lineItem->options = $options;
$lineItem->price = $dynamicPrice;

This is working fine, however, if the same product item is added to the cart but with different options (and therefor a different price) the existing line item is overwritten with the new values/price.

Is there a way I can create a new line item each time, rather than overwrite the existing one? Do I need to use a different event or create some kind of custom controller?


1 Answer 1


Commerce will by default combine line items that have the same hash value for the options (that is, the values of the items chosen options are run through md5 to get a hash - if the hash matches, the lineItems quantity is increased as the item is seen as the same item.

If you want line items with the same options to remain as separate line items, then you can simply add another unique option to the product as you add it to the cart (you don't need to display this of course).

<input type="hidden" name="options['whatevs']" value="somethingRandom">

Twig isn't actually ideal at generating random things I believe, I'd personally create a template variable in my Business Logic plugin that returns a random value, e.g. something like:

public function random(){
    return rand(1,time()); 

You can e.g. call the current timestamp in twig but there's always a chance that might not end up as random I suppose?

<input type="hidden" name="options['time']" value="{{ date().timestamp }}">

(Calling twigs own random (https://twig.sensiolabs.org/doc/2.x/functions/random.html) - doesn't seem ideal as that's inclusive so you might see the edge values returned more than you'd like).

  • Thanks, this is working and does create new line items rather than combine them. However, if I set $lineItem->price dynamically each time using the onPopulateLineItem event, it updates the price for that line item and the line items already in place linked to that product. I need the line items already in place to keep the price set on them when they were added and not inherit from the latest line item. Hopefully that makes sense.
    – Rich Mud
    Jun 1, 2017 at 9:17
  • I think you might need to chat to Luke Holder on that one. Probably means the hashing is happening for this scenario at the wrong time I'd guess. Not sure you'll be able to solve that without Luke... At least he'll have some good advice on it, I'm sure. Jun 1, 2017 at 10:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.