Paragraphs Editor
BundleListSelector.php
Go to the documentation of this file.
1 <?php
2 
4 
13 
14 /**
15  * Provides a simple listing of bundles to choose from.
16  *
17  * @ParagraphsEditorBundleSelector(
18  * id = "list",
19  * title = @Translation("List"),
20  * description = @Translation("Provides a basic list of bundles."),
21  * )
22  */
23 class BundleListSelector extends EntityListBuilder implements BundleSelectorInterface, ContainerFactoryPluginInterface {
24 
25  /**
26  * The plugin id for this plugin.
27  *
28  * @var string
29  */
30  protected $pluginId;
31 
32  /**
33  * The plugin definition for this plugin.
34  *
35  * @var object
36  */
37  protected $pluginDefinition;
38 
39  /**
40  * The command context the plugin is executing within.
41  *
42  * @var \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface
43  */
44  protected $context;
45 
46  /**
47  * The number of bundles to show on a page.
48  *
49  * @var int
50  */
51  protected $limit = 15;
52 
53  /**
54  * Creates a bundle selector form object.
55  *
56  * @param string $plugin_id
57  * The bundle selector plugin id.
58  * @param mixed $plugin_definition
59  * The bundle selector plugin definition.
60  * @param \Drupal\paragraphs_editor\EditorCommand\CommandContextInterface $context
61  * The editor command context to build the bundle form for.
62  * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
63  * The entity type manager service.
64  */
65  public function __construct($plugin_id, $plugin_definition, CommandContextInterface $context, EntityTypeManagerInterface $entity_type_manager) {
66  parent::__construct($entity_type_manager->getDefinition('paragraphs_type'), $entity_type_manager->getStorage('paragraphs_type'));
67  $this->pluginId = $plugin_id;
68  $this->pluginDefinition = $plugin_definition;
69  $this->context = $context;
70  }
71 
72  /**
73  * {@inheritdoc}
74  */
75  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
76  return new static(
77  $plugin_id,
78  $plugin_definition,
79  $configuration['context'],
80  $container->get('entity_type.manager')
81  );
82  }
83 
84  /**
85  * {@inheritdoc}
86  */
87  public function getFormId() {
88  return 'paragraphs_editor_bundle_list_builder';
89  }
90 
91  /**
92  * {@inheritdoc}
93  */
94  public function buildForm(array $form, FormStateInterface $form_state) {
95  $form['search_container'] = [
96  '#type' => 'container',
97  '#attributes' => [
98  'class' => [
99  'paragraphs-editor-bundle-selector-search',
100  ],
101  ],
102  '#attached' => [
103  'library' => [
104  'paragraphs_editor/core',
105  ],
106  ],
107  ];
108  $form['search_container']['search'] = [
109  '#title' => $this->t('Search'),
110  '#type' => 'textfield',
111  '#attributes' => [
112  'class' => [
113  'paragraphs-editor-bundle-selector-search__input',
114  ],
115  'autocomplete' => 'off',
116  ],
117  ];
118  $form['search_container']['search_button'] = [
119  '#type' => 'submit',
120  '#value' => 'Search',
121  '#submit' => [],
122  '#limit_validation_errors' => [],
123  '#ajax' => [
124  'callback' => [get_class($this), 'ajaxSearch'],
125  'wrapper' => 'paragraphs-editor-bundle-selector-options',
126  ],
127  '#attributes' => [
128  'class' => [
129  'paragraphs-editor-bundle-selector-search__submit',
130  'visually-hidden',
131  ],
132  ],
133  ];
134  $form['options'] = [
135  '#prefix' => '<div id="paragraphs-editor-bundle-selector-options">',
136  '#suffix' => '</div>',
137  '#type' => 'table',
138  '#header' => $this->buildHeader(),
139  '#empty' => t('Could not find any matching options.', ['@label' => $this->entityType->getLabel()]),
140  ];
141 
142  $input = $form_state->getUserInput();
143  $search = isset($input['search']) ? $input['search'] : '';
144  $search = trim(preg_replace('/\(.*\)$/', '', $search));
145  $entities = $this->load($search);
146  foreach ($entities as $entity) {
147  $row = $this->buildRow($entity);
148  if (isset($row['label'])) {
149  $row['label'] = ['#markup' => $row['label']];
150  }
151  $form['options'][$entity->id()] = $row;
152  }
153 
154  $form['cancel'] = [
155  '#type' => 'link',
156  '#title' => $this->t('Cancel'),
157  '#url' => $this->context->createCommandUrl('cancel'),
158  '#attributes' => [
159  'class' => [
160  'button',
161  'use-ajax',
162  ],
163  ],
164  ];
165 
166  return $form;
167  }
168 
169  /**
170  * Callback for handling the search box updates over ajax.
171  *
172  * @param array $form
173  * The regenerated form.
174  * @param \Drupal\Core\FOrm\FormStateInterface $form_state
175  * The form state.
176  *
177  * @return array
178  * The portion of the form to deliver.
179  */
180  public static function ajaxSearch(array $form, FormStateInterface $form_state) {
181  return $form['options'];
182  }
183 
184  /**
185  * {@inheritdoc}
186  */
187  public function buildHeader() {
188  $header = [];
189  $header['label'] = t('Type');
190  $header['operations'] = '';
191  return $header;
192  }
193 
194  /**
195  * {@inheritdoc}
196  */
197  public function buildRow(EntityInterface $entity) {
198  $row = [];
199  $row['label'] = $entity->label();
200  return $row + parent::buildRow($entity);
201  }
202 
203  /**
204  * {@inheritdoc}
205  */
206  public function buildOperations(EntityInterface $entity) {
207  // Create an ajax link that will take the user to an 'insert' endpoint for
208  // the bundle the operation relates to.
209  $build = [];
210  $build['add'] = [
211  '#type' => 'link',
212  '#title' => t('Add'),
213  '#url' => $this->context->createCommandUrl('insert', [
214  'bundle_name' => $entity->id(),
215  ]),
216  '#attributes' => [
217  'class' => [
218  'button',
219  'use-ajax',
220  ],
221  ],
222  ];
223  return $build;
224  }
225 
226  /**
227  * {@inheritdoc}
228  */
229  public function validateForm(array &$form, FormStateInterface $form_state) {
230  // This needs to be implemented, but we don't have anything to validate.
231  }
232 
233  /**
234  * {@inheritdoc}
235  */
236  public function submitForm(array &$form, FormStateInterface $form_state) {
237  // This needs to be implemented, but we don't have anything to submit.
238  }
239 
240  /**
241  * {@inheritdoc}
242  */
243  public function load($search = NULL) {
244  $entity_ids = $this->getEntityIds($search);
245  $entities = $this->storage->loadMultiple($entity_ids);
246 
247  // Sort the entities using the entity class's sort() method.
248  // See \Drupal\Core\Config\Entity\ConfigEntityBase::sort().
249  uasort($entities, [$this->entityType->getClass(), 'sort']);
250  return $entities;
251  }
252 
253  /**
254  * {@inheritdoc}
255  */
256  protected function getEntityIds($search = NULL) {
257  $query = $this->getStorage()->getQuery()
258  ->sort($this->entityType->getKey('id'));
259 
260  if ($search) {
261  $query->condition('label', $search, 'CONTAINS');
262  }
263 
264  $this->context->getBundleFilter()->filterQuery($query);
265 
266  // Only add the pager if a limit is specified.
267  if ($this->limit) {
268  $query->pager($this->limit);
269  }
270  $results = $query->execute();
271  return is_array($results) ? $results : [];
272  }
273 
274 }
__construct($plugin_id, $plugin_definition, CommandContextInterface $context, EntityTypeManagerInterface $entity_type_manager)
static create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition)