Mercurial > hg > isophonics-drupal-site
comparison core/modules/media/src/Entity/Media.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | 1fec387a4317 |
children | af1871eacc83 |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
27 * singular = "@count media item", | 27 * singular = "@count media item", |
28 * plural = "@count media items" | 28 * plural = "@count media items" |
29 * ), | 29 * ), |
30 * bundle_label = @Translation("Media type"), | 30 * bundle_label = @Translation("Media type"), |
31 * handlers = { | 31 * handlers = { |
32 * "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage", | 32 * "storage" = "Drupal\media\MediaStorage", |
33 * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", | 33 * "view_builder" = "Drupal\Core\Entity\EntityViewBuilder", |
34 * "list_builder" = "Drupal\media\MediaListBuilder", | 34 * "list_builder" = "Drupal\media\MediaListBuilder", |
35 * "access" = "Drupal\media\MediaAccessControlHandler", | 35 * "access" = "Drupal\media\MediaAccessControlHandler", |
36 * "form" = { | 36 * "form" = { |
37 * "default" = "Drupal\media\MediaForm", | 37 * "default" = "Drupal\media\MediaForm", |
38 * "add" = "Drupal\media\MediaForm", | 38 * "add" = "Drupal\media\MediaForm", |
39 * "edit" = "Drupal\media\MediaForm", | 39 * "edit" = "Drupal\media\MediaForm", |
40 * "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm", | 40 * "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm", |
41 * "delete-multiple-confirm" = "Drupal\Core\Entity\Form\DeleteMultipleForm", | |
41 * }, | 42 * }, |
42 * "translation" = "Drupal\content_translation\ContentTranslationHandler", | 43 * "translation" = "Drupal\content_translation\ContentTranslationHandler", |
43 * "views_data" = "Drupal\media\MediaViewsData", | 44 * "views_data" = "Drupal\media\MediaViewsData", |
44 * "route_provider" = { | 45 * "route_provider" = { |
45 * "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", | 46 * "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider", |
74 * "add-page" = "/media/add", | 75 * "add-page" = "/media/add", |
75 * "add-form" = "/media/add/{media_type}", | 76 * "add-form" = "/media/add/{media_type}", |
76 * "canonical" = "/media/{media}", | 77 * "canonical" = "/media/{media}", |
77 * "collection" = "/admin/content/media", | 78 * "collection" = "/admin/content/media", |
78 * "delete-form" = "/media/{media}/delete", | 79 * "delete-form" = "/media/{media}/delete", |
80 * "delete-multiple-form" = "/media/delete", | |
79 * "edit-form" = "/media/{media}/edit", | 81 * "edit-form" = "/media/{media}/edit", |
80 * "revision" = "/media/{media}/revisions/{media_revision}/view", | 82 * "revision" = "/media/{media}/revisions/{media_revision}/view", |
81 * } | 83 * } |
82 * ) | 84 * ) |
83 */ | 85 */ |
87 | 89 |
88 /** | 90 /** |
89 * {@inheritdoc} | 91 * {@inheritdoc} |
90 */ | 92 */ |
91 public function getName() { | 93 public function getName() { |
92 $name = $this->get('name'); | 94 $name = $this->getEntityKey('label'); |
93 | 95 |
94 if ($name->isEmpty()) { | 96 if (empty($name)) { |
95 $media_source = $this->getSource(); | 97 $media_source = $this->getSource(); |
96 return $media_source->getMetadata($this, $media_source->getPluginDefinition()['default_name_metadata_attribute']); | 98 return $media_source->getMetadata($this, $media_source->getPluginDefinition()['default_name_metadata_attribute']); |
97 } | 99 } |
98 else { | 100 |
99 return $name->value; | 101 return $name; |
100 } | |
101 } | 102 } |
102 | 103 |
103 /** | 104 /** |
104 * {@inheritdoc} | 105 * {@inheritdoc} |
105 */ | 106 */ |
177 * @todo There has been some disagreement about how to handle updates to | 178 * @todo There has been some disagreement about how to handle updates to |
178 * thumbnails. We need to decide on what the API will be for this. | 179 * thumbnails. We need to decide on what the API will be for this. |
179 * https://www.drupal.org/node/2878119 | 180 * https://www.drupal.org/node/2878119 |
180 */ | 181 */ |
181 protected function updateThumbnail($from_queue = FALSE) { | 182 protected function updateThumbnail($from_queue = FALSE) { |
182 $file_storage = \Drupal::service('entity_type.manager')->getStorage('file'); | 183 $this->thumbnail->target_id = $this->loadThumbnail($this->getThumbnailUri($from_queue))->id(); |
183 $thumbnail_uri = $this->getThumbnailUri($from_queue); | 184 |
184 $existing = $file_storage->getQuery() | 185 // Set the thumbnail alt. |
185 ->condition('uri', $thumbnail_uri) | 186 $media_source = $this->getSource(); |
186 ->execute(); | 187 $plugin_definition = $media_source->getPluginDefinition(); |
187 | 188 |
189 $this->thumbnail->alt = ''; | |
190 if (!empty($plugin_definition['thumbnail_alt_metadata_attribute'])) { | |
191 $this->thumbnail->alt = $media_source->getMetadata($this, $plugin_definition['thumbnail_alt_metadata_attribute']); | |
192 } | |
193 | |
194 return $this; | |
195 } | |
196 | |
197 /** | |
198 * Loads the file entity for the thumbnail. | |
199 * | |
200 * If the file entity does not exist, it will be created. | |
201 * | |
202 * @param string $thumbnail_uri | |
203 * (optional) The URI of the thumbnail, used to load or create the file | |
204 * entity. If omitted, the default thumbnail URI will be used. | |
205 * | |
206 * @return \Drupal\file\FileInterface | |
207 * The thumbnail file entity. | |
208 */ | |
209 protected function loadThumbnail($thumbnail_uri = NULL) { | |
210 $values = [ | |
211 'uri' => $thumbnail_uri ?: $this->getDefaultThumbnailUri(), | |
212 ]; | |
213 | |
214 $file_storage = $this->entityTypeManager()->getStorage('file'); | |
215 | |
216 $existing = $file_storage->loadByProperties($values); | |
188 if ($existing) { | 217 if ($existing) { |
189 $this->thumbnail->target_id = reset($existing); | 218 $file = reset($existing); |
190 } | 219 } |
191 else { | 220 else { |
192 /** @var \Drupal\file\FileInterface $file */ | 221 /** @var \Drupal\file\FileInterface $file */ |
193 $file = $file_storage->create(['uri' => $thumbnail_uri]); | 222 $file = $file_storage->create($values); |
194 if ($owner = $this->getOwner()) { | 223 if ($owner = $this->getOwner()) { |
195 $file->setOwner($owner); | 224 $file->setOwner($owner); |
196 } | 225 } |
197 $file->setPermanent(); | 226 $file->setPermanent(); |
198 $file->save(); | 227 $file->save(); |
199 $this->thumbnail->target_id = $file->id(); | 228 } |
200 } | 229 return $file; |
201 | 230 } |
202 // Set the thumbnail alt. | 231 |
203 $media_source = $this->getSource(); | 232 /** |
204 $plugin_definition = $media_source->getPluginDefinition(); | 233 * Returns the URI of the default thumbnail. |
205 if (!empty($plugin_definition['thumbnail_alt_metadata_attribute'])) { | 234 * |
206 $this->thumbnail->alt = $media_source->getMetadata($this, $plugin_definition['thumbnail_alt_metadata_attribute']); | 235 * @return string |
207 } | 236 * The default thumbnail URI. |
208 else { | 237 */ |
209 $this->thumbnail->alt = $this->t('Thumbnail', [], ['langcode' => $this->langcode->value]); | 238 protected function getDefaultThumbnailUri() { |
210 } | 239 $default_thumbnail_filename = $this->getSource()->getPluginDefinition()['default_thumbnail_filename']; |
211 | 240 return \Drupal::config('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename; |
212 // Set the thumbnail title. | |
213 if (!empty($plugin_definition['thumbnail_title_metadata_attribute'])) { | |
214 $this->thumbnail->title = $media_source->getMetadata($this, $plugin_definition['thumbnail_title_metadata_attribute']); | |
215 } | |
216 else { | |
217 $this->thumbnail->title = $this->label(); | |
218 } | |
219 | |
220 return $this; | |
221 } | 241 } |
222 | 242 |
223 /** | 243 /** |
224 * Updates the queued thumbnail for the media item. | 244 * Updates the queued thumbnail for the media item. |
225 * | 245 * |
253 * @internal | 273 * @internal |
254 */ | 274 */ |
255 protected function getThumbnailUri($from_queue) { | 275 protected function getThumbnailUri($from_queue) { |
256 $thumbnails_queued = $this->bundle->entity->thumbnailDownloadsAreQueued(); | 276 $thumbnails_queued = $this->bundle->entity->thumbnailDownloadsAreQueued(); |
257 if ($thumbnails_queued && $this->isNew()) { | 277 if ($thumbnails_queued && $this->isNew()) { |
258 $default_thumbnail_filename = $this->getSource()->getPluginDefinition()['default_thumbnail_filename']; | 278 return $this->getDefaultThumbnailUri(); |
259 $thumbnail_uri = \Drupal::service('config.factory')->get('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename; | |
260 } | 279 } |
261 elseif ($thumbnails_queued && !$from_queue) { | 280 elseif ($thumbnails_queued && !$from_queue) { |
262 $thumbnail_uri = $this->get('thumbnail')->entity->getFileUri(); | 281 return $this->get('thumbnail')->entity->getFileUri(); |
263 } | 282 } |
264 else { | 283 |
265 $thumbnail_uri = $this->getSource()->getMetadata($this, $this->getSource()->getPluginDefinition()['thumbnail_uri_metadata_attribute']); | 284 $source = $this->getSource(); |
266 } | 285 return $source->getMetadata($this, $source->getPluginDefinition()['thumbnail_uri_metadata_attribute']); |
267 | |
268 return $thumbnail_uri; | |
269 } | 286 } |
270 | 287 |
271 /** | 288 /** |
272 * Determines if the source field value has changed. | 289 * Determines if the source field value has changed. |
273 * | 290 * |
300 /** | 317 /** |
301 * {@inheritdoc} | 318 * {@inheritdoc} |
302 */ | 319 */ |
303 public function preSave(EntityStorageInterface $storage) { | 320 public function preSave(EntityStorageInterface $storage) { |
304 parent::preSave($storage); | 321 parent::preSave($storage); |
322 | |
323 // If no thumbnail has been explicitly set, use the default thumbnail. | |
324 if ($this->get('thumbnail')->isEmpty()) { | |
325 $this->thumbnail->target_id = $this->loadThumbnail()->id(); | |
326 } | |
327 } | |
328 | |
329 /** | |
330 * {@inheritdoc} | |
331 */ | |
332 public function postSave(EntityStorageInterface $storage, $update = TRUE) { | |
333 parent::postSave($storage, $update); | |
334 $is_new = !$update; | |
335 foreach ($this->translations as $langcode => $data) { | |
336 if ($this->hasTranslation($langcode)) { | |
337 $translation = $this->getTranslation($langcode); | |
338 if ($translation->bundle->entity->thumbnailDownloadsAreQueued() && $translation->shouldUpdateThumbnail($is_new)) { | |
339 \Drupal::queue('media_entity_thumbnail')->createItem(['id' => $translation->id()]); | |
340 } | |
341 } | |
342 } | |
343 } | |
344 | |
345 /** | |
346 * {@inheritdoc} | |
347 */ | |
348 public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) { | |
349 parent::preSaveRevision($storage, $record); | |
350 | |
351 $is_new_revision = $this->isNewRevision(); | |
352 if (!$is_new_revision && isset($this->original) && empty($record->revision_log_message)) { | |
353 // If we are updating an existing media item without adding a | |
354 // new revision, we need to make sure $entity->revision_log_message is | |
355 // reset whenever it is empty. | |
356 // Therefore, this code allows us to avoid clobbering an existing log | |
357 // entry with an empty one. | |
358 $record->revision_log_message = $this->original->revision_log_message->value; | |
359 } | |
360 | |
361 if ($is_new_revision) { | |
362 $record->revision_created = self::getRequestTime(); | |
363 } | |
364 } | |
365 | |
366 /** | |
367 * Sets the media entity's field values from the source's metadata. | |
368 * | |
369 * Fetching the metadata could be slow (e.g., if requesting it from a remote | |
370 * API), so this is called by \Drupal\media\MediaStorage::save() prior to it | |
371 * beginning the database transaction, whereas static::preSave() executes | |
372 * after the transaction has already started. | |
373 * | |
374 * @internal | |
375 * Expose this as an API in | |
376 * https://www.drupal.org/project/drupal/issues/2992426. | |
377 */ | |
378 public function prepareSave() { | |
379 // @todo If the source plugin talks to a remote API (e.g. oEmbed), this code | |
380 // might be performing a fair number of HTTP requests. This is dangerously | |
381 // brittle and should probably be handled by a queue, to avoid doing HTTP | |
382 // operations during entity save. See | |
383 // https://www.drupal.org/project/drupal/issues/2976875 for more. | |
384 | |
385 // In order for metadata to be mapped correctly, $this->original must be | |
386 // set. However, that is only set once parent::save() is called, so work | |
387 // around that by setting it here. | |
388 if (!isset($this->original) && $id = $this->id()) { | |
389 $this->original = $this->entityTypeManager() | |
390 ->getStorage('media') | |
391 ->loadUnchanged($id); | |
392 } | |
305 | 393 |
306 $media_source = $this->getSource(); | 394 $media_source = $this->getSource(); |
307 foreach ($this->translations as $langcode => $data) { | 395 foreach ($this->translations as $langcode => $data) { |
308 if ($this->hasTranslation($langcode)) { | 396 if ($this->hasTranslation($langcode)) { |
309 $translation = $this->getTranslation($langcode); | 397 $translation = $this->getTranslation($langcode); |
321 if ($translation->get('name')->isEmpty()) { | 409 if ($translation->get('name')->isEmpty()) { |
322 $translation->setName($translation->getName()); | 410 $translation->setName($translation->getName()); |
323 } | 411 } |
324 | 412 |
325 // Set thumbnail. | 413 // Set thumbnail. |
326 if ($translation->shouldUpdateThumbnail()) { | 414 if ($translation->shouldUpdateThumbnail($this->isNew())) { |
327 $translation->updateThumbnail(); | 415 $translation->updateThumbnail(); |
328 } | 416 } |
329 } | 417 } |
330 } | |
331 } | |
332 | |
333 /** | |
334 * {@inheritdoc} | |
335 */ | |
336 public function postSave(EntityStorageInterface $storage, $update = TRUE) { | |
337 parent::postSave($storage, $update); | |
338 $is_new = !$update; | |
339 foreach ($this->translations as $langcode => $data) { | |
340 if ($this->hasTranslation($langcode)) { | |
341 $translation = $this->getTranslation($langcode); | |
342 if ($translation->bundle->entity->thumbnailDownloadsAreQueued() && $translation->shouldUpdateThumbnail($is_new)) { | |
343 \Drupal::queue('media_entity_thumbnail')->createItem(['id' => $translation->id()]); | |
344 } | |
345 } | |
346 } | |
347 } | |
348 | |
349 /** | |
350 * {@inheritdoc} | |
351 */ | |
352 public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) { | |
353 parent::preSaveRevision($storage, $record); | |
354 | |
355 $is_new_revision = $this->isNewRevision(); | |
356 if (!$is_new_revision && isset($this->original) && empty($record->revision_log_message)) { | |
357 // If we are updating an existing media item without adding a | |
358 // new revision, we need to make sure $entity->revision_log_message is | |
359 // reset whenever it is empty. | |
360 // Therefore, this code allows us to avoid clobbering an existing log | |
361 // entry with an empty one. | |
362 $record->revision_log_message = $this->original->revision_log_message->value; | |
363 } | |
364 | |
365 if ($is_new_revision) { | |
366 $record->revision_created = self::getRequestTime(); | |
367 } | 418 } |
368 } | 419 } |
369 | 420 |
370 /** | 421 /** |
371 * {@inheritdoc} | 422 * {@inheritdoc} |