IFrame::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 9
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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