Commerce получить идентификаторы товара из заказа

12

Мой вопрос прост: как мне получить идентификаторы продукта из коммерческого заказа с кодом Drupal? У меня сейчас что-то вроде этого:

  $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?
    }

Надеюсь, кто-нибудь сможет ответить на этот вопрос :)

user5706
источник
Вы пробовали var_dump ($ order); внутри вашего 2-го foreach?
saadlulu

Ответы:

9

Я не могу вспомнить точную структуру ссылочного поля коммерческого продукта, но вам нужно сделать что-то подобное.

Предупреждение, этот стиль кода не будет работать для многих заказов, поскольку внутренний кэш для сущностей позиций будет использовать слишком много памяти. Это будет проблемой, если у вас есть тысячи заказов.

$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
источник
Спасибо, это работает. Мне пришла в голову мысль, что запуск запроса по коммерческим таблицам также был возможен. Там порядок отношений - продукт мог быть установлен с полем sku.
user5706
Я тоже. Жаль, что когда у меня есть идентификатор заказа, я не могу просто запросить ID продукта, но мне нужно загружать столько объектов.
Tomas.teicher
Неприлично использовать «und» напрямую. Если вы уверены, что ваш код будет использоваться только на непереведенном сайте, вы можете использовать константу LANGUAGE_NONE, но лучше использовать ее, field_get_items()чтобы получить элементы из поля и вместо этого выполнить итерацию. Так foreach ($order->commerce_line_items['und'] as $line) { ... }становится $items = field_get_items('commerce_order', $order, 'commerce_line_items'); foreach ($items as $line) { ... }и т. Д. Или используйте entity_metadata_wrapper, который автоматически учитывает языки.
KingAndy
22

Используя обертку метаданных сущности, вы также можете сделать:

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

Важной частью здесь является проверка типа позиции, поэтому вы не должны включать позиции отгрузки или другие типы позиций в свой список идентификаторов продуктов. Кроме того, заметив, что я использовал «сырое» значение поля commerce_product в позиции. Это связано с тем, что «value» будет полностью загруженным ссылочным продуктом, а «raw» - просто идентификатором продукта.

Райан Шрама
источник
3

Если вам не нужно загружать целые объекты (позиции, заказы и коммерческие продукты), вы можете выполнить запрос следующим образом:

 $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
источник
сопоставление данных с БД может быть довольно сложной задачей .. спасибо за эту информацию сопоставления .. искал это с 2 дня
mjs
Теоретически, другие типы сущностей могут использовать поле commerce_product, поэтому более подходящим будет соединениеJOIN {field_data_commerce_product} p ON (p.entity_id = li.line_item_id AND p.entity_type = 'commerce_line_item')
KingAndy