You are here

public function PaymentLineItemsInput::process in Payment 8.2

Implements form #process callback.

File

src/Element/PaymentLineItemsInput.php, line 101

Class

PaymentLineItemsInput
Provides a payment line items configuration element.

Namespace

Drupal\payment\Element

Code

public function process(array $element, FormStateInterface $form_state, array $form) {
  $plugin_id = $this
    ->getPluginId();

  // Set internal configuration.
  $element += array(
    '#value' => [],
  );
  $element['#payment_line_items'] = static::getLineItems($element, $form_state);
  $element['#element_validate'] = array(
    function (array &$element, FormStateInterface $form_state, array &$form) use ($plugin_id) {

      /** @var \Drupal\Component\Plugin\PluginManagerInterface $element_info_manager */
      $element_info_manager = \Drupal::service('plugin.manager.element_info');

      /** @var \Drupal\payment\Element\PaymentLineItemsInput $element_plugin */
      $element_plugin = $element_info_manager
        ->createInstance($plugin_id);
      $element_plugin
        ->validate($element, $form_state, $form);
    },
  );
  $element['#tree'] = TRUE;
  $element['#id'] = $this
    ->getElementId($element, $form_state);
  $element['#theme_wrappers'] = array(
    'container',
  );

  // Validate the element configuration.
  if ($element['#cardinality'] != self::CARDINALITY_UNLIMITED && count($element['#default_value']) > $element['#cardinality']) {
    throw new \InvalidArgumentException('The number of default line items can not be higher than the cardinality.');
  }
  foreach ($element['#default_value'] as $line_item) {
    if (!$line_item instanceof PaymentLineItemInterface) {
      throw new \InvalidArgumentException('A default line item does not implement \\Drupal\\payment\\Plugin\\Payment\\LineItem\\PaymentLineItemInterface.');
    }
  }
  static::initializeLineItems($element, $form_state);
  $line_items = static::getLineItems($element, $form_state);

  // Build the line items.
  $element['line_items'] = array(
    '#empty' => $this
      ->t('There are no line items yet.'),
    '#header' => array(
      array(
        'data' => $this
          ->t('Name'),
        'class' => array(
          RESPONSIVE_PRIORITY_MEDIUM,
        ),
      ),
      array(
        'data' => $this
          ->t('Type'),
        'class' => array(
          RESPONSIVE_PRIORITY_LOW,
        ),
      ),
      $this
        ->t('Configuration'),
      $this
        ->t('Weight'),
      $this
        ->t('Operations'),
    ),
    '#tabledrag' => array(
      array(
        'action' => 'order',
        'relationship' => 'self',
        'group' => 'payment-line-item-weight',
      ),
    ),
    '#type' => 'table',
    '#tree' => TRUE,
  );
  foreach ($line_items as $delta => $line_item) {
    $element['line_items'][$line_item
      ->getName()] = array(
      '#attributes' => array(
        'class' => array(
          'payment-line-item',
          'payment-line-item-name-' . $line_item
            ->getName(),
          'payment-line-item-plugin-' . $line_item
            ->getPluginId(),
        ),
      ),
    );
    $element['line_items'][$line_item
      ->getName()]['name'] = array(
      '#markup' => $line_item
        ->getName(),
    );
    $line_item_definition = $line_item
      ->getPluginDefinition();
    $element['line_items'][$line_item
      ->getName()]['type'] = array(
      '#markup' => $line_item_definition['label'],
    );
    $element['line_items'][$line_item
      ->getName()]['plugin_form'] = $line_item
      ->buildConfigurationForm([], $form_state);
    $element['line_items'][$line_item
      ->getName()]['weight'] = array(
      '#attributes' => array(
        'class' => array(
          'payment-line-item-weight',
        ),
      ),
      '#default_value' => $delta,
      '#delta' => count($line_items) * 2,
      '#title' => $this
        ->t('Weight'),
      '#type' => 'weight',
    );
    $element['line_items'][$line_item
      ->getName()]['delete'] = array(
      '#ajax' => array(
        'callback' => array(
          get_class($this),
          'ajaxDeleteSubmit',
        ),
        'effect' => 'fade',
        'event' => 'mousedown',
      ),
      '#limit_validation_errors' => [],
      '#submit' => array(
        array(
          get_class($this),
          'deleteSubmit',
        ),
      ),
      '#type' => 'submit',
      '#value' => $this
        ->t('Delete'),
      // Fixes https://www.drupal.org/project/drupal/issues/2546700.
      '#name' => 'delete_' . implode('-', $element['#parents']) . '_' . $line_item
        ->getName(),
    );
  }

  // "Add more line items" button.
  $element['add_more'] = array(
    '#access' => $element['#cardinality'] == self::CARDINALITY_UNLIMITED || count($line_items) < $element['#cardinality'],
    '#attributes' => array(
      'class' => array(
        'payment-add-more',
      ),
    ),
    '#type' => 'container',
  );
  $options = [];
  foreach ($this->paymentLineItemManager
    ->getDefinitions() as $line_item_plugin_id => $line_item_definition) {
    $options[$line_item_plugin_id] = $line_item_definition['label'];
  }
  natcasesort($options);
  $element['add_more']['type'] = array(
    '#options' => $options,
    '#title' => $this
      ->t('Type'),
    '#type' => 'select',
  );
  $element['add_more']['add'] = array(
    '#ajax' => array(
      'callback' => [
        get_class($this),
        'instantiate#ajaxAddMoreSubmit#' . $plugin_id,
      ],
      'effect' => 'fade',
      'event' => 'mousedown',
      'wrapper' => $element['#id'],
    ),
    '#limit_validation_errors' => array(
      array_merge($element['#parents'], array(
        'add_more',
        'type',
      )),
    ),
    '#submit' => [
      [
        get_class($this),
        'addMoreSubmit',
      ],
    ],
    '#type' => 'submit',
    '#value' => $this
      ->t('Add and configure a new line item'),
    // Fixes https://www.drupal.org/project/drupal/issues/2546700.
    '#name' => 'add_' . implode('-', $element['#parents']),
  );
  return $element;
}