comparison core/modules/media/src/MediaSourceBase.php @ 0:c75dbcec494b

Initial commit from drush-created site
author Chris Cannam
date Thu, 05 Jul 2018 14:24:15 +0000
parents
children a9cd425dd02b
comparison
equal deleted inserted replaced
-1:000000000000 0:c75dbcec494b
1 <?php
2
3 namespace Drupal\media;
4
5 use Drupal\Component\Utility\NestedArray;
6 use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
7 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
8 use Drupal\Core\Entity\EntityFieldManagerInterface;
9 use Drupal\Core\Entity\EntityTypeManagerInterface;
10 use Drupal\Core\Field\FieldTypePluginManagerInterface;
11 use Drupal\Core\Form\FormStateInterface;
12 use Drupal\Core\Config\ConfigFactoryInterface;
13 use Drupal\Core\Plugin\PluginBase;
14 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
15 use Symfony\Component\DependencyInjection\ContainerInterface;
16
17 /**
18 * Base implementation of media source plugin.
19 */
20 abstract class MediaSourceBase extends PluginBase implements MediaSourceInterface, ContainerFactoryPluginInterface {
21
22 /**
23 * Plugin label.
24 *
25 * @var string
26 */
27 protected $label;
28
29 /**
30 * The entity type manager service.
31 *
32 * @var \Drupal\Core\Entity\EntityTypeManagerInterface
33 */
34 protected $entityTypeManager;
35
36 /**
37 * The entity field manager service.
38 *
39 * @var \Drupal\Core\Entity\EntityFieldManagerInterface
40 */
41 protected $entityFieldManager;
42
43 /**
44 * The field type plugin manager service.
45 *
46 * @var \Drupal\Core\Field\FieldTypePluginManagerInterface
47 */
48 protected $fieldTypeManager;
49
50 /**
51 * The config factory service.
52 *
53 * @var \Drupal\Core\Config\ConfigFactoryInterface
54 */
55 protected $configFactory;
56
57 /**
58 * Constructs a new class instance.
59 *
60 * @param array $configuration
61 * A configuration array containing information about the plugin instance.
62 * @param string $plugin_id
63 * The plugin_id for the plugin instance.
64 * @param mixed $plugin_definition
65 * The plugin implementation definition.
66 * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
67 * Entity type manager service.
68 * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
69 * Entity field manager service.
70 * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
71 * The field type plugin manager service.
72 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
73 * The config factory service.
74 */
75 public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, ConfigFactoryInterface $config_factory) {
76 parent::__construct($configuration, $plugin_id, $plugin_definition);
77 $this->entityTypeManager = $entity_type_manager;
78 $this->entityFieldManager = $entity_field_manager;
79 $this->fieldTypeManager = $field_type_manager;
80 $this->configFactory = $config_factory;
81
82 // Add the default configuration of the media source to the plugin.
83 $this->setConfiguration($configuration);
84 }
85
86 /**
87 * {@inheritdoc}
88 */
89 public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
90 return new static(
91 $configuration,
92 $plugin_id,
93 $plugin_definition,
94 $container->get('entity_type.manager'),
95 $container->get('entity_field.manager'),
96 $container->get('plugin.manager.field.field_type'),
97 $container->get('config.factory')
98 );
99 }
100
101 /**
102 * {@inheritdoc}
103 */
104 public function setConfiguration(array $configuration) {
105 $this->configuration = NestedArray::mergeDeep(
106 $this->defaultConfiguration(),
107 $configuration
108 );
109 }
110
111 /**
112 * {@inheritdoc}
113 */
114 public function getConfiguration() {
115 return $this->configuration;
116 }
117
118 /**
119 * {@inheritdoc}
120 */
121 public function defaultConfiguration() {
122 return [
123 'source_field' => '',
124 ];
125 }
126
127 /**
128 * {@inheritdoc}
129 */
130 public function getMetadata(MediaInterface $media, $attribute_name) {
131 switch ($attribute_name) {
132 case 'default_name':
133 return 'media:' . $media->bundle() . ':' . $media->uuid();
134
135 case 'thumbnail_uri':
136 $default_thumbnail_filename = $this->pluginDefinition['default_thumbnail_filename'];
137 return $this->configFactory->get('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename;
138 }
139
140 return NULL;
141 }
142
143 /**
144 * {@inheritdoc}
145 */
146 public function calculateDependencies() {
147 return [];
148 }
149
150 /**
151 * Get the source field options for the media type form.
152 *
153 * This returns all fields related to media entities, filtered by the allowed
154 * field types in the media source annotation.
155 *
156 * @return string[]
157 * A list of source field options for the media type form.
158 */
159 protected function getSourceFieldOptions() {
160 // If there are existing fields to choose from, allow the user to reuse one.
161 $options = [];
162 foreach ($this->entityFieldManager->getFieldStorageDefinitions('media') as $field_name => $field) {
163 $allowed_type = in_array($field->getType(), $this->pluginDefinition['allowed_field_types'], TRUE);
164 if ($allowed_type && !$field->isBaseField()) {
165 $options[$field_name] = $field->getLabel();
166 }
167 }
168 return $options;
169 }
170
171 /**
172 * {@inheritdoc}
173 */
174 public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
175 $options = $this->getSourceFieldOptions();
176 $form['source_field'] = [
177 '#type' => 'select',
178 '#title' => $this->t('Field with source information'),
179 '#default_value' => $this->configuration['source_field'],
180 '#empty_option' => $this->t('- Create -'),
181 '#options' => $options,
182 '#description' => $this->t('Select the field that will store essential information about the media item. If "Create" is selected a new field will be automatically created.'),
183 ];
184
185 if (!$options && $form_state->get('operation') === 'add') {
186 $form['source_field']['#access'] = FALSE;
187 $field_definition = $this->fieldTypeManager->getDefinition(reset($this->pluginDefinition['allowed_field_types']));
188 $form['source_field_message'] = [
189 '#markup' => $this->t('%field_type field will be automatically created on this type to store the essential information about the media item.', [
190 '%field_type' => $field_definition['label'],
191 ]),
192 ];
193 }
194 elseif ($form_state->get('operation') === 'edit') {
195 $form['source_field']['#access'] = FALSE;
196 $fields = $this->entityFieldManager->getFieldDefinitions('media', $form_state->get('type')->id());
197 $form['source_field_message'] = [
198 '#markup' => $this->t('%field_name field is used to store the essential information about the media item.', [
199 '%field_name' => $fields[$this->configuration['source_field']]->getLabel(),
200 ]),
201 ];
202 }
203
204 return $form;
205 }
206
207 /**
208 * {@inheritdoc}
209 */
210 public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
211 }
212
213 /**
214 * {@inheritdoc}
215 */
216 public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
217 foreach (array_intersect_key($form_state->getValues(), $this->configuration) as $config_key => $config_value) {
218 $this->configuration[$config_key] = $config_value;
219 }
220
221 // If no source field is explicitly set, create it now.
222 if (empty($this->configuration['source_field'])) {
223 $field_storage = $this->createSourceFieldStorage();
224 $field_storage->save();
225 $this->configuration['source_field'] = $field_storage->getName();
226 }
227 }
228
229 /**
230 * Creates the source field storage definition.
231 *
232 * By default, the first field type listed in the plugin definition's
233 * allowed_field_types array will be the generated field's type.
234 *
235 * @return \Drupal\field\FieldStorageConfigInterface
236 * The unsaved field storage definition.
237 */
238 protected function createSourceFieldStorage() {
239 return $this->entityTypeManager
240 ->getStorage('field_storage_config')
241 ->create([
242 'entity_type' => 'media',
243 'field_name' => $this->getSourceFieldName(),
244 'type' => reset($this->pluginDefinition['allowed_field_types']),
245 ]);
246 }
247
248 /**
249 * Returns the source field storage definition.
250 *
251 * @return \Drupal\Core\Field\FieldStorageDefinitionInterface|null
252 * The field storage definition or NULL if it doesn't exists.
253 */
254 protected function getSourceFieldStorage() {
255 // Nothing to do if no source field is configured yet.
256 $field = $this->configuration['source_field'];
257 if ($field) {
258 // Even if we do know the name of the source field, there's no
259 // guarantee that it exists.
260 $fields = $this->entityFieldManager->getFieldStorageDefinitions('media');
261 return isset($fields[$field]) ? $fields[$field] : NULL;
262 }
263 return NULL;
264 }
265
266 /**
267 * {@inheritdoc}
268 */
269 public function getSourceFieldDefinition(MediaTypeInterface $type) {
270 // Nothing to do if no source field is configured yet.
271 $field = $this->configuration['source_field'];
272 if ($field) {
273 // Even if we do know the name of the source field, there is no
274 // guarantee that it already exists.
275 $fields = $this->entityFieldManager->getFieldDefinitions('media', $type->id());
276 return isset($fields[$field]) ? $fields[$field] : NULL;
277 }
278 return NULL;
279 }
280
281 /**
282 * {@inheritdoc}
283 */
284 public function createSourceField(MediaTypeInterface $type) {
285 $storage = $this->getSourceFieldStorage() ?: $this->createSourceFieldStorage();
286 return $this->entityTypeManager
287 ->getStorage('field_config')
288 ->create([
289 'field_storage' => $storage,
290 'bundle' => $type->id(),
291 'label' => $this->pluginDefinition['label'],
292 'required' => TRUE,
293 ]);
294 }
295
296 /**
297 * Determine the name of the source field.
298 *
299 * @return string
300 * The source field name. If one is already stored in configuration, it is
301 * returned. Otherwise, a new, unused one is generated.
302 */
303 protected function getSourceFieldName() {
304 $base_id = 'field_media_' . $this->getPluginId();
305 $tries = 0;
306 $storage = $this->entityTypeManager->getStorage('field_storage_config');
307
308 // Iterate at least once, until no field with the generated ID is found.
309 do {
310 $id = $base_id;
311 // If we've tried before, increment and append the suffix.
312 if ($tries) {
313 $id .= '_' . $tries;
314 }
315 $field = $storage->load('media.' . $id);
316 $tries++;
317 } while ($field);
318
319 return $id;
320 }
321
322 /**
323 * {@inheritdoc}
324 */
325 public function getSourceFieldValue(MediaInterface $media) {
326 $source_field = $this->configuration['source_field'];
327 if (empty($source_field)) {
328 throw new \RuntimeException('Source field for media source is not defined.');
329 }
330
331 /** @var \Drupal\Core\Field\FieldItemInterface $field_item */
332 $field_item = $media->get($source_field)->first();
333 return $field_item->{$field_item->mainPropertyName()};
334 }
335
336 /**
337 * {@inheritdoc}
338 */
339 public function prepareViewDisplay(MediaTypeInterface $type, EntityViewDisplayInterface $display) {
340 $display->setComponent($this->getSourceFieldDefinition($type)->getName());
341 }
342
343 /**
344 * {@inheritdoc}
345 */
346 public function prepareFormDisplay(MediaTypeInterface $type, EntityFormDisplayInterface $display) {
347 // Make sure the source field is placed just after the "name" basefield.
348 $name_component = $display->getComponent('name');
349 $source_field_weight = ($name_component && isset($name_component['weight'])) ? $name_component['weight'] + 5 : -50;
350 $display->setComponent($this->getSourceFieldDefinition($type)->getName(), [
351 'weight' => $source_field_weight,
352 ]);
353 }
354
355 }