Completed
Push — 8.x-1.x ( da8d51...96c705 )
by Janez
07:38 queued 03:01
created

IFrame::displayEntityBrowser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 53
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 11
Bugs 2 Features 1
Metric Value
cc 1
eloc 39
c 11
b 2
f 1
nc 1
nop 4
dl 0
loc 53
rs 9.5797

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 entity browser in an iFrame."),
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 View Code Duplication
  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) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
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 View Code Duplication
  public function defaultConfiguration() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
106
    return [
107
      'width' => '650',
108
      'height' => '500',
109
      'link_text' => 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
      'link' => [
145
        '#type' => 'html_tag',
146
        '#tag' => 'a',
147
        '#value' => $this->configuration['link_text'],
148
        '#attributes' => $data['attributes'],
149
        '#attached' => [
150
          'library' => ['entity_browser/iframe'],
151
          'drupalSettings' => [
152
            'entity_browser' => [
153
              'iframe' => [
154
                $this->getUuid() => [
155
                  'src' => Url::fromRoute('entity_browser.' . $this->configuration['entity_browser_id'], [], $data['query_parameters'])
156
                    ->toString(),
157
                  'width' => $this->configuration['width'],
158
                  'height' => $this->configuration['height'],
159
                  'js_callbacks' => $callback_event->getCallbacks(),
160
                  'entity_browser_id' => $this->configuration['entity_browser_id'],
161
                  'auto_open' => $this->configuration['auto_open'],
162
                ],
163
              ],
164
            ],
165
          ],
166
        ],
167
      ],
168
    ];
169
  }
170
171
  /**
172
   * KernelEvents::RESPONSE listener.
173
   *
174
   * Intercepts default response and injects response that will trigger JS to
175
   * propagate selected entities upstream.
176
   *
177
   * @param FilterResponseEvent $event
178
   *   Response event.
179
   */
180 View Code Duplication
  public function propagateSelection(FilterResponseEvent $event) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
    $render = [
182
      'labels' => [
183
        '#markup' => 'Labels: ' . implode(', ', array_map(function (EntityInterface $item) {
184
          return $item->label();
185
        }, $this->entities)),
186
        '#attached' => [
187
          'library' => ['entity_browser/iframe_selection'],
188
          'drupalSettings' => [
189
            'entity_browser' => [
190
              'iframe' => [
191
                'entities' => array_map(function (EntityInterface $item) {
192
                  return [$item->id(), $item->uuid(), $item->getEntityTypeId()];
193
                }, $this->entities),
194
                'uuid' => $this->request->query->get('uuid'),
195
              ],
196
            ],
197
          ],
198
        ],
199
      ],
200
    ];
201
202
    $event->setResponse(new Response(\Drupal::service('bare_html_page_renderer')->renderBarePage($render, 'Entity browser', 'page')));
203
  }
204
205
  /**
206
   * {@inheritdoc}
207
   */
208
  public function path() {
209
    return '/entity-browser/iframe/' . $this->configuration['entity_browser_id'];
210
  }
211
212
  /**
213
   * {@inheritdoc}
214
   */
215
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
216
    $configuration = $this->getConfiguration();
217
    $form['width'] = [
218
      '#type' => 'textfield',
219
      '#title' => $this->t('Width of the iFrame'),
220
      '#default_value' => $configuration['width'],
221
      '#description' => $this->t('Positive integer for absolute size or a relative size in percentages.'),
222
    ];
223
224
    $form['height'] = [
225
      '#type' => 'number',
226
      '#title' => $this->t('Height of the iFrame'),
227
      '#min' => 1,
228
      '#default_value' => $configuration['height'],
229
    ];
230
231
    $form['link_text'] = [
232
      '#type' => 'textfield',
233
      '#title' => $this->t('Link text'),
234
      '#default_value' => $configuration['link_text'],
235
    ];
236
237
    $form['auto_open'] = [
238
      '#type' => 'checkbox',
239
      '#title' => $this->t('Auto open entity browser'),
240
      '#default_value' => $configuration['auto_open'],
241
    ];
242
243
    return $form;
244
  }
245
246
  /**
247
   * {@inheritdoc}
248
   */
249
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
250
    // We want all positive integers, or percentages between 1% and 100%.
251
    $pattern = '/^([1-9][0-9]*|([2-9][0-9]{0,1}%)|(1[0-9]{0,2}%))$/';
252
    if (preg_match($pattern, $form_state->getValue('width')) == 0) {
253
      $form_state->setError($form['width'], $this->t('Width must be a number greater than 0, or a percentage between 1% and 100%.'));
254
    }
255
256
    if ($form_state->getValue('height') <= 0) {
257
      $form_state->setError($form['height'], $this->t('Height must be greater than 0.'));
258
    }
259
  }
260
261
}
262