You are here

function uc_product_kit_form_node_form_alter in Ubercart 8.4

Implements hook_form_BASE_FORM_ID_alter() for node_form().

File

uc_product_kit/uc_product_kit.module, line 528
The product kit module for Ubercart.

Code

function uc_product_kit_form_node_form_alter(&$form, FormStateInterface $form_state) {
  $node = $form_state
    ->getFormObject()
    ->getEntity();
  if ($node
    ->getType() != 'product_kit') {
    return;
  }

  // Create an array of products on the site for use in the product selector.
  $products = [];
  $result = \Drupal::entityQuery('node')
    ->condition('type', uc_product_types(), 'IN')
    ->sort('title')
    ->execute();
  foreach ($result as $nid) {
    $product = Node::load($nid);
    $products[$nid] = $product
      ->label();
  }
  $form['base'] = [
    '#type' => 'details',
    '#title' => t('Product kit information'),
    '#weight' => 0,
    '#open' => TRUE,
  ];
  $form['base']['mutable'] = [
    '#type' => 'radios',
    '#title' => t('How is this product kit handled by the cart?'),
    '#options' => [
      UC_PRODUCT_KIT_UNMUTABLE_NO_LIST => t('As a unit. Customers may only change how many kits they are buying. Do not list component products.'),
      UC_PRODUCT_KIT_UNMUTABLE_WITH_LIST => t('As a unit. Customers may only change how many kits they are buying. List component products.'),
      UC_PRODUCT_KIT_MUTABLE => t('As individual products. Customers may add or remove kit components at will. Discounts entered below are not applied to the kit price'),
    ],
    '#default_value' => $node->mutable,
  ];
  $form['base']['products'] = [
    '#type' => 'select',
    '#multiple' => TRUE,
    '#required' => TRUE,
    '#title' => t('Products'),
    '#options' => $products,
    '#default_value' => array_keys($node->products),
  ];
  $total = 0;
  $base_total = 0;
  if (!empty($node->products)) {
    $form['base']['items'] = [
      '#type' => 'table',
      '#header' => [
        t('Product'),
        t('Quantity'),
        t('List position'),
        t('Discount'),
      ],
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'uc-product-kit-item-ordering',
        ],
      ],
      '#weight' => 1,
    ];
    $form['base']['help'] = [
      '#markup' => '<p>' . t('Enter a positive or negative discount to raise or lower the item price by that amount. The change is applied to each item in the kit.') . '</p>',
      '#weight' => 2,
    ];
    foreach ($node->products as $i => $product) {
      $form['base']['items'][$i]['#attributes']['class'][] = 'draggable';
      $form['base']['items'][$i]['link'] = [
        '#type' => 'link',
        '#title' => $product
          ->label(),
        '#url' => $product
          ->toUrl(),
      ];
      $form['base']['items'][$i]['qty'] = [
        '#type' => 'uc_quantity',
        '#title' => t('Quantity'),
        '#title_display' => 'invisible',
        '#default_value' => $product->qty,
      ];
      $form['base']['items'][$i]['ordering'] = [
        '#type' => 'weight',
        '#title' => t('List position'),
        '#title_display' => 'invisible',
        '#default_value' => isset($product->ordering) ? $product->ordering : 0,
        '#attributes' => [
          'class' => [
            'uc-product-kit-item-ordering',
          ],
        ],
      ];
      $form['base']['items'][$i]['discount'] = [
        '#type' => 'textfield',
        '#title' => t('Discount'),
        '#title_display' => 'invisible',
        '#field_prefix' => uc_currency_format($product->price->value) . ' + ',
        '#default_value' => isset($product->discount) ? number_format($product->discount, 3, '.', '') : 0,
        '#size' => 5,
      ];
      $total += $product->price->value * $product->qty;
      $base_total += $product->price->value * $product->qty;
      if (isset($product->discount)) {
        $base_total -= $product->discount * $product->qty;
      }
    }
    if (!$node->synchronized && $node->price->value != $total) {

      // Component products have changed their prices. Recalculate discounts
      // to keep the same total.
      $total = $base_total;
      foreach ($node->products as $i => $product) {
        $discount = ($node->price->value - $base_total) * $product->price->value / $base_total;
        $total += $discount * $product->qty;
        $form['base']['items'][$i]['discount']['#default_value'] = number_format($discount, 3, '.', '');
      }
    }
    $form['base']['kit_total'] = [
      '#type' => 'uc_price',
      '#title' => t('Total price'),
      '#default_value' => $node->synchronized ? '' : $total,
      '#description' => t('If this field is set, the discounts of the individual products will be recalculated to equal this value. Currently, the total price is %price.', [
        '%price' => uc_currency_format($total),
      ]),
      '#empty_zero' => FALSE,
    ];
  }

  // Disable all shipping related functionality.
  $form['shipping']['#access'] = FALSE;
  $form['#entity_builders'] = [
    'uc_product_kit_node_builder',
  ];
}