IFrame::displayEntityBrowser()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 58
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 42
nc 1
nop 4
dl 0
loc 58
rs 9.639
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Drupal\entity_browser\Plugin\EntityBrowser\Display;
4
5
use Drupal\Component\Uuid\UuidInterface;
6
use Drupal\Core\Entity\EntityInterface;
7
use Drupal\Core\Form\FormStateInterface;
8
use Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface;
9
use Drupal\Core\Routing\RouteMatchInterface;
10
use Drupal\Core\Url;
11
use Drupal\entity_browser\DisplayBase;
12
use Drupal\entity_browser\DisplayRouterInterface;
13
use Drupal\entity_browser\Events\Events;
14
use Drupal\entity_browser\Events\RegisterJSCallbacks;
15
use Drupal\entity_browser\Events\AlterEntityBrowserDisplayData;
16
use Symfony\Component\DependencyInjection\ContainerInterface;
17
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
18
use Drupal\Core\Path\CurrentPathStack;
19
use Symfony\Component\HttpFoundation\Response;
20
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
21
use Symfony\Component\HttpFoundation\Request;
22
23
/**
24
 * Presents entity browser in an iFrame.
25
 *
26
 * @EntityBrowserDisplay(
27
 *   id = "iframe",
28
 *   label = @Translation("iFrame"),
29
 *   description = @Translation("Displays the entity browser in an iFrame container embedded into the main page."),
30
 *   uses_route = TRUE
31
 * )
32
 */
33
class IFrame extends DisplayBase implements DisplayRouterInterface {
34
35
  /**
36
   * Current route match service.
37
   *
38
   * @var \Drupal\Core\Routing\RouteMatchInterface
39
   */
40
  protected $currentRouteMatch;
41
42
  /**
43
   * Current path.
44
   *
45
   * @var \Drupal\Core\Path\CurrentPathStack
46
   */
47
  protected $currentPath;
48
49
  /**
50
   * Current request.
51
   *
52
   * @var \Symfony\Component\HttpFoundation\Request
53
   */
54
  protected $request;
55
56
  /**
57
   * Constructs display plugin.
58
   *
59
   * @param array $configuration
60
   *   A configuration array containing information about the plugin instance.
61
   * @param string $plugin_id
62
   *   The plugin_id for the plugin instance.
63
   * @param mixed $plugin_definition
64
   *   The plugin implementation definition.
65
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
66
   *   Event dispatcher service.
67
   * @param \Drupal\Component\Uuid\UuidInterface $uuid
68
   *   UUID generator interface.
69
   * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $selection_storage
70
   *   The selection storage.
71
   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
72
   *   The currently active route match object.
73
   * @param \Symfony\Component\HttpFoundation\Request $request
74
   *   Current request.
75
   * @param \Drupal\Core\Path\CurrentPathStack $current_path
76
   *   The current path.
77
   */
78
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, UuidInterface $uuid, KeyValueStoreExpirableInterface $selection_storage, RouteMatchInterface $current_route_match, Request $request, CurrentPathStack $current_path) {
79
    parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $uuid, $selection_storage);
80
    $this->currentRouteMatch = $current_route_match;
81
    $this->request = $request;
82
    $this->currentPath = $current_path;
83
  }
84
85
  /**
86
   * {@inheritdoc}
87
   */
88
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
89
    return new static(
90
      $configuration,
91
      $plugin_id,
92
      $plugin_definition,
93
      $container->get('event_dispatcher'),
94
      $container->get('uuid'),
95
      $container->get('entity_browser.selection_storage'),
96
      $container->get('current_route_match'),
97
      $container->get('request_stack')->getCurrentRequest(),
98
      $container->get('path.current')
99
    );
100
  }
101
102
  /**
103
   * {@inheritdoc}
104
   */
105
  public function defaultConfiguration() {
106
    return [
107
      'width' => '650',
108
      'height' => '500',
109
      'link_text' => $this->t('Select entities'),
110
      'auto_open' => FALSE,
111
    ] + parent::defaultConfiguration();
112
  }
113
114
  /**
115
   * {@inheritdoc}
116
   */
117
  public function displayEntityBrowser(array $element, FormStateInterface $form_state, array &$complete_form, array $persistent_data = []) {
118
    parent::displayEntityBrowser($element, $form_state, $complete_form, $persistent_data);
119
    /** @var \Drupal\entity_browser\Events\RegisterJSCallbacks $event */
120
    $js_event_object = new RegisterJSCallbacks($this->configuration['entity_browser_id'], $this->getUuid());
121
    $js_event_object->registerCallback('Drupal.entityBrowser.selectionCompleted');
122
    $callback_event = $this->eventDispatcher->dispatch(Events::REGISTER_JS_CALLBACKS, $js_event_object);
123
    $original_path = $this->currentPath->getPath();
124
125
    $data = [
126
      'query_parameters' => [
127
        'query' => [
128
          'uuid' => $this->getUuid(),
129
          'original_path' => $original_path,
130
        ],
131
      ],
132
      'attributes' => [
133
        'href' => '#browser',
134
        'class' => ['entity-browser-handle', 'entity-browser-iframe'],
135
        'data-uuid' => $this->getUuid(),
136
        'data-original-path' => $original_path,
137
      ],
138
    ];
139
    $event_object = new AlterEntityBrowserDisplayData($this->configuration['entity_browser_id'], $this->getUuid(), $this->getPluginDefinition(), $form_state, $data);
140
    $event = $this->eventDispatcher->dispatch(Events::ALTER_BROWSER_DISPLAY_DATA, $event_object);
141
    $data = $event->getData();
142
    return [
143
      '#theme_wrappers' => ['container'],
144
      '#attributes' => [
145
        'class' => [
146
          'entity-browser-iframe-container',
147
        ],
148
      ],
149
      'link' => [
150
        '#type' => 'html_tag',
151
        '#tag' => 'a',
152
        '#value' => $this->configuration['link_text'],
153
        '#attributes' => $data['attributes'],
154
        '#attached' => [
155
          'library' => ['entity_browser/iframe'],
156
          'drupalSettings' => [
157
            'entity_browser' => [
158
              'iframe' => [
159
                $this->getUuid() => [
160
                  'src' => Url::fromRoute('entity_browser.' . $this->configuration['entity_browser_id'], [], $data['query_parameters'])
161
                    ->toString(),
162
                  'width' => $this->configuration['width'],
163
                  'height' => $this->configuration['height'],
164
                  'js_callbacks' => $callback_event->getCallbacks(),
165
                  'entity_browser_id' => $this->configuration['entity_browser_id'],
166
                  'auto_open' => $this->configuration['auto_open'],
167
                ],
168
              ],
169
            ],
170
          ],
171
        ],
172
      ],
173
    ];
174
  }
175
176
  /**
177
   * KernelEvents::RESPONSE listener.
178
   *
179
   * Intercepts default response and injects response that will trigger JS to
180
   * propagate selected entities upstream.
181
   *
182
   * @param FilterResponseEvent $event
183
   *   Response event.
184
   */
185
  public function propagateSelection(FilterResponseEvent $event) {
186
    $render = [
187
      'labels' => [
188
        '#markup' => 'Labels: ' . implode(', ', array_map(function (EntityInterface $item) {
189
          return $item->label();
190
        }, $this->entities)),
191
        '#attached' => [
192
          'library' => ['entity_browser/'. $this->pluginDefinition['id'] . '_selection'],
193
          'drupalSettings' => [
194
            'entity_browser' => [
195
              $this->pluginDefinition['id'] => [
196
                'entities' => array_map(function (EntityInterface $item) {
197
                  return [$item->id(), $item->uuid(), $item->getEntityTypeId()];
198
                }, $this->entities),
199
                'uuid' => $this->request->query->get('uuid'),
200
              ],
201
            ],
202
          ],
203
        ],
204
      ],
205
    ];
206
207
    $event->setResponse(new Response(\Drupal::service('bare_html_page_renderer')->renderBarePage($render, 'Entity browser', 'page')));
208
  }
209
210
  /**
211
   * {@inheritdoc}
212
   */
213
  public function path() {
214
    return '/entity-browser/' . $this->pluginDefinition['id'] . '/' . $this->configuration['entity_browser_id'];
215
  }
216
217
  /**
218
   * {@inheritdoc}
219
   */
220
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
221
    $configuration = $this->getConfiguration();
222
    $form['width'] = [
223
      '#type' => 'textfield',
224
      '#title' => $this->t('Width of the iFrame'),
225
      '#default_value' => $configuration['width'],
226
      '#description' => $this->t('Positive integer for absolute size or a relative size in percentages.'),
227
    ];
228
229
    $form['height'] = [
230
      '#type' => 'number',
231
      '#title' => $this->t('Height of the iFrame'),
232
      '#min' => 1,
233
      '#default_value' => $configuration['height'],
234
    ];
235
236
    $form['link_text'] = [
237
      '#type' => 'textfield',
238
      '#title' => $this->t('Link text'),
239
      '#default_value' => $configuration['link_text'],
240
    ];
241
242
    $form['auto_open'] = [
243
      '#type' => 'checkbox',
244
      '#title' => $this->t('Auto open entity browser'),
245
      '#default_value' => $configuration['auto_open'],
246
    ];
247
248
    return $form;
249
  }
250
251
  /**
252
   * {@inheritdoc}
253
   */
254
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
255
    // We want all positive integers, or percentages between 1% and 100%.
256
    $pattern = '/^([1-9][0-9]*|([2-9][0-9]{0,1}%)|(1[0-9]{0,2}%))$/';
257
    if (preg_match($pattern, $form_state->getValue('width')) == 0) {
258
      $form_state->setError($form['width'], $this->t('Width must be a number greater than 0, or a percentage between 1% and 100%.'));
259
    }
260
261
    if ($form_state->getValue('height') <= 0) {
262
      $form_state->setError($form['height'], $this->t('Height must be greater than 0.'));
263
    }
264
  }
265
266
}
267