contacts_events-8.x-1.x-dev/modules/villages/src/Plugin/views/field/VillageRequirementsCheckboxListField.php
modules/villages/src/Plugin/views/field/VillageRequirementsCheckboxListField.php
<?php namespace Drupal\contacts_events_villages\Plugin\views\field; use Drupal\commerce_order\Entity\Order; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\Plugin\views\field\UncacheableFieldHandlerTrait; use Drupal\views\ResultRow; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Order balance views field hander. * * @ingroup views_field_handlers * * @ViewsField("contacts_events_village_requirements") */ class VillageRequirementsCheckboxListField extends FieldPluginBase { use UncacheableFieldHandlerTrait; /** * Cache of requirement taxonomy terms. * * @var array */ private static $requirements = []; /** * Entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->entityTypeManager = $entity_type_manager; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager') ); } /** * {@inheritdoc} */ public function query() { // No-op. } /** * {@inheritdoc} */ public function clickSortable() { return FALSE; } /** * {@inheritdoc} */ public function getValue(ResultRow $row, $field = NULL) { return '<!--form-item-' . $this->options['id'] . '--' . $row->index . '-->'; } /** * Form constructor for the views form. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ public function viewsForm(array &$form, FormStateInterface $form_state) { // Make sure we do not accidentally cache this form. $form['#cache']['max-age'] = 0; // The view is empty, abort. if (empty($this->view->result)) { unset($form['actions']); return; } if (empty(self::$requirements)) { $storage = $this->entityTypeManager->getStorage('taxonomy_term'); $query = $storage->getQuery(); $query->condition('vid', 'village_requirements'); $query->accessCheck(TRUE); /** @var \Drupal\taxonomy\Entity\Term $requirement */ foreach ($storage->loadMultiple($query->execute()) as $requirement) { self::$requirements[$requirement->id()] = $requirement->getName(); } } $form[$this->options['id']]['#tree'] = TRUE; foreach ($this->view->result as $row_index => $row) { /** @var \Drupal\commerce_order\Entity\Order $order */ $order = $this->getEntity($row); $existing_requirements = $this->getExistingRequirements($order); $form[$this->options['id']][$row_index] = [ '#type' => 'checkboxes', '#options' => self::$requirements, '#default_value' => $existing_requirements, ]; } } /** * Submit handler for the views form. * * @param array $form * An associative array containing the structure of the form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The current state of the form. */ public function viewsFormSubmit(array &$form, FormStateInterface $form_state) { // All the submitted requirements. // They will be in an array keyed by row index. // The array value will be an array containing all the selectable // requirements. The key will be the requirement ID. The value will be // either the requirement ID too (if selected), or integer 0 // (if not selected). $all_requirements = $form_state->getValue($this->options['id'], []); foreach ($all_requirements as $row_index => $order_requirements) { // Strip out requirements not selected. $requirements_to_select = array_filter(array_values($order_requirements), function ($r) { return $r !== 0; }); /** @var \Drupal\commerce_order\Entity\Order $order */ $order = $this->getEntity($this->view->result[$row_index]); $existing_requirements = $this->getExistingRequirements($order); if ($existing_requirements != $requirements_to_select) { $order->set('village_requirements', $requirements_to_select); $order->save(); } } $this->messenger()->addMessage($this->t('Changes have been saved.')); } /** * Gets the existing requirements on a booking as an array of IDs. * * @param \Drupal\commerce_order\Entity\Order $order * The order. * * @return array * Array of IDs. */ protected function getExistingRequirements(Order $order) { return $existing_requirements = array_map(function ($item) { return $item['target_id']; }, $order->get('village_requirements')->getValue()); } }