I'm using reference field for commerce product in node entity and using inline entity form to edit it in node. After declaring this field in node form I get error:

TypeError: Argument 1 passed to Drupal\commerce_bulk\BulkVariationsCreator::getProductVariation() must be an instance of Drupal\commerce_product\Entity\Product, null given, called in
/modules/contrib/commerce_bulk/commerce_bulk.module on line 61 in
/modules/contrib/commerce_bulk/src/BulkVariationsCreator.php on line 105 #0
/modules/contrib/commerce_bulk/commerce_bulk.module(61): Drupal\commerce_bulk\BulkVariationsCreator->getProductVariation(NULL)

This error is occurred because this line is incorrect for my case:

$product = $form_state->getFormObject()->getEntity();

Because $form_state was generated for node form not for product form.

I have quick fix for me but I think it's not a solution. I used this line after previous:

if (get_class($product) == 'Drupal\node\Entity\Node') {
   $product = $product->get('field_product')->entity;
}

Also this line was working instead of original line:

$product = $context['items']->getEntity();

field_product — is my reference field.

Also after clicking generation button I got error:

TypeError: Argument 1 passed to Drupal\commerce_bulk\BulkVariationsCreator::getAttributeFieldOptionIds() must be an instance of Drupal\commerce_product\Entity\ProductVariation, boolean given, called in
/modules/contrib/commerce_bulk/src/BulkVariationsCreator.php on line 287 in
/modules/contrib/commerce_bulk/src/BulkVariationsCreator.php on line 397 #0
/modules/contrib/commerce_bulk/src/BulkVariationsCreator.php(287): Drupal\commerce_bulk\BulkVariationsCreator->getAttributeFieldOptionIds(false)

Here we have the same situation, because the next code is incorrect for my case:

$ief_id = $form['variations']['widget']['#ief_id'];

Because node form doesn't include this.

I added the next code for fixing (it works only for me):

if (!empty($form['field_product']['widget'][0]['inline_entity_form']['variations']['widget']['#ief_id'])) {
   $ief_id = $form['field_product']['widget'][0]['inline_entity_form']['variations']['widget']['#ief_id'];
}

field_product — is my reference field.

I think solution of this is simple but I didn't find it for now. I'll be searching it for nearest time. But If I will not be able to do it I'll use this quick solution. But it will not work for reference fields with different name. Also I'm not sure that my solution work correctly.

CommentFileSizeAuthor
#5 fix-reference-field-issue.patch2.5 KBlobodakyrylo

Comments

madlobz created an issue. See original summary.

drugan’s picture

Title: Module doesn't work with product reference field » Add support for product reference field
Version: 8.x-1.0-alpha3 » 8.x-1.x-dev
Component: Code » Commerce Bulk
Category: Bug report » Feature request
Priority: Critical » Normal

Unfortunately, the Drupal Commerce does not support products referenced from nodes. The same with the Commerce Bulk, as it totally relies on a bare product, not a reference field.

if (get_class($product) == 'Drupal\node\Entity\Node') {
   $product = $product->get('field_product')->entity;
}

This assumes that the field is always called product resulting in 'field_product' but it may be called whatever. In my test case I've called it 'field_my_product', french may call it 'field_produit' and so on. Also, assuming that product will be always referenced from the node entity is a bit specific one. If we'd fix it, tomorrow someone will open a new issue: "Add support for xyz entity!!!".

Below are the DC issues related with node as a housing for products. The whole issue is quite complex and potentially might be fixed here, therefore I don't close it yet in a hope that some day I'll have a free time for the work. Contributed patches are welcomed but, ... you should think carefully whether the play worth candles. Is it not simpler to use products for placing the required content? (стоит ли овчинка выделки ваще)

#2821338: (Commerce:) Error when creating both product and variations via nested inline entity forms
#2651026: Fatal error with AddToCartForm.php
#2927505: Using existing Node as Product Entity
#2892201: How to reference and connect products to nodes and nodes to products
#2861197: Allow to use non commerce_product entity (example - node)

lobodakyrylo’s picture

Unfortunately, the Drupal Commerce does not support products referenced from nodes.

What do you mean Drupal Commerce doesn't support referenced form? I'm using Inline Entity Form for it that is part of Commerce requirements. It worked in drupal 7 and works in Drupal 8. I have some specific tasks that can be solved only with reference between node and product. If Commerce has this ability why do I need to change specification for my website or create a custom module.

I'll try to solve this problem in general. Thanks.

drugan’s picture

I mean, the fatal error when adding / editing node could be fixed right now:


function commerce_bulk_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {
  $product = $form_state->getFormObject()->getEntity();
  if (!($product instanceof Drupal\commerce_product\Entity\ProductInterface)) {
    return;
  }
  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
  $field_definition = $context['items']->getFieldDefinition();
  $field_name = $field_definition->getName();
  $entity_type = $field_definition->getTargetEntityTypeId();
// ....
}

But the Commerce Bulk will not work on this form. No variations could be bulk created. You can create variations manually, one by one, but they will not work properly. See issues on the #1 comment.

Conclusion: if all that you need to prevent fatal error then I'll fix it right now (has no sense at all). If you need Commerce Bulk working with node referenced products then please, wait a bit. Or, would be glad to review a patch if that will be contributed.

lobodakyrylo’s picture

StatusFileSize
new2.5 KB

I solved this issue. But we need to check all features. I attached a patch.

In this case I get object from context and send wrapper ID via button settings.

Also I changed this code:

$variation = $this->entityTypeManager->getStorage('commerce_product_variation')->create([

to:

$variation = \Drupal::entityTypeManager()->getStorage('commerce_product_variation')->create([

Really I don't understand why do you use property entityTypeManager, but if in this it's not needed it will solve a problem.

drugan’s picture

Status: Active » Needs work

I really like the patch and want to commit it but...

What I've found:

The fatal error is gone: good!

The bulk creation of variations works inside nested IEF product form: good!

The created reference product could be deleted outside the housing node: not good but might be ignored as a site admin's trouble.

The created reference product is not deleted when the housing node is deleted: actually good.

The node could be saved without referenced product is saved on the IEF form (variations are bulk created but the Create product button is not pressed): not good but could considered as admin's trouble.

After everything is saved as needed and attempted to press the Add to cart button there is a fatal error:

The website encountered an unexpected error. Please try again later.</br></br><em class="placeholder">Exception</em>: The given entity is not assigned to any store. in <em class="placeholder">Drupal\commerce_cart\Form\AddToCartForm-&gt;selectStore()</em> (line <em class="placeholder">255</em> of <em class="placeholder">modules/commerce_core_modules/commerce/modules/cart/src/Form/AddToCartForm.php</em>)

Opened the node for editing again and checked: the store checkbox is checked as it was before saving product & node.

And only after pressing the Update product button and resaving the node everything works as expected.

Obviously that you and me can easily remember the trick and apply each time when creating referenced products but that's inappropriate for most of the users.

Would be great if we'd found the reason for not saved store issue because many people are used to D7 product displays and that way they can more easily migrate to D8 products. Which are actually better than displays.

drugan’s picture

#2721349: Nested inline entities must be saved in "inside-out" order

Might be related, I am not sure yet, needs digging in.

lobodakyrylo’s picture

Thanks. I'll be working on this issue today. Maybe I'll find solution.

lobodakyrylo’s picture

I caught issue with nested entities: https://www.drupal.org/project/inline_entity_form/issues/2721349#comment...
And it's correctly works for me. We need to wait community tests and reactions.

drugan’s picture

Thank you. Waiting impatiently because this will be cool. Even the Drupal Commerce does not provide this but we will!

ncxn’s picture

I found same issues:

TypeError: Argument 1 passed to Drupal\commerce_bulk\BulkVariationsCreator::getProductVariation() must be an instance of Drupal\commerce_product\Entity\Product, instance of Drupal\commerce_bulk\Entity\BulkProductVariation given, called in .\modules\commerce_bulk\commerce_bulk.module on line 171 in Drupal\commerce_bulk\BulkVariationsCreator->getProductVariation() (line 105 of ..\modules\commerce_bulk\src\BulkVariationsCreator.php)

line 171: commerce_bulk.module

$variation = $creator->getProductVariation($product);

line 105 BulkVariationsCreator.php

public function getProductVariation(Product $product) {
    $variations = $product->getVariations();
    $variation = end($variations);
    $timestamp = time();
    if (!$variation instanceof ProductVariation) {
      $variation = \Drupal::entityTypeManager()->getStorage('commerce_product_variation')->create([
        'type' => $product->getFieldDefinition('variations')->getSettings()['handler_settings']['target_bundles'][0],
        'created' => $timestamp,
        'changed' => $timestamp,
      ]);
    }

    return $variation;
  }
drugan’s picture

anybody’s picture

Assigned: lobodakyrylo » Unassigned