Drupal → Программный экспорт товаров в CSV

10.02.2016

Пример экспорта товаров Drupal Commerce в CSV файл:

define('MODULENAME_CSV_DELIMITER', ';');

/**
 * Export form.
 */
function modulename_export_form($form, &$form_state) {
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Run export'),
  );

  if (!empty($_SESSION['export_file_ready'])) {
    drupal_add_js('
      jQuery(function() {
        var link = document.createElement("a");
        link.download = "products-export.csv";
        link.href = "' . file_create_url('public://products-export.csv') . '";
        link.click();
      });
    ', 'inline');
    unset($_SESSION['export_file_ready']);
  }
  
  return $form;
}

/**
 * Export form submit callback.
 */
function modulename_export_form_submit($form, &$form_state) {
  // Create CSV file with header
  $csv_handle = fopen('temporary://products-export.csv', 'w');
  fputcsv($csv_handle, modulename_get_csv_header_col_names(), MODULENAME_CSV_DELIMITER);

  // Create batch operations
  $product_display_nids = modulename_get_product_display_nids();
  $batch_operations = array();
  foreach ($product_display_nids as $product_display_nid) {
    $batch_operations[] = array('modulename_export_node', array($product_display_nid));
  }

  // Start batch
  batch_set(array(
    'operations' => $batch_operations,
    'finished' => 'modulename_export_batch_finished',
  ));
}

/**
 * Batch worker callback.
 */
function modulename_export_node($product_display_nid, &$context) {
  $csv_handle = fopen('temporary://products-export.csv', 'a');
  
  $product_display_wrapper = entity_metadata_wrapper('node', $product_display_nid);
  $product_wrapper = $product_display_wrapper->field_product;

  $row = array_fill_keys(modulename_get_csv_header_col_names(), '');
  
  $row['nid']      = $product_display_nid;
  $row['title']    = $product_display_wrapper->title->value();
  $row['body']     = $product_display_wrapper->body->value->value();
  $row['status']   = $product_display_wrapper->status->value();
  $row['category'] = $product_display_wrapper->field_product_category->name->value();
  $row['sku']      = $product_wrapper->sku->value();
  $row['price']    = commerce_currency_amount_to_decimal($product_wrapper->commerce_price->amount->value(), $product_wrapper->commerce_price->currency_code->value());

  fputcsv($csv_handle, $row, MODULENAME_CSV_DELIMITER);
  fclose($csv_handle);
}

/**
 * Batch finish callback.
 */
function modulename_export_batch_finished($success, $results, $operations) {
  file_unmanaged_move('temporary://products-export.csv', 'public://products-export.csv', FILE_EXISTS_REPLACE);
  $_SESSION['export_file_ready'] = TRUE;
}

/**
 * Return all product display nids.
 */
function modulename_get_product_display_nids() {
  return db_select('node', 'node')
    ->fields('node', array('nid'))
    ->condition('node.type', 'product_display')
    ->execute()
    ->fetchCol();
}

/**
 * Return CSV header col names.
 */
function modulename_get_csv_header_col_names() {
  return array(
    'nid',
    'title',
    'body',
    'status',
    'category',
    'sku',
    'price',
  );
}
Написанное актуально для
Drupal 7
Похожие записи

Комментарии

Если переписать батч на экспорт пачки товаров за одну итерацию, то можно хорошо повысить скорость выгрузки товара. Особенно актуально если товара много.

Евгений
08.04.2016, 11:47

Мне кажется, что это неправильный подход. Правильный - поставить views data export, настроить и, если нужно, дергать программно.

Во views data export вы не сможете заложить необходиму логику экспорта

Евгений
17.05.2016, 14:51

Например? Учитывая то, что это вьюха, которая экзекьютится в батче, то с помощью хендлеров и хуков можно сделать всё очень кастомизированно, если необходимо.

хендлеры, хуки, .... Это все усложняет задачу, а не упрощает (плюсом будете еще иметь проблемы с производительностью). Если простая выгрузка, то проще views data export, если есть логика, которая может в будущем усложнятся - лучше сразу заложить программную генерацию.

Евгений
20.05.2016, 15:03

Я бы сказал, что наоборот. Вместо какого-то кастомного решения, с вручную написанной обработкой полей, используются вьюхи, вылизанные кучей разработчиков.
Они отлично переносится через фичи, обладают огромной гибкостью сами по себе (поля, разные варианты вывода, т.п.), а также существует куча модулей, расширяющих их функциональность.
Views data export же позволяет этот вывод перенаправлять в файл (причем поддерживает несколько форматов), генерировать данные как напрямую, так и через батч - и так далее.
--
Использовать вьюхи - это друпал вэй. Вы же, когда хотите вывести табличку с данными, не создаете отдельный меню коллбек, в котором вызываете theme('table')? Намного легче и правильнее создать вьюху типа "page" да и накидать, что нужно.

Друпал вэй - это использовать голову, а не вьюхи. Views в данной задачи не нужен совершенно.

Евгений, больше похоже, что вы еще не сталкивались с кастомным выводом сложных данных в csv файл. Далеко не всю логику можно реализовать с помощью готовых модулей. И иногда быстрее сделать свой небольшой модуль, чем настраивать какого то монстра под узкую задачу. Но это придет) У вас еще все впереди, развивайтесь и изучайте альтернативные методы решения задач.

Гость
26.03.2017, 03:10

А как вызвать этот модуль для выполнения экспорта, после его добавления в систему и включения?

Гость
26.03.2017, 19:20

Разобрался, сделал через hook_menu. Спасибо за просвещение в массы)

Добавить комментарий