woocommerce-coupon-generator icon indicating copy to clipboard operation
woocommerce-coupon-generator copied to clipboard

Prevent generating duplicate coupon codes

Open DanWin opened this issue 1 year ago • 4 comments

When generating a large number of coupons, I noticed that some codes were duplicated. This patch will first check the database for an existing coupon code and re-generate, if it already exists.

DanWin avatar Apr 29 '23 17:04 DanWin

Hi Daniel,

I've spend a LOT of time to optimize the plugin for optimal performance when generating coupons, unfortunately adding just a single query like this will significantly impact the performance.

I have seen/had reports of duplicate coupons before, IIRC this was related due to a older version of PHP where the random function was not so random.. Could that be it for your setup?

JeroenSormani avatar May 02 '23 08:05 JeroenSormani

Hello @JeroenSormani ,

yes that is true. A possible alternative could be fetching all existing coupons, storing them in an array and then checking for duplicates. I can revise this in a new commit. There are not many duplicates, perhaps 5 on a million, but not checking for duplicates and simply assuming that enough entropy will be available to always generate a unique code won't work in the long run.

DanWin avatar May 02 '23 09:05 DanWin

If fetching/storing ALL coupons in memory I'm a bit worried about excessing memory usage (haven't checked though). Maybe this can be done as a once-off quickly at the end of the generation process to show duplicate coupons.

So far it hasn't been worth the additional effort as no-one reported it as a big issue after updating PHP 😅

JeroenSormani avatar May 02 '23 09:05 JeroenSormani

I've done some more testing, in my setup the unique-check adds roughly 10% to the generation time, but guarantees uniqueness. I also chose to check against "post_name" instead of "post_title", which WooCommerce uses, since this column is indexed and also set with the code by the plugin. Loading all the coupons and keeping them in memory turns out to be a bad idea. A single batch of 500 then jumps to using 15 times more time (with 600k coupons) and uses about 240MB of RAM. So not really an option, unless also chunked and done after finalizing the generation.

DanWin avatar May 05 '23 17:05 DanWin