/web/core/lib/Drupal/Core/Config/Entity/DraggableListBuilder.php

https://gitlab.com/mohamed_hussein/prodt · PHP · 179 lines · 103 code · 20 blank · 56 comment · 12 complexity · 842fef77531608896b2e7b18e0af15a2 MD5 · raw file

  1. <?php
  2. namespace Drupal\Core\Config\Entity;
  3. use Drupal\Core\Entity\EntityInterface;
  4. use Drupal\Core\Entity\EntityStorageInterface;
  5. use Drupal\Core\Entity\EntityTypeInterface;
  6. use Drupal\Core\Form\FormInterface;
  7. use Drupal\Core\Form\FormStateInterface;
  8. /**
  9. * Defines a class to build a draggable listing of configuration entities.
  10. */
  11. abstract class DraggableListBuilder extends ConfigEntityListBuilder implements FormInterface {
  12. /**
  13. * The key to use for the form element containing the entities.
  14. *
  15. * @var string
  16. */
  17. protected $entitiesKey = 'entities';
  18. /**
  19. * The entities being listed.
  20. *
  21. * @var \Drupal\Core\Entity\EntityInterface[]
  22. */
  23. protected $entities = [];
  24. /**
  25. * Name of the entity's weight field or FALSE if no field is provided.
  26. *
  27. * @var string|bool
  28. */
  29. protected $weightKey = FALSE;
  30. /**
  31. * The form builder.
  32. *
  33. * @var \Drupal\Core\Form\FormBuilderInterface
  34. */
  35. protected $formBuilder;
  36. /**
  37. * {@inheritdoc}
  38. */
  39. public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage) {
  40. parent::__construct($entity_type, $storage);
  41. // Check if the entity type supports weighting.
  42. if ($this->entityType->hasKey('weight')) {
  43. $this->weightKey = $this->entityType->getKey('weight');
  44. }
  45. $this->limit = FALSE;
  46. }
  47. /**
  48. * {@inheritdoc}
  49. */
  50. public function buildHeader() {
  51. $header = [];
  52. if (!empty($this->weightKey)) {
  53. $header['weight'] = t('Weight');
  54. }
  55. return $header + parent::buildHeader();
  56. }
  57. /**
  58. * {@inheritdoc}
  59. */
  60. public function buildRow(EntityInterface $entity) {
  61. $row = [];
  62. if (!empty($this->weightKey)) {
  63. // Override default values to markup elements.
  64. $row['#attributes']['class'][] = 'draggable';
  65. $row['#weight'] = $entity->get($this->weightKey);
  66. // Add weight column.
  67. $row['weight'] = [
  68. '#type' => 'weight',
  69. '#title' => t('Weight for @title', ['@title' => $entity->label()]),
  70. '#title_display' => 'invisible',
  71. '#default_value' => $entity->get($this->weightKey),
  72. '#attributes' => ['class' => ['weight']],
  73. ];
  74. }
  75. return $row + parent::buildRow($entity);
  76. }
  77. /**
  78. * {@inheritdoc}
  79. */
  80. public function render() {
  81. if (!empty($this->weightKey)) {
  82. return $this->formBuilder()->getForm($this);
  83. }
  84. return parent::render();
  85. }
  86. /**
  87. * {@inheritdoc}
  88. */
  89. public function buildForm(array $form, FormStateInterface $form_state) {
  90. $form[$this->entitiesKey] = [
  91. '#type' => 'table',
  92. '#header' => $this->buildHeader(),
  93. '#empty' => t('There are no @label yet.', ['@label' => $this->entityType->getPluralLabel()]),
  94. '#tabledrag' => [
  95. [
  96. 'action' => 'order',
  97. 'relationship' => 'sibling',
  98. 'group' => 'weight',
  99. ],
  100. ],
  101. ];
  102. $this->entities = $this->load();
  103. $delta = 10;
  104. // Change the delta of the weight field if have more than 20 entities.
  105. if (!empty($this->weightKey)) {
  106. $count = count($this->entities);
  107. if ($count > 20) {
  108. $delta = ceil($count / 2);
  109. }
  110. }
  111. foreach ($this->entities as $entity) {
  112. $row = $this->buildRow($entity);
  113. if (isset($row['label'])) {
  114. $row['label'] = ['#plain_text' => $row['label']];
  115. }
  116. if (isset($row['weight'])) {
  117. $row['weight']['#delta'] = $delta;
  118. }
  119. $form[$this->entitiesKey][$entity->id()] = $row;
  120. }
  121. $form['actions']['#type'] = 'actions';
  122. $form['actions']['submit'] = [
  123. '#type' => 'submit',
  124. '#value' => t('Save'),
  125. '#button_type' => 'primary',
  126. ];
  127. return $form;
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. public function validateForm(array &$form, FormStateInterface $form_state) {
  133. // No validation.
  134. }
  135. /**
  136. * {@inheritdoc}
  137. */
  138. public function submitForm(array &$form, FormStateInterface $form_state) {
  139. foreach ($form_state->getValue($this->entitiesKey) as $id => $value) {
  140. if (isset($this->entities[$id]) && $this->entities[$id]->get($this->weightKey) != $value['weight']) {
  141. // Save entity only when its weight was changed.
  142. $this->entities[$id]->set($this->weightKey, $value['weight']);
  143. $this->entities[$id]->save();
  144. }
  145. }
  146. }
  147. /**
  148. * Returns the form builder.
  149. *
  150. * @return \Drupal\Core\Form\FormBuilderInterface
  151. * The form builder.
  152. */
  153. protected function formBuilder() {
  154. if (!$this->formBuilder) {
  155. $this->formBuilder = \Drupal::formBuilder();
  156. }
  157. return $this->formBuilder;
  158. }
  159. }