Commerce obtenha IDs de produtos do pedido

12

Minha pergunta é simples: como obtenho os IDs de produtos de uma ordem comercial com código Drupal? Eu tenho algo assim no 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?
    }

Espero que alguém seja capaz de responder a esta pergunta :)

user5706
fonte
Você já tentou var_dump ($ order); dentro da sua segunda foreach?
28412 saadlulu

Respostas:

9

Não me lembro da estrutura exata do campo de referência do produto comercial, mas você precisa fazer algo assim.

Aviso: este estilo de código não funcionará em muitos pedidos, pois o cache interno das entidades do item de linha usará muita memória. Isso será um problema se você tiver milhares 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
fonte
Obrigado, isso funciona. Tive a ideia de que executar uma consulta nas tabelas de comércio também era uma opção. Existe uma ordem de relacionamento - o produto pode ter sido estabelecido com o campo sku.
user5706
Eu também. Pena que, quando tenho o ID do pedido, não posso apenas consultar o IDS do produto, mas preciso carregar tantos objetos.
tomas.teicher
Não é uma boa prática usar 'und' diretamente. Se você tiver certeza de que seu código será usado apenas em um site não traduzido, poderá usar a constante LANGUAGE_NONE - mas é uma prática melhor usar field_get_items()para obter os itens do campo e iterar por ele. Assim , foreach ($order->commerce_line_items['und'] as $line) { ... }torna-se $items = field_get_items('commerce_order', $order, 'commerce_line_items'); foreach ($items as $line) { ... }etc. Ou use o entity_metadata_wrapper, que automaticamente leva em consideração os idiomas.
KingAndy
22

Usando o wrapper de metadados da entidade, você também pode:

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();
    }
  }
}

A parte importante aqui é verificar o tipo do item de linha, para que você não inclua itens de linha de envio ou outros tipos de itens de linha na sua lista de IDs de produtos. Além disso, com o aviso de invólucro, usei o valor "bruto" do campo trade_product no item de linha. Isso ocorre porque o "valor" seria o produto referenciado totalmente carregado, enquanto o valor "bruto" é simplesmente o ID do produto.

Ryan Szrama
fonte
3

Se você não precisar carregar objetos inteiros (itens de linha, produtos de pedido e comércio), execute uma 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
fonte
mapear os dados para DB pode ser uma tarefa bastante difícil .. obrigado por esta informação mapeamento .. têm procurado isso desde 2 dias
MJS
Em teoria outros tipos de entidade poderia estar usando o campo commerce_product, de modo que o Junte-se mais apropriadamente serJOIN {field_data_commerce_product} p ON (p.entity_id = li.line_item_id AND p.entity_type = 'commerce_line_item')
KingAndy