class PaymentLineItemsInput in Payment 8.2
Provides a payment line items configuration element.
Plugin annotation
@FormElement("payment_line_items_input");
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\Core\Render\Element\RenderElement implements ElementInterface
- class \Drupal\Core\Render\Element\FormElement implements FormElementInterface
- class \Drupal\payment\Element\PaymentLineItemsInput implements ContainerFactoryPluginInterface uses FormElementCallbackTrait
- class \Drupal\Core\Render\Element\FormElement implements FormElementInterface
- class \Drupal\Core\Render\Element\RenderElement implements ElementInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of PaymentLineItemsInput
3 files declare their use of PaymentLineItemsInput
- PaymentLineItemElement.php in modules/
payment_test/ src/ PaymentLineItemElement.php - PaymentLineItemsInputTest.php in tests/
src/ Unit/ Element/ PaymentLineItemsInputTest.php - PaymentReference.php in modules/
payment_reference/ src/ Plugin/ Field/ FieldType/ PaymentReference.php
3 #type uses of PaymentLineItemsInput
- PaymentForm::formElementProcess in modules/
payment_form/ src/ Plugin/ Field/ FieldWidget/ PaymentForm.php - Implements form API #process callback.
- PaymentLineItemElement::buildForm in modules/
payment_test/ src/ PaymentLineItemElement.php - Form constructor.
- PaymentReference::fieldSettingsForm in modules/
payment_reference/ src/ Plugin/ Field/ FieldType/ PaymentReference.php - Returns a form for the field-level settings.
File
- src/
Element/ PaymentLineItemsInput.php, line 26
Namespace
Drupal\payment\ElementView source
class PaymentLineItemsInput extends FormElement implements ContainerFactoryPluginInterface {
use FormElementCallbackTrait;
/**
* An unlimited cardinality.
*/
const CARDINALITY_UNLIMITED = -1;
/**
* The payment line item manager.
*
* @var \Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemManagerInterface
*/
protected $paymentLineItemManager;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Creates a new instance.
*
* @param mixed[] $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
* @param \Drupal\Core\Render\RendererInterface $renderer
* @param \Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemManagerInterface $payment_line_item_manager
*/
public function __construct(array $configuration, $plugin_id, array $plugin_definition, TranslationInterface $string_translation, RendererInterface $renderer, PaymentLineItemManagerInterface $payment_line_item_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->paymentLineItemManager = $payment_line_item_manager;
$this->renderer = $renderer;
$this->stringTranslation = $string_translation;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('string_translation'), $container
->get('renderer'), $container
->get('plugin.manager.payment.line_item'));
}
/**
* {@inheritdoc}
*/
public function getInfo() {
$plugin_id = $this
->getPluginId();
return array(
// The number of values this element allows, which must be at least as
// many as the number of line items in the default value. For unlimited
// values, use
// \Drupal\payment\Element\PaymentLineItemsInput::CARDINALITY_UNLIMITED.
'#cardinality' => self::CARDINALITY_UNLIMITED,
// An array of
// \Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemInterface
// objects (required).
'#default_value' => [],
// A \Drupal\payment\Entity\PaymentInterface object (optional).
'#payment' => NULL,
'#process' => [
[
get_class($this),
'instantiate#process#' . $plugin_id,
],
],
);
}
/**
* Implements form #process callback.
*/
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;
}
/**
* Implements form #element_validate callback.
*/
public static function validate(array $element, FormStateInterface $form_state, array &$form) {
// Reorder line items based on their weight elements.
$line_items = [];
$values = $form_state
->getValues();
$values = NestedArray::getValue($values, $element['#parents']);
if ($values['line_items']) {
foreach ($values['line_items'] as $name => $line_item_values) {
$line_items[$name] = $line_item_values['weight'];
}
asort($line_items);
foreach (static::getLineItems($element, $form_state) as $line_item) {
$line_items[$line_item
->getName()] = $line_item;
$line_item
->validateConfigurationForm($element['line_items'][$line_item
->getName()]['plugin_form'], $form_state);
// @todo Don't call the submit handler if plugin validation failed.
$line_item
->submitConfigurationForm($element['line_items'][$line_item
->getName()]['plugin_form'], $form_state);
}
static::setLineItems($element, $form_state, array_values($line_items));
}
}
/**
* Implements form #submit callback.
*/
public static function addMoreSubmit(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$parents = array_slice($triggering_element['#array_parents'], 0, -2);
$root_element = NestedArray::getValue($form, $parents);
$values = $form_state
->getValues();
$values = NestedArray::getValue($values, array_slice($triggering_element['#parents'], 0, -2));
$line_item = \Drupal::service('plugin.manager.payment.line_item')
->createInstance($values['add_more']['type']);
$line_item
->setName(static::createLineItemName($root_element, $form_state, $values['add_more']['type']));
$line_items = static::getLineItems($root_element, $form_state);
$line_items[] = $line_item;
static::setLineItems($root_element, $form_state, $line_items);
$form_state
->setRebuild();
}
/**
* Implements form AJAX callback.
*/
public static function ajaxAddMoreSubmit(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$parents = array_slice($triggering_element['#array_parents'], 0, -2);
$element = NestedArray::getValue($form, $parents);
return $element;
}
/**
* Implements form #submit callback.
*/
public static function deleteSubmit(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$root_element_parents = array_slice($triggering_element['#array_parents'], 0, -3);
$root_element = NestedArray::getValue($form, $root_element_parents);
$parents = $triggering_element['#array_parents'];
$line_item_name = $parents[count($parents) - 2];
/** @var \Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemInterface[] $line_items */
$line_items = array_values(static::getLineItems($root_element, $form_state));
foreach ($line_items as $i => $line_item) {
if ($line_item
->getName() == $line_item_name) {
unset($line_items[$i]);
}
}
static::setLineItems($root_element, $form_state, $line_items);
$form_state
->setRebuild();
}
/**
* Implements form AJAX callback.
*/
public static function ajaxDeleteSubmit(array &$form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$root_element_parents = array_slice($triggering_element['#array_parents'], 0, -3);
$root_element = NestedArray::getValue($form, $root_element_parents);
$parents = $triggering_element['#array_parents'];
$line_item_name = $parents[count($parents) - 2];
$response = new AjaxResponse();
$response
->addCommand(new RemoveCommand('#' . $root_element['#id'] . ' .payment-line-item-name-' . $line_item_name));
return $response;
}
/**
* Creates a unique line item name.
*
* @param mixed[] $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param string $name
* The preferred name.
*
* @return string
*/
protected static function createLineItemName(array $element, FormStateInterface $form_state, $name) {
$counter = NULL;
while (static::lineItemExists($element, $form_state, $name . $counter)) {
$counter++;
}
return $name . $counter;
}
/**
* Checks if a line item name already exists.
*
* @param mixed[] $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param string $name
*
* @return bool
*/
protected static function lineItemExists(array $element, FormStateInterface $form_state, $name) {
foreach (static::getLineItems($element, $form_state) as $line_item) {
if ($line_item
->getName() == $name) {
return TRUE;
}
}
return FALSE;
}
/**
* Stores the line items in the form's state.
*
* @param mixed[] $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
* @param \Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemInterface[] $line_items
*/
protected static function setLineItems(array $element, FormStateInterface $form_state, array $line_items) {
$form_state
->set('payment.element.payment_line_items_input.configured.' . $element['#name'], $line_items);
}
/**
* Retrieves the line items from the form's state.
*
* @param mixed[] $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return \Drupal\payment\Plugin\Payment\LineItem\PaymentLineItemInterface[]
*/
public static function getLineItems(array $element, FormStateInterface $form_state) {
$key = 'payment.element.payment_line_items_input.configured.' . $element['#name'];
return $form_state
->has($key) ? $form_state
->get($key) : [];
}
/**
* Gets the root element's HTML ID.
*
* @param mixed[] $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return string
*/
protected static function getElementId(array $element, FormStateInterface $form_state) {
return Html::getId('payment-element-payment_line_items_input--' . implode('-', $element['#parents']));
}
/**
* Initializes stored line items.
*
* @param mixed[] $element
* @param \Drupal\Core\Form\FormStateInterface $form_state
*
* @return bool
*/
protected static function initializeLineItems(array $element, FormStateInterface $form_state) {
if (!$form_state
->has('payment.element.payment_line_items_input.configured.' . $element['#name'])) {
static::setLineItems($element, $form_state, $element['#default_value']);
}
}
/**
* {@inheritdoc}
*/
public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
static::initializeLineItems($element, $form_state);
return static::getLineItems($element, $form_state);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormElement:: |
public static | function | Adds autocomplete functionality to elements. | |
FormElement:: |
public static | function | #process callback for #pattern form element property. | |
FormElement:: |
public static | function | #element_validate callback for #pattern form element property. | |
FormElementCallbackTrait:: |
public static | function | Instantiates this class as a plugin and calls a method on it. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PaymentLineItemsInput:: |
protected | property | The payment line item manager. | |
PaymentLineItemsInput:: |
protected | property | The renderer. | |
PaymentLineItemsInput:: |
public static | function | Implements form #submit callback. | |
PaymentLineItemsInput:: |
public static | function | Implements form AJAX callback. | |
PaymentLineItemsInput:: |
public static | function | Implements form AJAX callback. | |
PaymentLineItemsInput:: |
constant | An unlimited cardinality. | ||
PaymentLineItemsInput:: |
public static | function |
Creates an instance of the plugin. Overrides ContainerFactoryPluginInterface:: |
|
PaymentLineItemsInput:: |
protected static | function | Creates a unique line item name. | |
PaymentLineItemsInput:: |
public static | function | Implements form #submit callback. | |
PaymentLineItemsInput:: |
protected static | function | Gets the root element's HTML ID. | |
PaymentLineItemsInput:: |
public | function |
Returns the element properties for this element. Overrides ElementInterface:: |
|
PaymentLineItemsInput:: |
public static | function | Retrieves the line items from the form's state. | |
PaymentLineItemsInput:: |
protected static | function | Initializes stored line items. | |
PaymentLineItemsInput:: |
protected static | function | Checks if a line item name already exists. | |
PaymentLineItemsInput:: |
public | function | Implements form #process callback. | |
PaymentLineItemsInput:: |
protected static | function | Stores the line items in the form's state. | |
PaymentLineItemsInput:: |
public static | function | Implements form #element_validate callback. | |
PaymentLineItemsInput:: |
public static | function |
Determines how user input is mapped to an element's #value property. Overrides FormElement:: |
|
PaymentLineItemsInput:: |
public | function |
Creates a new instance. Overrides PluginBase:: |
|
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
RenderElement:: |
public static | function | Adds Ajax information about an element to communicate with JavaScript. | |
RenderElement:: |
public static | function | Adds members of this group as actual elements for rendering. | |
RenderElement:: |
public static | function | Form element processing handler for the #ajax form property. | 1 |
RenderElement:: |
public static | function | Arranges elements into groups. | |
RenderElement:: |
public static | function |
Sets a form element's class attribute. Overrides ElementInterface:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |