Completed
Push — 8.x-1.x ( d0852f...55caf8 )
by Janez
02:42
created

IFrame::setUuid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/**
4
 * Contains \Drupal\entity_browser\Plugin\EntityBrowser\Display\IFrame.
5
 */
6
7
namespace Drupal\entity_browser\Plugin\EntityBrowser\Display;
8
9
use Drupal\Component\Uuid\UuidInterface;
10
use Drupal\Core\Entity\EntityInterface;
11
use Drupal\Core\Routing\RouteMatchInterface;
12
use Drupal\Core\Url;
13
use Drupal\entity_browser\DisplayBase;
14
use Drupal\entity_browser\DisplayRouterInterface;
15
use Drupal\entity_browser\Events\Events;
16
use Drupal\entity_browser\Events\RegisterJSCallbacks;
17
use Symfony\Component\DependencyInjection\ContainerInterface;
18
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
19
use Drupal\Core\Path\CurrentPathStack;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
22
use Symfony\Component\HttpKernel\KernelEvents;
23
use Symfony\Component\HttpFoundation\Request;
24
25
/**
26
 * Presents entity browser in an iFrame.
27
 *
28
 * @EntityBrowserDisplay(
29
 *   id = "iframe",
30
 *   label = @Translation("iFrame"),
31
 *   description = @Translation("Displays entity browser in an iFrame."),
32
 *   uses_route = TRUE
33
 * )
34
 */
35
class IFrame extends DisplayBase implements DisplayRouterInterface {
36
37
  /**
38
   * Current route match service.
39
   *
40
   * @var \Drupal\Core\Routing\RouteMatchInterface
41
   */
42
  protected $currentRouteMatch;
43
44
  /**
45
   * UUID generator interface.
46
   *
47
   * @var \Drupal\Component\Uuid\UuidInterface
48
   */
49
  protected $uuidGenerator;
50
51
  /**
52
   * UIID string.
53
   *
54
   * @var string
55
   */
56
  protected $uuid = NULL;
57
58
  /**
59
   * Current path.
60
   *
61
   * @var \Drupal\Core\Path\CurrentPathStack
62
   */
63
  protected $currentPath;
64
65
  /**
66
   * Current request.
67
   *
68
   * @var \Symfony\Component\HttpFoundation\Request
69
   */
70
  protected $request;
71
72
  /**
73
   * Constructs display plugin.
74
   *
75
   * @param array $configuration
76
   *   A configuration array containing information about the plugin instance.
77
   * @param string $plugin_id
78
   *   The plugin_id for the plugin instance.
79
   * @param mixed $plugin_definition
80
   *   The plugin implementation definition.
81
   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
82
   *   Event dispatcher service.
83
   * @param \Drupal\Core\Routing\RouteMatchInterface
84
   *   The currently active route match object.
85
   * @param \Drupal\Component\Uuid\UuidInterface
86
   *   UUID generator interface.
87
   * @param \Drupal\Core\Path\CurrentPathStack $current_path
88
   *   The current path.
89
   */
90
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, RouteMatchInterface $current_route_match, UuidInterface $uuid, Request $request, CurrentPathStack $current_path) {
91
    parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher);
92
    $this->currentRouteMatch = $current_route_match;
93
    $this->uuidGenerator = $uuid;
94
    $this->request = $request;
95
    $this->currentPath = $current_path;
96
  }
97
98
  /**
99
   * {@inheritdoc}
100
   */
101 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...
102
    return new static(
103
      $configuration,
104
      $plugin_id,
105
      $plugin_definition,
106
      $container->get('event_dispatcher'),
107
      $container->get('current_route_match'),
108
      $container->get('uuid'),
109
      $container->get('request_stack')->getCurrentRequest(),
110
      $container->get('path.current')
111
    );
112
  }
113
114
  /**
115
   * {@inheritdoc}
116
   */
117 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...
118
    return array(
119
      'width' => '650',
120
      'height' => '500',
121
      'link_text' => t('Select entities'),
122
      'auto_open' => FALSE,
123
    ) + parent::defaultConfiguration();
124
  }
125
126
  /**
127
   * {@inheritdoc}
128
   */
129
  public function displayEntityBrowser() {
130
    $uuid = $this->getUuid();
131
    /** @var \Drupal\entity_browser\Events\RegisterJSCallbacks $event */
132
    // TODO - $uuid is unused in this event but we need to pass it as
133
    // constructor expects it. See https://www.drupal.org/node/2600706 for more
134
    // info.
135
    $event_object = new RegisterJSCallbacks($this->configuration['entity_browser_id'], $uuid);
136
    $event_object->registerCallback('Drupal.entityBrowser.selectionCompleted');
137
    $event = $this->eventDispatcher->dispatch(Events::REGISTER_JS_CALLBACKS, $event_object );
138
    $original_path = $this->currentPath->getPath();
139
    return [
140
      '#theme_wrappers' => ['container'],
141
      'link' => [
142
        '#type' => 'html_tag',
143
        '#tag' => 'a',
144
        '#value' => $this->configuration['link_text'],
145
        '#attributes' => [
146
          'href' => '#browser',
147
          'class' => ['entity-browser-handle', 'entity-browser-iframe'],
148
          'data-uuid' => $uuid,
149
          'data-original-path' => $original_path,
150
        ],
151
        '#attached' => [
152
          'library' => ['entity_browser/iframe'],
153
          'drupalSettings' => [
154
            'entity_browser' => [
155
              'iframe' => [
156
                $uuid => [
157
                  'src' => Url::fromRoute('entity_browser.' . $this->configuration['entity_browser_id'], [], [
158
                    'query' => [
159
                      'uuid' => $uuid,
160
                      'original_path' => $original_path,
161
                    ]
162
                  ])->toString(),
163
                  'width' => $this->configuration['width'],
164
                  'height' => $this->configuration['height'],
165
                  'js_callbacks' => $event->getCallbacks(),
166
                  'entity_browser_id' => $this->configuration['entity_browser_id'],
167
                  'auto_open' => $this->configuration['auto_open'],
168
                ],
169
              ],
170
            ],
171
          ]
172
        ],
173
      ],
174
    ];
175
  }
176
177
  /**
178
   * {@inheritdoc}
179
   */
180
  public function selectionCompleted(array $entities) {
181
    $this->entities = $entities;
182
    $this->eventDispatcher->addListener(KernelEvents::RESPONSE, [$this, 'propagateSelection']);
183
  }
184
185
  /**
186
   * KernelEvents::RESPONSE listener. Intercepts default response and injects
187
   * response that will trigger JS to propagate selected entities upstream.
188
   *
189
   * @param FilterResponseEvent $event
190
   *   Response event.
191
   */
192 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...
193
    $render = [
194
      'labels' => [
195
        '#markup' => 'Labels: ' . implode(', ', array_map(function (EntityInterface $item) {return $item->label();}, $this->entities)),
196
        '#attached' => [
197
          'library' => ['entity_browser/iframe_selection'],
198
          'drupalSettings' => [
199
            'entity_browser' => [
200
              'iframe' => [
201
                'entities' => array_map(function (EntityInterface $item) {return [$item->id(), $item->uuid(), $item->getEntityTypeId()];}, $this->entities),
202
                'uuid' => $this->request->query->get('uuid'),
203
              ],
204
            ],
205
          ],
206
        ],
207
      ],
208
    ];
209
210
    $event->setResponse(new Response(\Drupal::service('bare_html_page_renderer')->renderBarePage($render, 'Entity browser', 'page')));
211
  }
212
213
  /**
214
   * {@inheritdoc}
215
   */
216
  public function getUuid() {
217
    if (empty($this->uuid)) {
218
      $this->uuid = $this->uuidGenerator->generate();
219
    }
220
    return $this->uuid;
221
  }
222
223
  /**
224
    * {@inheritdoc}
225
    */
226
  public function setUuid($uuid) {
227
    $this->uuid = $uuid;
228
  }
229
230
  /**
231
   * {@inheritdoc}
232
   */
233
  public function path() {
234
    return '/entity-browser/iframe/' . $this->configuration['entity_browser_id'];
235
  }
236
237
}
238