Skip to content

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

@alanmels

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions