Since the security release SA-CORE-2019-003 (https://www.drupal.org/node/3034490) serialized objects stored in product 'options' are no longer able to be unserialized correctly and product pages can no longer be viewed as a PHP error is thrown:
Notice: Drupal\shopify\Form\ShopifyVariantOptionsForm::buildForm(): The script tried to execute a method or access a property of an incomplete object. Please ensure that the class definition "stdClass" of the object you are trying to operate on was loaded _before_ unserialize() gets called or provide a __autoload() function to load the class definition in Drupal\shopify\Form\ShopifyVariantOptionsForm->buildForm()
The line from the security release affecting this issue on Drupal 8.5 is https://github.com/drupal/core/commit/59396df3e7d8c304b2de91a1b34835a874...
According to http://php.net/manual/en/function.unserialize.php the allowed_classes basically instantiates all classes as __PHP_Incomplete_Class
This affects sites running Drupal 8.6 too as the same line is in that release too.
I assume the object needs to be stored in that options product property so there's no way around that, and the security patch still needs to be applied, so the only way around this issue that I can see at the moment is to try and turn the object into a 'complete' one.
Not sure whether to mark this as Critical or Major as technically product pages are no longer able to be accessed and pages are broken.
Comments
Comment #2
oldspot commentedI managed to quickly patch the site by adding this code in the "src/Form/ShopifyVariantOptionsForm.php" file:
And calling that function from the buildForm function:
I'll try and create a patch from it (unless someone else has a better fix for it) once I fix a checkout issue that got introduced as well last night :(
Comment #3
oldspot commentedCreated a quick patch from above code. Seems to work fine on our site and it brought back the product pages.
Comment #4
xpersonas commentedI can confirm this issue after upgrading. I'm using alpha3 too. alpha 4 breaks my site.
I was just about to post the exact same patch when I found yours. I can confirm that it fixes the error.
Comment #5
bdawg8569 commentedI had this same issue on drupal 8.6 and after the move to 8.6.10. I fixed it on my local copy and thought it was all good, only to find that it didn't work on my production server when I pushed it up. After closer inspection, this fix will NOT work if you are using PHP 7.2.
The conditions that are being used in the patch to determine when to serialize/unserialize are using is_object() and there was a change to how this works in php 7.2
"is_object() now returns TRUE for unserialized objects without a class definition (class of __PHP_Incomplete_Class). Previously FALSE was returned."
To fix this, I simply changed the condition for the fixIncompleteObject function:
Comment #6
Asacolips commentedRerolled the patch against 8.x-1.x-dev and implemented the change in #5. In addition, the patch from #3 introduced a new
$optionvariable that was passed by reference and conflicts with a different$optionvariable later in the code. I renamed that to$option_objto restore functionality for multi-variant product forms.Comment #7
xpersonas commentedI'm not sure what has changed, but I was having the same issues described earlier, but recently I found that my variant (options) select list was not working on my products. Debugging, I noticed I was no longer getting the incomplete object. So it seemed I didn't need this patch anymore.
Now it seemed like for what ever reason, I couldn't access the options of the product entity. So I added a getOptions() method to the entity, and I'm calling that now in my ShopifyVariantOptionsForm.php. Seems to work.
It's still related to this issue enough that I wanted to put the patch here in case it helps any one else.
Comment #8
xpersonas commentedApologies, disregard #7. Patched the wrong version. I'm still using the alpha3 version.
Comment #9
abaier commentedToday I did an upgrade of Drupal core from 8.5.3 to 8.7.3 and noticed that my product pages were also missing their options fields. I am using shopify 8.x-1.0-alpha3+16-dev.
Patch #7 did not work for me, so I tried #8, which eliminated the warnings, but brought back only ONE options field per product. Sometimes we have multiple, i.e. size and color.
I then changed the follwing in the patch, which worked out so far:
I am no coder actually, so please correct me, if this could cause 'damage' ;)
Before, I got the following warnings:
Comment #10
gustavowal commentedWe've had an issue where a product with no options was giving a fatal error when accessing the page.
This was due to
shopify/src/Form/ShopifyVariantOptionsForm.php L35 $options = $product->getOptions();getting product options not as an multidimensional array. When'#title' => t($option->name),was called,core/lib/Drupal/Core/StringTranslation/TranslatableMarkup.php L130 if (!is_string($string))was getting TRUE cause $string was null and was throwing an exception.Managed to temporarily fix this by applying https://www.drupal.org/files/issues/2019-04-01/2719553-26-null_for_strin... but that would show the Product Option Selector even when the product didn't had any.
I got this fixed more correctly by checking for an array before returning on
function getOptions().Comment #11
abaier commentedThanks for patch #10! Works as expected.
Comment #12
rho_ commentedPatch #10 worked for me as well.
Comment #13
bobbygryzyngerWith the patch in #10
$product->getOptions()returns a serialized array which causes the options rendering to fail because it passes a non-string for translation which causes the error (which seems like it should be the expected behavior).Here, it looks like the options should be unserialized at some point before processing them.
Comment #14
bobbygryzyngerComment #15
lobodakyrylo commentedThis patch for dev version of the module
Comment #16
joe huggansI am also seeing this error when syncing products, I seem to have patched this by adding the following to the shopify_sync_products() function in shopify.module file after the line
if ($entity instanceof ShopifyProduct) {Comment #17
bobbygryzyngerI'm still seeing the issue with serialized options mentioned in #13. The attached patch attempts to unserialize the options if they're not already an array.
Comment #18
bobbygryzyngerThe attached patch stores all options as a serialized array rather than a PHP object. This will need a post_update operation to resync all products since the product option storage will need to be altered.
Comment #19
bobbygryzyngerSetting to "needs work" to deal with update path.
Comment #21
bobbygryzyngerSaving credit.
Comment #22
bobbygryzyngerAdds the post_update hook to resync all of a site's products.
Comment #24
bobbygryzynger