Completed
Push — 8.x-1.x ( 228956...9813da )
by Janez
03:15
created

IFrame::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 10

Duplication

Lines 12
Ratio 100 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 10
c 2
b 0
f 1
nc 1
nop 4
dl 12
loc 12
rs 9.4285
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\Routing\RouteMatchInterface;
9
use Drupal\Core\Url;
10
use Drupal\entity_browser\DisplayBase;
11
use Drupal\entity_browser\DisplayRouterInterface;
12
use Drupal\entity_browser\Events\Events;
13
use Drupal\entity_browser\Events\RegisterJSCallbacks;
14
use Drupal\entity_browser\Events\AlterEntityBrowserDisplayData;
15
use Symfony\Component\DependencyInjection\ContainerInterface;
16
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
17
use Drupal\Core\Path\CurrentPathStack;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
20
use Symfony\Component\HttpKernel\KernelEvents;
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
68
   *   UUID generator interface.
69
   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
70
   *   The currently active route match object.
71
   * @param \Symfony\Component\HttpFoundation\Request $request
72
   *   Current request.
73
   * @param \Drupal\Core\Path\CurrentPathStack $current_path
74
   *   The current path.
75
   */
76 View Code Duplication
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, UuidInterface $uuid, 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...
77
    parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $uuid);
78
    $this->currentRouteMatch = $current_route_match;
79
    $this->request = $request;
80
    $this->currentPath = $current_path;
81
  }
82
83
  /**
84
   * {@inheritdoc}
85
   */
86 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...
87
    return new static(
88
      $configuration,
89
      $plugin_id,
90
      $plugin_definition,
91
      $container->get('event_dispatcher'),
92
      $container->get('uuid'),
93
      $container->get('current_route_match'),
94
      $container->get('request_stack')->getCurrentRequest(),
95
      $container->get('path.current')
96
    );
97
  }
98
99
  /**
100
   * {@inheritdoc}
101
   */
102 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...
103
    return [
104
      'width' => '650',
105
      'height' => '500',
106
      'link_text' => t('Select entities'),
107
      'auto_open' => FALSE,
108
    ] + parent::defaultConfiguration();
109
  }
110
111
  /**
112
   * {@inheritdoc}
113
   */
114
  public function displayEntityBrowser(FormStateInterface $form_state) {
115
    $uuid = $this->getUuid();
116
    /** @var \Drupal\entity_browser\Events\RegisterJSCallbacks $event */
117
    $js_event_object = new RegisterJSCallbacks($this->configuration['entity_browser_id'], $uuid);
118
    $js_event_object->registerCallback('Drupal.entityBrowser.selectionCompleted');
119
    $callback_event = $this->eventDispatcher->dispatch(Events::REGISTER_JS_CALLBACKS, $js_event_object);
120
    $original_path = $this->currentPath->getPath();
121
    $data = [
122
      'query_parameters' => [
123
        'query' => [
124
          'uuid' => $uuid,
125
          'original_path' => $original_path,
126
        ],
127
      ],
128
      'attributes' => [
129
        'href' => '#browser',
130
        'class' => ['entity-browser-handle', 'entity-browser-iframe'],
131
        'data-uuid' => $uuid,
132
        'data-original-path' => $original_path,
133
      ],
134
    ];
135
    $event_object = new AlterEntityBrowserDisplayData($this->configuration['entity_browser_id'], $uuid, $this->getPluginDefinition(), $form_state, $data);
136
    $event = $this->eventDispatcher->dispatch(Events::ALTER_BROWSER_DISPLAY_DATA, $event_object);
137
    $data = $event->getData();
138
    return [
139
      '#theme_wrappers' => ['container'],
140
      'link' => [
141
        '#type' => 'html_tag',
142
        '#tag' => 'a',
143
        '#value' => $this->configuration['link_text'],
144
        '#attributes' => $data['attributes'],
145
        '#attached' => [
146
          'library' => ['entity_browser/iframe'],
147
          'drupalSettings' => [
148
            'entity_browser' => [
149
              'iframe' => [
150
                $uuid => [
151
                  'src' => Url::fromRoute('entity_browser.' . $this->configuration['entity_browser_id'], [], $data['query_parameters'])
152
                    ->toString(),
153
                  'width' => $this->configuration['width'],
154
                  'height' => $this->configuration['height'],
155
                  'js_callbacks' => $callback_event->getCallbacks(),
156
                  'entity_browser_id' => $this->configuration['entity_browser_id'],
157
                  'auto_open' => $this->configuration['auto_open'],
158
                ],
159
              ],
160
            ],
161
          ],
162
        ],
163
      ],
164
    ];
165
  }
166
167
  /**
168
   * {@inheritdoc}
169
   */
170
  public function selectionCompleted(array $entities) {
171
    $this->entities = $entities;
172
    $this->eventDispatcher->addListener(KernelEvents::RESPONSE, [$this, 'propagateSelection']);
173
  }
174
175
  /**
176
   * KernelEvents::RESPONSE listener. Intercepts default response and injects
177
   * response that will trigger JS to propagate selected entities upstream.
178
   *
179
   * @param FilterResponseEvent $event
180
   *   Response event.
181
   */
182 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...
183
    $render = [
184
      'labels' => [
185
        '#markup' => 'Labels: ' . implode(', ', array_map(function (EntityInterface $item) {
186
          return $item->label();
187
        }, $this->entities)),
188
        '#attached' => [
189
          'library' => ['entity_browser/iframe_selection'],
190
          'drupalSettings' => [
191
            'entity_browser' => [
192
              'iframe' => [
193
                'entities' => array_map(function (EntityInterface $item) {
194
                  return [$item->id(), $item->uuid(), $item->getEntityTypeId()];
195
                }, $this->entities),
196
                'uuid' => $this->request->query->get('uuid'),
197
              ],
198
            ],
199
          ],
200
        ],
201
      ],
202
    ];
203
204
    $event->setResponse(new Response(\Drupal::service('bare_html_page_renderer')->renderBarePage($render, 'Entity browser', 'page')));
205
  }
206
207
  /**
208
   * {@inheritdoc}
209
   */
210
  public function path() {
211
    return '/entity-browser/iframe/' . $this->configuration['entity_browser_id'];
212
  }
213
214
  /**
215
   * {@inheritdoc}
216
   */
217
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
218
    $configuration = $this->getConfiguration();
219
    $form['width'] = [
220
      '#type' => 'number',
221
      '#title' => $this->t('Width of the iFrame'),
222
      '#min' => 1,
223
      '#default_value' => $configuration['width'],
224
    ];
225
226
    $form['height'] = [
227
      '#type' => 'number',
228
      '#title' => $this->t('Height of the iFrame'),
229
      '#min' => 1,
230
      '#default_value' => $configuration['height'],
231
    ];
232
233
    $form['link_text'] = [
234
      '#type' => 'textfield',
235
      '#title' => $this->t('Link text'),
236
      '#default_value' => $configuration['link_text'],
237
    ];
238
239
    $form['auto_open'] = [
240
      '#type' => 'checkbox',
241
      '#title' => $this->t('Auto open entity browser'),
242
      '#default_value' => $configuration['auto_open'],
243
    ];
244
245
    return $form;
246
  }
247
248
  /**
249
   * {@inheritdoc}
250
   */
251
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
252
    if ($form_state->getValue('width') <= 0) {
253
      $form_state->setError($form['width'], $this->t('Width must be greather than 0.'));
254
    }
255
    if ($form_state->getValue('height') <= 0) {
256
      $form_state->setError($form['height'], $this->t('Height must be greather than 0.'));
257
    }
258
  }
259
260
}
261