Commit 7997ee4a authored by Taggart Jensen's avatar Taggart Jensen
Browse files

add the things

parents
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
name: 'commerce_product_bulk_variations'
type: module
description: 'Allow for Bulk bulk_variations'
core: 8.x
package: 'Custom'
+24 −0
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Contains commerce_product_bulk_variations.module.
 */

use Drupal\Core\Routing\RouteMatchInterface;

/**
 * Implements hook_help().
 */
function commerce_product_bulk_variations_help($route_name, RouteMatchInterface $route_match) {
  switch ($route_name) {
    // Main module help for the commerce_product_bulk_variations module.
    case 'help.page.commerce_product_bulk_variations':
      $output = '';
      $output .= '<h3>' . t('About') . '</h3>';
      $output .= '<p>' . t('Allow for Bulk bulk_variations') . '</p>';
      return $output;

    default:
  }
}
+11 −0
Original line number Diff line number Diff line
commerce_product_bulk_variations.commerse_generate_variations_form:
  path: '/product/{commerce_product}/variations/{commerce_product_variation}/bulk-generate'
  defaults:
    _form: '\Drupal\commerce_product_bulk_variations\Form\GenerateVariationsForm'
    _title: 'Generate Bulk Product Variations'
  requirements:
    _permission: 'administer commerce_product_type'
  options:
    _admin_route: 1

+259 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\commerce_product_bulk_variations\Form;

use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Class GenerateVariationsForm.
 */
class GenerateVariationsForm extends FormBase {

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

  /**
   * Symfony\Component\DependencyInjection\ContainerAwareInterface definition.
   *
   * @var \Symfony\Component\DependencyInjection\ContainerAwareInterface
   */
  protected $entityQuery;

  /**
   * The request stack.
   *
   * @var \Symfony\Component\HttpFoundation\RequestStack
   */
  protected $requestStack;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    $instance = parent::create($container);
    $instance->entityTypeManager = $container->get('entity_type.manager');
    $instance->entityQuery = $container->get('entity.query');
    $instance->requestStack = $container->get('request_stack');
    return $instance;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'commerse_generate_variations_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $request = $this->requestStack->getCurrentRequest()->attributes;
    $commerce_product_id = $request->get('commerce_product');
    $commerce_product_variation_id = $request->get('commerce_product_variation');
    if (!empty($commerce_product_variation_id) && !empty($commerce_product_id)) {
      $commerce_product_variation = $this->entityTypeManager->getStorage('commerce_product_variation')->load($commerce_product_variation_id);
      // Ok well we now have every thing we need.
      $commerce_product  = $commerce_product_variation->product_id->entity;
      $form_state->set('commerce_product_variation', $commerce_product_variation);

      $all_combos = $this->getCombos($commerce_product, $commerce_product_variation);
      $existing_variations = $commerce_product->variations->referencedEntities();
      if (count($existing_variations) != 0) {
        $all_combos['count'] = $all_combos['count'] - count($existing_variations);
        $existing_var_values = [];
        $field_names = $this->getAttributeFieldNames($commerce_product);
        foreach ($existing_variations as $p_variation) {
          $value = [];
          $value[$p_variation->id()] = [];
          foreach ($field_names as $fname) {
            if (!empty($p_variation->{$fname}->target_id)) {
              $existing_var_values[$p_variation->id()][$fname] = $p_variation->{$fname}->target_id;
            }
          }
        }

        if (!empty($existing_var_values)) {
          foreach ($all_combos['combinations'] as $key => $field_array) {
            foreach ($existing_var_values as $f_array_values) {
              if ($field_array['attribute_size'] == $f_array_values['attribute_size'] && $field_array['attribute_color'] == $f_array_values['attribute_color']) {
                unset($all_combos['combinations'][$key]);
              }
            }
          }
        }

        if ($all_combos['count'] != 0) {
          $form_state->set('all_combos', $all_combos);

          $form['info'] = [
            '#markup' => t('<h2> Submit this form to bulk generate @count Variations</h2>', [
              '@count' => $all_combos['count'],
            ])
          ];
          $form['submit'] = [
            '#type' => 'submit',
            '#value' => $this->t('Submit'),
          ];
        }
      }
      else {
        $form['info'] = [
          '#markup' => t('<h2> Please create at least one variation </h2>'),
        ];
      }
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    foreach ($form_state->getValues() as $key => $value) {
      // @TODO: Validate fields.
    }
    parent::validateForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $commerce_product_variation = $form_state->get('commerce_product_variation');
    $commerce_product = $commerce_product_variation->product_id->entity;
    if (!empty($commerce_product_variation) && !empty($commerce_product)) {
      // Check combos.
      $all_combos = $form_state->get('all_combos');
      foreach ($all_combos['combinations'] as $combo) {
        $timestamp = time();
        $variation = $commerce_product_variation->createDuplicate()
          ->set('variation_id', NULL)
          ->setSku($this->getUniqSku())
          ->setChangedTime($timestamp)
          ->setCreatedTime($timestamp);
        foreach ($combo as $field_name => $id) {
          $variation->get($field_name)->setValue(['target_id' => $id == '_none' ? NULL : $id]);
        }
        $variation->updateOriginalValues();

        $variation->save();
      }
    }
  }


  public static function getUniqSku() {
      return \uniqid('sku-');
  }

  /**
   * Method to get all possable variations.
   *
   * @param $commerce_product
   * @param $commerce_product_variation
   * @return array
   */
  public function getCombos($commerce_product, $commerce_product_variation) {
    $field_names = $this->getAttributeFieldNames($commerce_product);
    $option_ids = $this->getAttributeFieldOptionIds($commerce_product, $commerce_product_variation);

    $combinations = $this->getArrayValueCombinations($option_ids['ids']);
    $field_names = array_values($field_names);
    $all = [];
    foreach ($combinations as $combination) {
      array_walk($combination, function (&$id) {$id = (string) $id;});
      $all['combinations'][] = array_combine($field_names, $combination);
    }
    $all['count'] = count($combinations);
    return $all;
  }


  /**
   * Gets all ids combinations of the commerce_product's attribute fields.
   *
   * @return array
   *   An array of ids combinations and combinations quantity.
   */
  public function getAttributesCombinations() {
    $combinations = $this->getArrayValueCombinations($this->getAttributeFieldOptionIds()['ids']);
    $field_names = array_values($this->getAttributeFieldNames());
    $all = [];
    foreach ($combinations as $combination) {
      array_walk($combination, function (&$id) {$id = (string) $id;});
      $all['combinations'][] = array_combine($field_names, $combination);
    }
    $all['count'] = count($combinations);
    return $all;
  }




  /**
   * Gets combinations of an Array values.
   *
   *
   * @param array $data
   *   An array with mixed data.
   *
   * @return array
   *   An array of all possible array values combinations.
   */
  protected function getArrayValueCombinations(array $data = array(), array &$all = array(), array $group = array(), $value = null, $i = 0) {
    $keys = array_keys($data);
    if (isset($value) === TRUE) {
      array_push($group, $value);
    }
    if ($i >= count($data)) {
      array_push($all, $group);
    }
    elseif (isset($keys[$i])) {
      $currentKey = $keys[$i];
      $currentElement = $data[$currentKey];
      foreach ($currentElement as $key => $val) {
        $this->getArrayValueCombinations($data, $all, $group, $val, $i + 1);
      }
    }

    return $all;
  }

  /**
   * Gets the Ids of the variation's attribute fields.
   *
   * @return array
   *   An array of Ids arrays keyed by field name.
   */
  public function getAttributeFieldOptionIds($entity, $variation) {
    $field_options = $ids = $fields = [];
    foreach ($this->getAttributeFieldNames($entity) as $field_name) {
      $definition = $variation->get($field_name)->getFieldDefinition();
      $fields[$field_name] = $definition->getFieldStorageDefinition()
        ->getOptionsProvider('target_id', $variation)
        ->getSettableOptions(\Drupal::currentUser());
      $ids[$field_name] = array_keys($fields[$field_name]);
      // Optional fields need '_none' id as a possible choice.
      !$definition->isRequired() && array_unshift($ids[$field_name], '_none');
    }
    $field_options['ids'] = $ids;
    $field_options['options'] = $fields;

    return $field_options;
  }

  public function getAttributeFieldNames($entity) {
    $attribute_field_manager = \Drupal::service('commerce_product.attribute_field_manager');
    $field_map = $attribute_field_manager->getFieldMap($entity->bundle());
    return array_column($field_map, 'field_name');
  }

}