backdrop-contrib / ubercart

A flexible but easy-to-use e-commerce system for Backdrop.
https://backdropcms.org/project/ubercart
GNU General Public License v2.0
4 stars 10 forks source link

Ubercart/Filefield Paths crash (stdClass instead of entity) #496

Closed bugfolder closed 6 months ago

bugfolder commented 7 months ago

The error message is:

Message | Error: Call to undefined method stdClass::bundle() in filefield_paths_field_storage_pre_update() (line 363 of mysite/modules/contrib/filefield_paths/filefield_paths.module).

Further details and discussion in the original FFP issue: https://github.com/backdrop-contrib/filefield_paths/issues/27

H/T @argiepiano

bugfolder commented 7 months ago

Some notes here. Per @argiepiano's comment, I can reproduce this error in an installation with filefield_paths module installed if I

Also:

This is all consistent with @argiepiano's description of what's going on and what needs to be fixed.

bugfolder commented 7 months ago

Using entity_create in uc_order_edit_products_add_blank() fixes the problem with adding a blank line.

However, in the case of editing an existing order, the stdClass is still there (giving rise to a missing bundle() method), and comes from a cast to object in uc_order_pane_products() (lines 245–251):

    case 'edit-process':
      if (isset($form_state['values']['products'])) {
        foreach ($form_state['values']['products'] as $key => $product) {
          $product['data'] = unserialize($product['data']);
          uc_order_product_save($order->order_id, (object) $product);
        }
      }

There's lots of stdClass and (object) $something throughout UC, so there may be more of this situation lurking about.

argiepiano commented 7 months ago

I can take a look tonight. Many of the stdClass uses are not fieldable entities. This one is.

argiepiano commented 7 months ago

@bugfolder I'm submitting a PR. This needs thorough testing just to be sure it doesn't break other things.

In addition to using entity_create() in uc_order_edit_products_add_blank() (which you tried), it stores the existing uc_order_product entities present in the order in the $form_state array, so that they can be retrieved in the submit handler handled by the 'edit-process' op. That handler basically sets the values of the entity object properties, and uses that entity object to send to uc_order_product_save() instead of a stdClass object.

bugfolder commented 7 months ago

Testing:

However:

Warning: Undefined array key 105642 in uc_order_pane_products() (line 248 of /mysite/modules/contrib/ubercart/uc_order/uc_order.order_pane.inc). Error: Attempt to assign property "remove" on null in uc_order_pane_products() (line 250 of /mysite/modules/contrib/ubercart/uc_order/uc_order.order_pane.inc).

argiepiano commented 7 months ago

Hmmm... I'm able to add products normally. But I'm working with a vanilla install of Ubercart without anything else. Can you let me know what other uc modules you have enabled?

[EDIT] OK, I think I can reproduce. Will look more into this.

argiepiano commented 7 months ago

@bugfolder, here's a different approach. There is no need to store the products in the $form_state (in fact, that let to the issue you found, since a Node object is stored there when a normal product is added). So, now, in order to populate their new values, products are pulled from the order itself. The $order object contains the new products nd blank line items as UcOrderProduct objects already by the time it reaches the processes in 'form-process'.

Please test.

bugfolder commented 7 months ago

Ran all those same tests (and a few more CRUD actions on the admin order page). All worked. LGTM.