commerce_smart_importer-8.x-1.0-alpha1/src/Form/CSVExportForm.php

src/Form/CSVExportForm.php
<?php

namespace Drupal\commerce_smart_importer\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\commerce_smart_importer\Plugin\CommerceSmartImporterService;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\commerce_store\Entity\Store;

/**
 * Form for exporting products in CSV format.
 *
 * Later can be used in update.
 */
class CSVExportForm extends FormBase {

  /**
   * Database service.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * Smart importer service.
   *
   * @var \Drupal\commerce_smart_importer\Plugin\CommerceSmartImporterService
   */
  protected $smartImporterService;

  /**
   * Config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactory
   */
  protected $configFactory;

  /**
   * Entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * Returns form id.
   */
  public function getFormId() {
    return 'csvExportFormSmartImporter';
  }

  /**
   * CSVExportForm constructor.
   */
  public function __construct(Connection $connection,
                              CommerceSmartImporterService $service,
                              ConfigFactory $configFactory,
                              EntityTypeManagerInterface $entityTypeManager) {
    $this->database = $connection;
    $this->smartImporterService = $service;
    $this->configFactory = $configFactory;
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * Create.
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('database'),
      $container->get('commerce_smart_importer.service'),
      $container->get('config.factory'),
      $container->get('entity_type.manager')
    );
  }

  /**
   * Builds form.
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $options['all'] = 'All';
    $config = $this->smartImporterService->getConfig();
    $taxonomies = $this->smartImporterService->getReferencedTaxonomyTerms('product', $config['commerce_product_bundle']);

    foreach ($taxonomies as $taxonomy) {
      $options[$taxonomy['machine_name']] = $taxonomy['name'];
    }

    $form['export_by'] = [
      '#type' => 'select',
      '#options' => $options,
    ];

    foreach ($options as $exportBy => $option) {
      $options2 = [];

      $options2['all'] = 'All';
      if ($exportBy != 'all') {
        foreach ($taxonomies as $taxonomy) {
          if ($taxonomy['machine_name'] == $exportBy) {
            foreach ($taxonomy['target_bundles'] as $bundle) {
              $terms = $this->entityTypeManager
                ->getStorage('taxonomy_term')
                ->loadTree($bundle);
              foreach ($terms as $term) {
                $options2[$term->tid] = $term->name;
              }
            }
          }
        }
      }

      $form['export_tax_' . $exportBy] = [
        '#type' => 'select',
        '#options' => $options2,
        '#states' => [
          'visible' => [
            ':input[name="export_by"]' => ['value' => $exportBy],
          ],
        ],
      ];
    }

    $fields = $this->smartImporterService->getFieldDefinition(TRUE);
    $identifier_fields = $this->smartImporterService->getIdentifierFields();
    $product_identifiers = [];
    $product_fields = [];
    foreach ($fields['product'] as $field) {
      if (in_array($field['machine_names'], $identifier_fields['product'])) {
        $product_identifiers[$field['machine_names']] = ['machine_name' => $field['machine_names'], 'field_name' => $field['label']];
      }
      else {
        $product_fields[$field['machine_names']] = ['machine_name' => $field['machine_names'], 'field_name' => $field['label']];
      }
    }
    $variation_identifiers = [];
    $variation_fields = [];
    foreach ($fields['variation'] as $field) {
      if (in_array($field['machine_names'], $identifier_fields['variation'])) {
        $variation_identifiers[$field['machine_names']] = ['machine_name' => $field['machine_names'], 'field_name' => $field['label']];
      }
      else {
        $variation_fields[$field['machine_names']] = ['machine_name' => $field['machine_names'], 'field_name' => $field['label']];
      }
    }
    $headers = ['field_name' => $this->t('Field name'), 'machine_name' => $this->t('Machine name')];
    $form['product'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Product Fields'),
    ];
    $form['product']['product_identifiers_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Product identifier Fields'),
    ];
    $form['product']['product_identifiers_fieldset']['product_identifiers'] = [
      '#type' => 'tableselect',
      '#header' => $headers,
      '#options' => $product_identifiers,
    ];

    $form['product']['product_fields_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Product Fields'),
    ];

    $form['product']['product_fields_fieldset']['product_fields'] = [
      '#type' => 'tableselect',
      '#header' => $headers,
      '#options' => $product_fields,
    ];

    $form['variation'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Variation Fields'),
    ];
    $form['variation']['variation_identifiers_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Variation identifier Fields'),
    ];
    $form['variation']['variation_identifiers_fieldset']['variation_identifiers'] = [
      '#type' => 'tableselect',
      '#header' => $headers,
      '#options' => $variation_identifiers,
    ];

    $form['variation']['variation_fields_fieldset'] = [
      '#type' => 'fieldset',
      '#title' => $this->t('Variation Fields'),
    ];

    $form['variation']['variation_fields_fieldset']['variation_fields'] = [
      '#type' => 'tableselect',
      '#header' => $headers,
      '#options' => $variation_fields,
    ];

    $form['export'] = [
      '#value' => 'Export',
      '#type' => 'submit',
    ];

    $form['download_export'] = [
      '#value' => 'Download last export',
      '#type' => 'submit',
      '#submit' => [[$this, 'downloadCsv']],
    ];

    $form['#attached']['library'] = [
      'commerce_smart_importer/commerce-smart-importer-importer-load-library',
    ];

    if (isset($_GET['download'])) {
      $this->downloadCsv();
    }

    return $form;
  }

  /**
   * Validates form.
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();
    if ($this->isFieldChecked($values['variation_fields'])) {
      if (!$this->isFieldChecked($values['variation_identifiers'])) {
        $form_state->setErrorByName('variation_identifiers', $this->t('If you want to export variation, you need at least one identifier.'));
      }
    }

    if ($this->isFieldChecked($values['product_fields'])) {
      if (!$this->isFieldChecked($values['product_identifiers'])) {
        $form_state->setErrorByName('product_identifiers', $this->t('If you want to export product, you need at least one identifier.'));
      }
    }

    parent::validateForm($form, $form_state);
  }

  /**
   * Submits form.
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $values = $form_state->getValues();
    $config = $this->smartImporterService->getConfig();
    $export_fields_names = [];
    foreach ($values['product_fields'] as $field) {
      if (!empty($field)) {
        $export_fields_names[] = $field;
      }
    }
    foreach ($values['product_identifiers'] as $field) {
      if (!empty($field)) {
        $export_fields_names[] = $field;
      }
    }
    foreach ($values['variation_identifiers'] as $field) {
      if (!empty($field)) {
        $export_fields_names[] = $field;
      }
    }
    foreach ($values['variation_fields'] as $field) {
      if (!empty($field)) {
        $export_fields_names[] = $field;
      }
    }
    $fields = $this->smartImporterService->getFieldDefinition(TRUE);

    $this->leaveOnlyCheckedFields($fields, $export_fields_names);
    if ($values['export_by'] != 'all' && $values['export_tax_' . $values['export_by']] != 'all') {
      $query = $this->database->query("SELECT cp.product_id FROM commerce_product cp JOIN commerce_product__" . $values['export_by'] . " tax ON tax.entity_id=cp.product_id WHERE tax." . $values['export_by'] . "_target_id=" . $values['export_tax_' . $values['export_by']])->fetchAll();
      $field_value = [$values['export_by'], $values['export_tax_' . $values['export_by']]];
    }
    else {
      $query = $this->database->select('commerce_product')
        ->fields('commerce_product', ['product_id'])
        ->condition('type', $config['commerce_product_bundle'])
        ->execute()->fetchAll();
      $field_value = [];
    }

    $product_number = count($query);
    $per_batch = 5;
    $number_of_batches = ceil($product_number / $per_batch);

    $batch = [
      'title' => $this->t('Exporting all products'),
      'init_message' => $this->t('Beginning...'),
      'progress_message' => $this->t('exported @current out of @total product groups'),
      'error_message' => $this->t('Something went wrong'),
      'progressive' => FALSE,
      'operations' => [],
    ];

    if ($config['store'] != 'all') {
      $store = Store::load($config['store']);
      $name = $store->getName();
    } else {
      $name = $this->config('system.site')->get('name');
    }

    $file = fopen('temporary://export-' . str_replace(' ', '-', $name) . '.csv', 'w');
    $header = [];
    foreach ($fields['product'] as $product_header) {
      $header[] = $product_header['label'];
    }
    foreach ($fields['variation'] as $variation_header) {
      $header[] = $variation_header['label'];
    }
    fputcsv($file, $header);
    fputcsv($file, ['']);
    fclose($file);
    for ($i = 0; $i < $number_of_batches; $i++) {
      $batch['operations'][] = [
        [
          $this,
          'putExportedProductsInCsv',
        ],
        [
          $i * $per_batch,
          $per_batch,
          $fields,
          $field_value,
        ],
      ];
    }

    batch_set($batch);
  }

  /**
   * Writes formated product to CSV file.
   */
  public function putExportedProductsInCsv($start, $limit, $field_definitions, array $field_value) {
    $config = $this->smartImporterService->getConfig();
    if ($config['store'] != 'all') {
      $store = Store::load($config['store']);
      $name = $store->getName();
    } else {
      $name = $this->config('system.site')->get('name');
    }
    $file = fopen('temporary://export-' . str_replace(' ', '-', $name) . '.csv', 'a');
    $rows = $this->exportProducts($start, $limit, $field_definitions, $field_value);
    foreach ($rows as $row) {
      fputcsv($file, $row);
    }
    fclose($file);
  }

  /**
   * Export whole product to CSV fromatted.
   */
  public function exportProducts($start, $limit, $field_definitions, array $field_value) {

    $product_data = [];
    $config = $this->smartImporterService->getConfig();
    if (empty($field_value)) {
      $query = $this->database->select('commerce_product')
        ->fields('commerce_product', ['product_id'])
        ->condition('type', $config['commerce_product_bundle'])
        ->range($start, $limit)->execute()->fetchAll();
    }
    else {
      $query = $this->database->query("SELECT cp.product_id FROM commerce_product cp JOIN commerce_product__" . $field_value[0] . " tax ON tax.entity_id=cp.product_id WHERE tax." . $field_value[0] . "_target_id=" . $field_value[1])->fetchAll();
    }

    foreach ($query as $product) {
      $product_temp_data = [];
      $product_temp_data['product'] = $product->product_id;

      $variation_query = $this->database->query('SELECT variation_id FROM {commerce_product_variation_field_data} WHERE product_id=' . $product->product_id)
        ->fetchAll();
      foreach ($variation_query as $variation) {
        $product_temp_data['variation'][] = $variation->variation_id;
      }
      $product_data[] = $product_temp_data;
    }

    $empty_product = array_fill(0, count($field_definitions['product']), '');
    $rows = [];
    foreach ($product_data as $product_datum) {
      $first = TRUE;
      foreach ($product_datum['variation'] as $variation_id) {
        if ($first) {
          $temp_row = $this->smartImporterService->exportMultipleFields('commerce_product', $product_datum['product'], $field_definitions['product']);
          $first = FALSE;
        }
        else {
          $temp_row = $empty_product;
        }
        $temp_row = array_merge($temp_row, $this->smartImporterService->exportMultipleFields('commerce_product_variation', $variation_id, $field_definitions['variation']));
        $rows[] = $temp_row;
      }
    }
    return $rows;
  }

  /**
   * Checks if field is checked.
   */
  private function isFieldChecked(array $fields) {
    foreach ($fields as $field) {
      if (!empty($field)) {
        return TRUE;
      }
    }
    return FALSE;
  }

  /**
   * Unsets fields that are not checked.
   */
  private function leaveOnlyCheckedFields(&$fields, $field_list) {
    foreach ($fields['product'] as $key => $field) {
      if (!in_array($field['machine_names'], $field_list)) {
        unset($fields['product'][$key]);
      }
    }
    foreach ($fields['variation'] as $key => $field) {
      if (!in_array($field['machine_names'], $field_list)) {
        unset($fields['variation'][$key]);
      }
    }
  }

  /**
   * Downloads CSV.
   */
  public function downloadCsv() {
    $config = $this->smartImporterService->getConfig();
    if ($config['store'] != 'all') {
      $store = Store::load($config['store']);
      $name = $store->getName();
    } else {
      $name = $this->config('system.site')->get('name');
    }
    $filename = 'temporary://export-' . str_replace(' ', '-', $name) . '.csv';
    if (is_file($filename)) {
      $csv_file = file_get_contents($filename);
      header('Content-Description: File Transfer');
      header('Expires: 0');
      header('Cache-Control: must-revalidate');
      header('Pragma: public');
      header('Content-Type: application/csv');
      header("Content-length: " . filesize($filename));
      header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
      echo $csv_file;
      exit();
    }
    else {
      $this->messenger()->addStatus($this->t('Export first'));
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc