Loading commerce_product_bulk_variations.info.yml 0 → 100644 +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' commerce_product_bulk_variations.module 0 → 100644 +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: } } commerce_product_bulk_variations.routing.yml 0 → 100644 +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 src/Form/GenerateVariationsForm.php 0 → 100644 +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'); } } Loading
commerce_product_bulk_variations.info.yml 0 → 100644 +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'
commerce_product_bulk_variations.module 0 → 100644 +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: } }
commerce_product_bulk_variations.routing.yml 0 → 100644 +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
src/Form/GenerateVariationsForm.php 0 → 100644 +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'); } }