Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
36 | * ) |
||
37 | */ |
||
38 | class IFrame extends DisplayBase implements DisplayRouterInterface { |
||
39 | |||
40 | /** |
||
41 | * Current route match service. |
||
42 | * |
||
43 | * @var \Drupal\Core\Routing\RouteMatchInterface |
||
44 | */ |
||
45 | protected $currentRouteMatch; |
||
46 | |||
47 | /** |
||
48 | * UUID generator interface. |
||
49 | * |
||
50 | * @var \Drupal\Component\Uuid\UuidInterface |
||
51 | */ |
||
52 | protected $uuidGenerator; |
||
53 | |||
54 | /** |
||
55 | * UIID string. |
||
56 | * |
||
57 | * @var string |
||
58 | */ |
||
59 | protected $uuid = NULL; |
||
60 | |||
61 | /** |
||
62 | * Current path. |
||
63 | * |
||
64 | * @var \Drupal\Core\Path\CurrentPathStack |
||
65 | */ |
||
66 | protected $currentPath; |
||
67 | |||
68 | /** |
||
69 | * Current request. |
||
70 | * |
||
71 | * @var \Symfony\Component\HttpFoundation\Request |
||
72 | */ |
||
73 | protected $request; |
||
74 | |||
75 | /** |
||
76 | * Constructs display plugin. |
||
77 | * |
||
78 | * @param array $configuration |
||
79 | * A configuration array containing information about the plugin instance. |
||
80 | * @param string $plugin_id |
||
81 | * The plugin_id for the plugin instance. |
||
82 | * @param mixed $plugin_definition |
||
83 | * The plugin implementation definition. |
||
84 | * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher |
||
85 | * Event dispatcher service. |
||
86 | * @param \Drupal\Core\Routing\RouteMatchInterface |
||
87 | * The currently active route match object. |
||
88 | * @param \Drupal\Component\Uuid\UuidInterface |
||
89 | * UUID generator interface. |
||
90 | * @param \Drupal\Core\Path\CurrentPathStack $current_path |
||
91 | * The current path. |
||
92 | */ |
||
93 | public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, RouteMatchInterface $current_route_match, UuidInterface $uuid, Request $request, CurrentPathStack $current_path) { |
||
94 | parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher); |
||
95 | $this->currentRouteMatch = $current_route_match; |
||
96 | $this->uuidGenerator = $uuid; |
||
97 | $this->request = $request; |
||
98 | $this->currentPath = $current_path; |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * {@inheritdoc} |
||
103 | */ |
||
104 | public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { |
||
105 | return new static( |
||
106 | $configuration, |
||
107 | $plugin_id, |
||
108 | $plugin_definition, |
||
109 | $container->get('event_dispatcher'), |
||
110 | $container->get('current_route_match'), |
||
111 | $container->get('uuid'), |
||
112 | $container->get('request_stack')->getCurrentRequest(), |
||
113 | $container->get('path.current') |
||
114 | ); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * {@inheritdoc} |
||
119 | */ |
||
120 | public function defaultConfiguration() { |
||
121 | return array( |
||
122 | 'width' => '650', |
||
123 | 'height' => '500', |
||
124 | 'link_text' => t('Select entities'), |
||
125 | 'auto_open' => FALSE, |
||
126 | ) + parent::defaultConfiguration(); |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * {@inheritdoc} |
||
131 | */ |
||
132 | public function displayEntityBrowser(FormStateInterface $form_state) { |
||
133 | $uuid = $this->getUuid(); |
||
134 | /** @var \Drupal\entity_browser\Events\RegisterJSCallbacks $event */ |
||
135 | // TODO - $uuid is unused in this event but we need to pass it as |
||
136 | // constructor expects it. See https://www.drupal.org/node/2600706 for more |
||
137 | // info. |
||
138 | $js_event_object = new RegisterJSCallbacks($this->configuration['entity_browser_id'], $uuid); |
||
139 | $js_event_object->registerCallback('Drupal.entityBrowser.selectionCompleted'); |
||
140 | $callback_event = $this->eventDispatcher->dispatch(Events::REGISTER_JS_CALLBACKS, $js_event_object); |
||
141 | $original_path = $this->currentPath->getPath(); |
||
142 | $data = [ |
||
143 | 'query_parameters' => [ |
||
144 | 'query' => [ |
||
145 | 'uuid' => $uuid, |
||
146 | 'original_path' => $original_path, |
||
147 | ], |
||
148 | ], |
||
149 | 'attributes' => [ |
||
150 | 'href' => '#browser', |
||
151 | 'class' => ['entity-browser-handle', 'entity-browser-iframe'], |
||
152 | 'data-uuid' => $uuid, |
||
153 | 'data-original-path' => $original_path, |
||
154 | ], |
||
155 | ]; |
||
156 | $event_object = new AlterEntityBrowserDisplayData($this->configuration['entity_browser_id'], $uuid, $this->getPluginDefinition(), $form_state, $data); |
||
157 | $event = $this->eventDispatcher->dispatch(Events::ALTER_BROWSER_DISPLAY_DATA, $event_object); |
||
158 | $data = $event->getData(); |
||
159 | return [ |
||
160 | '#theme_wrappers' => ['container'], |
||
161 | 'link' => [ |
||
162 | '#type' => 'html_tag', |
||
163 | '#tag' => 'a', |
||
164 | '#value' => $this->configuration['link_text'], |
||
165 | '#attributes' => $data['attributes'], |
||
166 | '#attached' => [ |
||
167 | 'library' => ['entity_browser/iframe'], |
||
168 | 'drupalSettings' => [ |
||
169 | 'entity_browser' => [ |
||
170 | 'iframe' => [ |
||
171 | $uuid => [ |
||
172 | 'src' => Url::fromRoute('entity_browser.' . $this->configuration['entity_browser_id'], [], $data['query_parameters']) |
||
173 | ->toString(), |
||
174 | 'width' => $this->configuration['width'], |
||
175 | 'height' => $this->configuration['height'], |
||
176 | 'js_callbacks' => $callback_event->getCallbacks(), |
||
177 | 'entity_browser_id' => $this->configuration['entity_browser_id'], |
||
178 | 'auto_open' => $this->configuration['auto_open'], |
||
179 | ], |
||
180 | ], |
||
181 | ], |
||
182 | ] |
||
183 | ], |
||
184 | ], |
||
185 | ]; |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * {@inheritdoc} |
||
190 | */ |
||
191 | public function selectionCompleted(array $entities) { |
||
192 | $this->entities = $entities; |
||
193 | $this->eventDispatcher->addListener(KernelEvents::RESPONSE, [$this, 'propagateSelection']); |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * KernelEvents::RESPONSE listener. Intercepts default response and injects |
||
198 | * response that will trigger JS to propagate selected entities upstream. |
||
199 | * |
||
200 | * @param FilterResponseEvent $event |
||
201 | * Response event. |
||
202 | */ |
||
203 | public function propagateSelection(FilterResponseEvent $event) { |
||
204 | $render = [ |
||
205 | 'labels' => [ |
||
206 | '#markup' => 'Labels: ' . implode(', ', array_map(function (EntityInterface $item) {return $item->label();}, $this->entities)), |
||
207 | '#attached' => [ |
||
208 | 'library' => ['entity_browser/iframe_selection'], |
||
209 | 'drupalSettings' => [ |
||
210 | 'entity_browser' => [ |
||
211 | 'iframe' => [ |
||
212 | 'entities' => array_map(function (EntityInterface $item) {return [$item->id(), $item->uuid(), $item->getEntityTypeId()];}, $this->entities), |
||
213 | 'uuid' => $this->request->query->get('uuid'), |
||
214 | ], |
||
215 | ], |
||
216 | ], |
||
217 | ], |
||
218 | ], |
||
219 | ]; |
||
220 | |||
221 | $event->setResponse(new Response(\Drupal::service('bare_html_page_renderer')->renderBarePage($render, 'Entity browser', 'page'))); |
||
222 | } |
||
223 | |||
224 | /** |
||
225 | * {@inheritdoc} |
||
226 | */ |
||
227 | public function getUuid() { |
||
228 | if (empty($this->uuid)) { |
||
229 | $this->uuid = $this->uuidGenerator->generate(); |
||
230 | } |
||
231 | return $this->uuid; |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * {@inheritdoc} |
||
236 | */ |
||
237 | public function setUuid($uuid) { |
||
238 | $this->uuid = $uuid; |
||
239 | } |
||
240 | |||
241 | /** |
||
242 | * {@inheritdoc} |
||
243 | */ |
||
244 | public function path() { |
||
245 | return '/entity-browser/iframe/' . $this->configuration['entity_browser_id']; |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * {@inheritdoc} |
||
250 | */ |
||
251 | public function buildConfigurationForm(array $form, FormStateInterface $form_state) { |
||
252 | $configuration = $this->getConfiguration(); |
||
253 | $form['width'] = [ |
||
254 | '#type' => 'number', |
||
255 | '#title' => $this->t('Width of the iFrame'), |
||
256 | '#min' => 1, |
||
257 | '#default_value' => $configuration['width'], |
||
258 | ]; |
||
259 | |||
260 | $form['height'] = [ |
||
261 | '#type' => 'number', |
||
262 | '#title' => $this->t('Height of the iFrame'), |
||
263 | '#min' => 1, |
||
264 | '#default_value' => $configuration['height'], |
||
265 | ]; |
||
266 | |||
267 | $form['link_text'] = [ |
||
268 | '#type' => 'textfield', |
||
269 | '#title' => $this->t('Link text'), |
||
270 | '#default_value' => $configuration['link_text'], |
||
271 | ]; |
||
272 | |||
273 | $form['auto_open'] = [ |
||
274 | '#type' => 'checkbox', |
||
275 | '#title' => $this->t('Auto open entity browser'), |
||
276 | '#default_value' => $configuration['auto_open'], |
||
277 | ]; |
||
278 | |||
279 | return $form; |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * {@inheritdoc} |
||
284 | */ |
||
285 | public function validateConfigurationForm(array &$form, FormStateInterface $form_state) { |
||
295 |