Skip to content

The entity_plus_view() function returns incorrect result in certain conditions #143

Description

@alanmels

First, let me paste just the relevant part of a long custom function:

$new_product = uc_product_load_variant($result[$cycle]->nid);
$new_product->qty = $product->qty;
$new_items[] = $new_product;
dpm($new_items);
$display_items = uc_order_product_view_multiple($new_items);

At this stage, the $new_items array contains two Node type objects as dpm() shows:

Screenshot 2022-12-23 at 4 24 37 PM

Further processing through the uc_order_product_view_multiple() function turns the Node objects to UcOrderProduct objects.

function uc_order_product_view_multiple($order_products, $view_mode = 'full', $langcode = NULL, $page = NULL) {
  $order_product_entities = array();
  // Ensure we pass entities of the correct type to entity_plus_view.
  // @see https://github.com/backdrop-contrib/ubercart/issues/309
  foreach ($order_products as $id => $item) {
    if (!is_a($item, 'Entity') || $item->entityType() !== 'uc_order_product') {
      $order_product_entities[$id] = entity_create('uc_order_product', (array) $item);
    } else {
      $order_product_entities[$id] = $item;
    }
  }
  sdpm($order_product_entities);
  return entity_plus_view('uc_order_product', $order_product_entities, $view_mode, $langcode, $page);
}

Screenshot 2022-12-23 at 4 24 43 PM

The problem starts when the entity_plus_view() looses one of the array members and returns incomplete result. Unfortunately, the function was returning just one item:

function uc_order_product_view_multiple($order_products, $view_mode = 'full', $langcode = NULL, $page = NULL) {
  $order_product_entities = array();
  // Ensure we pass entities of the correct type to entity_plus_view.
  // @see https://github.com/backdrop-contrib/ubercart/issues/309
  foreach ($order_products as $id => $item) {
    if (!is_a($item, 'Entity') || $item->entityType() !== 'uc_order_product') {
      $order_product_entities[$id] = entity_create('uc_order_product', (array) $item);
    } else {
      $order_product_entities[$id] = $item;
    }
  }
  sdpm(entity_plus_view('uc_order_product', $order_product_entities, $view_mode, $langcode, $page));
  return entity_plus_view('uc_order_product', $order_product_entities, $view_mode, $langcode, $page);
}

until I changed the entity_plus_view() which looks like:

function entity_plus_view($entity_plus_type, $entities, $view_mode = 'full', $langcode = NULL, $page = NULL) {
  $info = entity_get_info($entity_plus_type);
  if (isset($info['view callback'])) {
    $entities = entity_plus_key_array_by_property($entities, $info['entity keys']['id']);
    return $info['view callback']($entities, $view_mode, $langcode, $entity_plus_type);
  }
  elseif (in_array('EntityPlusControllerInterface', class_implements($info['controller class']))) {
    return entity_get_controller($entity_plus_type)->view($entities, $view_mode, $langcode, $page);
  }
  return FALSE;
}

to:

function entity_plus_view($entity_plus_type, $entities, $view_mode = 'full', $langcode = NULL, $page = NULL) {
  $info = entity_get_info($entity_plus_type);
  if (isset($info['view callback'])) {
    $entities = entity_plus_key_array_by_property($entities, $info['entity keys']['id']);
    return $info['view callback']($entities, $view_mode, $langcode, $entity_plus_type);
  }
  elseif (in_array('EntityPlusControllerInterface', class_implements($info['controller class']))) {
    foreach ($entities as $id => $entity) {
      if (empty($entity->order_product_id)) {
        $entity->order_product_id = $id;
      }
    }
    dpm(entity_get_controller($entity_plus_type)->view($entities, $view_mode, $langcode, $page));
    return entity_get_controller($entity_plus_type)->view($entities, $view_mode, $langcode, $page);
  }
  return FALSE;
}

Turns out if $entity->order_product_id is not assigned yet, then the entity_plus_view() returns just one item (probably the last one overwrites the first one).

I'm now trying to figure out if there is a way for the newly formatted Node objects (order products) to already have order_product_id before passing to uc_order_product_view_multiple() function, but I thought to report this anyway, so you, guys, could consider changing the entity_plus_view() function slightly to make it foolproof against similar cases when UcOrderProduct entities with no order_product_id are served to it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions