Commerce obtiene la identificación del producto del pedido

12

Mi pregunta es simple: ¿cómo obtengo la identificación del producto de una orden comercial con código Drupal? Tengo algo como esto en este momento:

  $orders = commerce_order_load_multiple(array(), array('status' => 'pending'), TRUE);
  foreach($orders as $order) {
    foreach ($order->commerce_line_items['und'] as $line) {
        $line_id = $line['line_item_id'];
        // ... product id, where are you?
    }

Esperemos que alguien pueda responder esta pregunta :)

usuario5706
fuente
¿Has probado var_dump ($ order); dentro de tu segundo foreach?
saadlulu

Respuestas:

9

No recuerdo la estructura exacta del campo de referencia del producto comercial, pero debe hacer algo como esto.

Advertencia: este estilo de código no funcionará en muchos pedidos, ya que la memoria caché interna para las entidades de línea de pedido usará demasiada memoria. Esto será un problema si tiene miles de pedidos.

$orders = commerce_order_load_multiple(array(), array('status' => 'pending'), TRUE);
foreach($orders as $order) {
  foreach ($order->commerce_line_items['und'] as $line) {
    $line_item = commerce_line_item_load($line['line_item_id']);
    $product_id = $line_item->commerce_product['und']...
  }
}
googletorp
fuente
Gracias, esto funciona. Se me ocurrió que ejecutar una consulta en las tablas de comercio también era una opción. Existe un orden de relación: el producto podría haberse establecido con el campo sku.
user5706
Yo también. Lástima que cuando tengo ID de pedido, no puedo simplemente consultar IDS de productos, sino que tengo que cargar tantos objetos.
tomas.teicher
No es una buena práctica usar 'und' directamente. Si está seguro de que su código solo se usará en un sitio no traducido, puede usar la constante LANGUAGE_NONE, pero es mejor usarla field_get_items()para obtener los elementos del campo e iterar a través de ella. Entonces se foreach ($order->commerce_line_items['und'] as $line) { ... }convierte $items = field_get_items('commerce_order', $order, 'commerce_line_items'); foreach ($items as $line) { ... }, etc. O, usa entity_metadata_wrapper, que automáticamente toma en cuenta los idiomas.
KingAndy
22

Usando el contenedor de metadatos de la entidad, también podría hacer:

foreach (commerce_order_load_multiple(array(), array('status' => 'pending'), TRUE) as $order) {
  $product_ids = array();
  foreach (entity_metadata_wrapper('commerce_order', $order)->commerce_line_items as $delta => $line_item_wrapper) {
    if (in_array($line_item_wrapper->type->value(), commerce_product_line_item_types())) {
      $product_ids[] = $line_item_wrapper->commerce_product->raw();
    }
  }
}

La parte importante aquí es verificar el tipo de línea de pedido, para que no termine incluyendo líneas de envío u otros tipos de líneas de pedido en su lista de ID de productos. Además, con el aviso de contenedor que utilicé el valor "sin procesar" del campo commerce_product en la línea de pedido. Esto se debe a que el "valor" sería el producto referenciado completamente cargado, mientras que el valor "en bruto" es simplemente el ID del producto.

Ryan Szrama
fuente
3

Si no necesita cargar objetos completos (líneas de pedido, pedidos y productos comerciales), puede ejecutar una consulta como esta:

 $args = array(
    ':order_id' => $order_id,

);
$product_ids = db_query("SELECT p.commerce_product_product_id 
   FROM {commerce_line_item} li 
   JOIN {field_data_commerce_product} p ON (p.entity_id = li.line_item_id) 
   WHERE li.order_id = :order_id AND li.type = 'product'", $args)->fetchCol();
return $product_ids;
tomas.teicher
fuente
asignar los datos a DB puede ser una tarea bastante desalentadora ... gracias por esta información de asignación ... he estado buscando esto desde hace 2 días
mjs
En teoría, otros tipos de entidades podrían estar utilizando el campo commerce_product, por lo que la unión sería más apropiadamente serJOIN {field_data_commerce_product} p ON (p.entity_id = li.line_item_id AND p.entity_type = 'commerce_line_item')
KingAndy