craftcms / commerce

Fully integrated ecommerce for Craft CMS.
https://craftcms.com/commerce
Other
217 stars 170 forks source link

Invalid product ID after adding new site #1954

Closed jerome2710 closed 1 year ago

jerome2710 commented 3 years ago

Description After adding an additional site to our multi-site config, we are now seeing multiple issues when saving Commerce products. While product types don't have the 'enabled'-lightswitch like sections do, it seems that products are not properly enabled or propagated to the new site.

Schermafbeelding 2021-01-13 om 12 40 17 I have redacted the site names

  1. Site D is our new site, for both NL and EN languages. It seems that the product is disabled for these sites, but whenever I switch to either of these, the 404 Page not found / Product not found CP screen pops up.

Schermafbeelding 2021-01-13 om 13 19 17

--

  1. Whenever I now re-save the product for one of the sites where the product is enabled, it triggers the 404 error as well and causes a white screen:
yii\base\InvalidConfigException: Invalid product ID: 12345
#25 /.../vendor/craftcms/commerce/src/elements/Variant.php(432): craft\commerce\elements\Variant::getProduct
#24 /.../vendor/craftcms/commerce/src/elements/Variant.php(402): craft\commerce\elements\Variant::getFieldLayout
#23 /.../vendor/craftcms/cms/src/base/Element.php(3394): craft\base\Element::fieldByHandle
#22 /.../vendor/craftcms/cms/src/base/Element.php(1436): craft\base\Element::__get
#21 /.../vendor/tde/craft-cacheable/src/Cacheable.php(295): tde\craft\cacheable\Cacheable::tde\craft\cacheable\{closure}
#20 [internal](0): call_user_func
#19 /.../vendor/yiisoft/yii2/base/Event.php(312): yii\base\Event::trigger
#18 /.../vendor/yiisoft/yii2/base/Component.php(636): yii\base\Component::trigger
#17 /.../vendor/craftcms/cms/src/services/Elements.php(2267): craft\services\Elements::_saveElementInternal
#16 /.../vendor/craftcms/cms/src/services/Elements.php(2658): craft\services\Elements::_propagateElement
#15 /.../vendor/craftcms/cms/src/services/Elements.php(2463): craft\services\Elements::_saveElementInternal
#14 /.../vendor/craftcms/cms/src/services/Elements.php(755): craft\services\Elements::saveElement
#13 /.../vendor/craftcms/commerce/src/elements/Product.php(753): craft\commerce\elements\Product::afterSave
#12 /.../vendor/craftcms/cms/src/services/Elements.php(2454): craft\services\Elements::_saveElementInternal
#11 /.../vendor/craftcms/cms/src/services/Elements.php(755): craft\services\Elements::saveElement
#10 /.../vendor/craftcms/commerce/src/controllers/ProductsController.php(301): craft\commerce\controllers\ProductsController::actionSaveProduct
#9 [internal](0): call_user_func_array
#8 /.../vendor/yiisoft/yii2/base/InlineAction.php(57): yii\base\InlineAction::runWithParams
#7 /.../vendor/yiisoft/yii2/base/Controller.php(180): yii\base\Controller::runAction
#6 /.../vendor/craftcms/cms/src/web/Controller.php(190): craft\web\Controller::runAction
#5 /.../vendor/yiisoft/yii2/base/Module.php(528): yii\base\Module::runAction
#4 /.../vendor/craftcms/cms/src/web/Application.php(274): craft\web\Application::runAction
#3 /.../vendor/craftcms/cms/src/web/Application.php(577): craft\web\Application::_processActionRequest
#2 /.../vendor/craftcms/cms/src/web/Application.php(253): craft\web\Application::handleRequest
#1 /.../vendor/yiisoft/yii2/base/Application.php(386): yii\base\Application::run
#0 /index.php(34): null

--

  1. When trying out ./craft resave/products to possible fix some relations, it triggers errors as well: error: Invalid product ID: 12345.

Additional info

pdaleramirez commented 3 years ago

@jerome2710 It seems that you have an element type custom field on you product type variants fieldLayout that is causing the error. You could try finding that product and remove it from the custom field and see if it resolves the issue, If not We could debug further by sending us a copy of your DB along with your composer.json and composer.lock to support@craftcms.com

jerome2710 commented 3 years ago

@pdaleramirez Fortunately, saving products started working again. We are in the proces of applying various changes and I think either the project-config or delayed queue-jobs might have been causing this issue. I cannot seem to reproduce this issue anymore, although I do find it worrying.

pdaleramirez commented 3 years ago

@jerome2710 Good to know It is working now, I am closing the issue for now. If it happens again, I will re-open the issue and debug further.

jerome2710 commented 3 years ago

@pdaleramirez Unfortunately, after publishing our changes to the live site and applying the project-config, we are now unable to save any products.

2021-01-25 09:49:26 [-][1][123e20d0426403476fe7667500539897][error][yii\base\InvalidConfigException] yii\base\InvalidConfigException: Invalid product ID: 470335 in /{redacted}/vendor/craftcms/commerce/src/elements/Variant.php:432
Stack trace:
#0 /{redacted}/vendor/craftcms/commerce/src/elements/Variant.php(1134): craft\commerce\elements\Variant->getProduct()
#1 /{redacted}/vendor/craftcms/cms/src/services/Elements.php(2271): craft\commerce\elements\Variant->beforeSave(false)
#2 /{redacted}/vendor/craftcms/cms/src/services/Elements.php(2658): craft\services\Elements->_saveElementInternal(Object(craft\commerce\elements\Variant), true, false)
#3 /{redacted}/vendor/craftcms/cms/src/services/Elements.php(2463): craft\services\Elements->_propagateElement(Object(craft\commerce\elements\Variant), Array, Object(craft\commerce\elements\Variant))
#4 /{redacted}/vendor/craftcms/cms/src/services/Elements.php(755): craft\services\Elements->_saveElementInternal(Object(craft\commerce\elements\Variant), false, true, true)
#5 /{redacted}/vendor/craftcms/commerce/src/elements/Product.php(753): craft\services\Elements->saveElement(Object(craft\commerce\elements\Variant), false)
#6 /{redacted}/vendor/craftcms/cms/src/services/Elements.php(2454): craft\commerce\elements\Product->afterSave(false)
#7 /{redacted}/vendor/craftcms/cms/src/services/Elements.php(755): craft\services\Elements->_saveElementInternal(Object(craft\commerce\elements\Product), true, true, true)
#8 /{redacted}/vendor/craftcms/commerce/src/controllers/ProductsController.php(301): craft\services\Elements->saveElement(Object(craft\commerce\elements\Product))
#9 [internal function]: craft\commerce\controllers\ProductsController->actionSaveProduct(false)
#10 /{redacted}/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array(Array, Array)
#11 /{redacted}/vendor/yiisoft/yii2/base/Controller.php(180): yii\base\InlineAction->runWithParams(Array)
#12 /{redacted}/vendor/craftcms/cms/src/web/Controller.php(190): yii\base\Controller->runAction('save-product', Array)
#13 /{redacted}/vendor/yiisoft/yii2/base/Module.php(528): craft\web\Controller->runAction('save-product', Array)
#14 /{redacted}/vendor/craftcms/cms/src/web/Application.php(274): yii\base\Module->runAction('commerce/produc...', Array)
#15 /{redacted}/vendor/craftcms/cms/src/web/Application.php(577): craft\web\Application->runAction('commerce/produc...', Array)
#16 /{redacted}/vendor/craftcms/cms/src/web/Application.php(253): craft\web\Application->_processActionRequest(Object(craft\web\Request))
#17 /{redacted}/vendor/yiisoft/yii2/base/Application.php(386): craft\web\Application->handleRequest(Object(craft\web\Request))
#18 /{redacted}/web/index.php(34): yii\base\Application->run()
#19 {main}

Please note that our product variants does not have any additional fields in it's field layout, as you mentioned in #issuecomment-760092582. I will e-mail the database and files as well.

jerome2710 commented 3 years ago

To help any others, @pdaleramirez eventually came to the same conclusion that the propagation of products failed for the new site. We commented the following line: https://github.com/craftcms/commerce/blob/09895aa60dfc7e580d9c49a0c5d82ac938b80d31/src/elements/Variant.php#L426 to prevent Craft from retrieving the product from that specific site and ran ./craft resave/products to force the propagation. Uncommenting the line afterwards and everything works again now!

Craft will look into this and investigate what might have went wrong, but this solution might get your shop back up and running! Thanks @pdaleramirez!

jerome2710 commented 3 years ago

Hi @pdaleramirez, already any updates on the cause of this issue? We just published some changes to one of our production sites and everything broke again. Luckily the previous fix still works, but it's not really comforting.

yoannisj commented 3 years ago

I am experiencing the same issue when pushing and applying project-config changes which include a craft update, commerce update, and creation of a new site to a staging server.

There is a lot going on, and I am not sure exactly which of these factors are related to or causing the issue, so let me try and outline the context and scenario in as much detail as possible:

  1. Created two new sites locally (updates project-config files)
  2. Updated Craft CMS from 3.5.19 to 3.6.10 and Commerce from 3.2.15.1 to 3.2.17.1 locally (updates composer.json and project-config files)
  3. Updated other plugins locally (I don't think this is related, but who knows)
  4. Import sql dump from production database (uses Craft 3.5.19 and Commerce 3.2.15) into staging database (not sure this is relevant, but most likely)
  5. Deploy local code changes to staging server with git, which triggers a deployment script running the following commands:
    • composer install
    • php craft migrate/all
    • php craft project-config/apply
    • php craft clear-caches/all
    • php craft invalidate-tags/all

The deployment adds many jobs to the queue, including multiple "Resave products" jobs (seems to be one per site). All "Resave products" jobs fail with the "Invalid product ID {id}" error thrown at vendor/craftcms/commerce/src/elements/Variant.php(402): craft\commerce\elements\Variant->getProduct().

It looks like the job tries to resave product Variants in a site where the product does not exist: when I go to /<cp-trigger>/commerce/products and select any of the new sites, the list of products is empty (for sites that already existed before the deployment, I can see all products being listed).

My feeling is that there should be a "Propagate products" job for each new site which is missing from the queue for some reason. Looks like Craft pushes such a job for other localized element types when creating new sites: https://github.com/craftcms/cms/blob/3.6/src/services/Sites.php#L786-L806. Unless the "Resave products" job fulfils the same purpose?

yoannisj commented 3 years ago

The same error is thrown when trying to save the product for an existing site via the CP (like @jerome2710 reports above). I just checked the database and I can see the product id in the craft_commerce_products table, and the product.id >< site.id relation in the craft_elements_sites table.

jerome2710 commented 3 years ago

Hi @pdaleramirez, following the detailed description of @yoannisj, we have just added another multi-site to our project as well. The full collection of products failed as a response and I was forced to manually apply the fix as described above. While this issue is marked as closed, I do not feel comfortable debugging and manually modifying vendor packages on our production server in effort to fix issues. Is it possible to look into a more robust solution for this issue?

pdaleramirez commented 3 years ago

@jerome2710 If at some point you are able to recreate the steps on how this happens. Please create a new issue then we'll track further.

@yoannisj Commerce does Propagate products for each new site created.

boboldehampsink commented 1 year ago

@pdaleramirez this is still an issue with the latest version of Craft Commerce. This is because when propagating a variant it tries to get a product of the new site, which hasn't been saved yet.

pdaleramirez commented 1 year ago

@boboldehampsink This is the intended behavior because Commerce does not support multi store yet. A product on a site will propagate to all created sites. Commerce will support multi store on Commerce 5 which will be released this year. When multi store is live you can create products on different site with its own pricing and attributes. You can track it here https://github.com/craftcms/commerce/discussions/2283

boboldehampsink commented 1 year ago

@pdaleramirez yeah but this means that Craft Commerce won't work at all on a multisite setup... my fix in #3068 simply ignores specific sites, making it work again. Since Commerce doesn't support multisite, why bother fetching for a specific site anyway?

lukeholder commented 1 year ago

We still want to get the correct Product in getProduct(), which should be the same site as the variant, so we are leaving that as the default. This is useful in templates with variant.product.title, for example, where you would want the correct translated title.

But, we can see if the original propagation failed when making the new site, and the Product does not yet exist in that new site, we agree that getting the primary site product is fine during the duration of that request (which may happen during a resave of all products).