Working on a client's site this morning because they noticed something odd on their site:


The website runs on the PrestaShop ecommerce platform. This is a newly built site on the latest version – 1.7 – with the content imported from the original site built on PS 1.6. The "Product Samples" module was added to it, and it all went as smoothly as expected (I've been fixing things on this new site since December).

First thing I checked was the module settings. I couldn't find an obvious option anywhere to change the text, so took a look at the code.

PrestaShop uses the PHP backed Smarty template language. It's been around for ever and generally works quite well if you're aware of some of its nuances. I was expecting the worst, but I wasn't expecting this:

Roughly translated into pseudocode/valid Python:

if sample_price == 0:
  print(f"Free Sample {sample_price}")
else:  # If there is a sample price.
  print("Add Sample")

Sure, by all means, print "Free Sample" when the price of the sample is 0. That makes sense. So why is it:

  1. Only supposed to be printing the price when it's equal to 0, and
  2. actually printing "FREE SAMPLE £0.50"?

Two things are happening here. To cover the former I think that somewhere along the lines a developer has mixed up where the {productsample->price... line is supposed to go and put it in the wrong place. Surely it should be after the <br> in the else part.

For the latter it got more interesting. This might have worked differently in PrestaShop 1.6, but in 1.7 (or this version of the module) $productsample->price isn't a number.

What?! Yeah, that got me too. Naively I expected that it was perhaps converting 0.50 to an integer and rounding down, since it was comparing to 0 rather than 0.0 – an integer rather than a float. Maybe it would work if I changed it to 0.0 forcing it to compare the numbers properly. Nope.

A colleague mentioned something when I pointed this out. It's not comparing 0.50 to anything. It's comparing "£0.50" to 0. There's no £ in the code above. $productsample->price is a string, not a number. This should still return False, right? Perhaps an error about trying to compare a string and a number.

Of course not. Somewhere (I really can't be bothered with PHP/Smarty enough to investigate why or how) it converts the string £0.50 into 0, because it it's not a number, so naturally 0 will do just fine. It won't. It was ultimately asking if 0 == 0, which it does, then printing out on of those 0s as £0.50 when it got to the rendering stage.

I fixed it, kinda.

I had bigger things to worry about than trying to fix this properly, so I changed the module's template code to always show SAMPLE {productsample->price} – it'll work no matter the price, and I don't have to figure out where it stores the number version of the price. More importantly the customer is happy with it.