inline_media_form-1.0.0-beta1/src/MediaItemAdapter.php
src/MediaItemAdapter.php
<?php
namespace Drupal\inline_media_form;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\ChangedFieldItemList;
use Drupal\inline_media_form\EntitySummarizer\EntitySummarizerFactory;
use Drupal\inline_media_form\EntitySummarizer\EntitySummarizerFactoryInterface;
use Drupal\media\MediaInterface;
/**
* Default adapter for media entities to work with IMF widgets.
*/
class MediaItemAdapter implements EntityNeedsSaveInterface, MediaItemAdapterInterface {
use DependencySerializationTrait;
use EntityNeedsSaveTrait {
isSaveNeeded as baseIsSaveNeeded;
}
/**
* The manager of entity types.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The factory for obtaining summarizers of entity fields.
*
* @var \Drupal\inline_media_form\EntitySummarizer\EntitySummarizerFactory
*/
protected $entitySummarizerFactory;
/**
* The media entity this adapter is wrapping.
*
* @var \Drupal\media\MediaInterface
*/
protected $mediaEntity;
// ===========================================================================
// IoC Constructor
// ===========================================================================
/**
* Creates a new instance of this class, with all dependencies injected.
*
* @param \Drupal\media\MediaInterface $media_entity
* The media entity to wrap.
*
* @return static
* The new instance of this class.
*/
public static function create(MediaInterface $media_entity) {
$entity_type_manager = \Drupal::entityTypeManager();
/** @var \Drupal\inline_media_form\EntitySummarizer\EntitySummarizerFactoryInterface $entity_summarizer_factory */
$entity_summarizer_factory =
\Drupal::service('inline_media_form.entity_summarizer_factory');
return new static(
$entity_type_manager,
$entity_summarizer_factory,
$media_entity
);
}
// ===========================================================================
// Constructor
// ===========================================================================
/**
* Constructor for MediaItemAdapter.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\inline_media_form\EntitySummarizer\EntitySummarizerFactoryInterface $entity_summarizer_factory
* The factory for obtaining summarizers of entity fields.
* @param \Drupal\media\MediaInterface $media_entity
* The media entity to wrap.
*/
public function __construct(
EntityTypeManagerInterface $entity_type_manager,
EntitySummarizerFactoryInterface $entity_summarizer_factory,
MediaInterface $media_entity) {
$this->entityTypeManager = $entity_type_manager;
$this->entitySummarizerFactory = $entity_summarizer_factory;
$this->mediaEntity = $media_entity;
}
// ===========================================================================
// Public API
// ===========================================================================
/**
* {@inheritdoc}
*/
public function getMediaType(): string {
return $this->getMediaEntity()->bundle();
}
/**
* {@inheritdoc}
*
* Media items are marked as needing a save if any of their fields have
* changed.
*/
public function isSaveNeeded() {
return ($this->baseIsSaveNeeded() || $this->isChanged());
}
/**
* {@inheritdoc}
*/
public function isChanged(): bool {
$has_changed = FALSE;
$media_entity = $this->getMediaEntity();
if ($media_entity->isNew()) {
$has_changed = TRUE;
}
else {
$original = $this->loadLatestSavedRevision();
// If the current revision has just been added, we have a change.
if ($original->isNewRevision()) {
$has_changed = TRUE;
}
else {
$field_definitions = $media_entity->getFieldDefinitions();
// Compare field item current values with the original ones to determine
// whether we have changes. We skip computed fields as comparing them
// with their original values might not be possible or be meaningless.
foreach ($field_definitions as $field_name => $definition) {
$field = $media_entity->get($field_name);
// When saving entities in the user interface, the changed timestamp
// is automatically incremented by ContentEntityForm::submitForm()
// even if nothing was actually changed. Thus, the changed time needs
// to be ignored when determining whether there are any actual changes
// in the entity.
if (!($field instanceof ChangedFieldItemList) &&
!$definition->isComputed()) {
$items = $field->filterEmptyItems();
$original_items = $original->get($field_name)->filterEmptyItems();
if (!$items->equals($original_items)) {
// Stop on first change.
$has_changed = TRUE;
break;
}
}
}
}
}
return $has_changed;
}
/**
* {@inheritdoc}
*/
public function isPublished(): bool {
return $this->getMediaEntity()->isPublished();
}
/**
* {@inheritdoc}
*/
public function canView(): bool {
$media_entity = $this->toMediaEntity();
return ($media_entity->access('update') || $media_entity->access('view'));
}
/**
* {@inheritdoc}
*/
public function canModify(): bool {
$media_entity = $this->toMediaEntity();
return $media_entity->access('update');
}
/**
* {@inheritdoc}
*/
public function canDelete(): bool {
$media_entity = $this->toMediaEntity();
// Avoid checking delete access for new entities.
return ($media_entity->isNew() || $media_entity->access('delete'));
}
/**
* {@inheritdoc}
*/
public function saveIfNecessary(): void {
if ($this->isSaveNeeded()) {
$this->getMediaEntity()->save();
$this->markSaved();
}
}
/**
* {@inheritdoc}
*/
public function toSummary(string $form_mode = EntityDisplayRepositoryInterface::DEFAULT_DISPLAY_MODE): string {
$media_entity = $this->getMediaEntity();
$summarizer =
$this->getEntitySummarizerFactory()->getSummarizerFor($media_entity);
return $summarizer->summarize($media_entity, $form_mode);
}
/**
* {@inheritdoc}
*/
public function toFieldSummaries(string $form_mode = EntityDisplayRepositoryInterface::DEFAULT_DISPLAY_MODE): array {
$media_entity = $this->getMediaEntity();
$summarizer =
$this->getEntitySummarizerFactory()->getSummarizerFor($media_entity);
$field_summaries = $summarizer->summarizeFields($media_entity, $form_mode);
return array_values($field_summaries);
}
/**
* {@inheritdoc}
*/
public function toMediaEntity(): MediaInterface {
return $this->getMediaEntity();
}
// ===========================================================================
// Protected Accessors
// ===========================================================================
/**
* Gets the manager for entity types.
*
* @return \Drupal\Core\Entity\EntityTypeManagerInterface
* An instance of the entity type manager interface.
*/
protected function getEntityTypeManager(): EntityTypeManagerInterface {
return $this->entityTypeManager;
}
/**
* Gets the factory for getting objects to summarize entities.
*
* @return \Drupal\inline_media_form\EntitySummarizer\EntitySummarizerFactory
* The new summarizer factory.
*/
protected function getEntitySummarizerFactory(): EntitySummarizerFactory {
return $this->entitySummarizerFactory;
}
/**
* Gets the media entity this adapter is wrapping.
*
* @return \Drupal\media\MediaInterface
* The wrapped media entity.
*/
protected function getMediaEntity() {
return $this->mediaEntity;
}
// ===========================================================================
// Protected API
// ===========================================================================
/**
* Loads the copy of the media entity that was last saved to the database.
*
* @return \Drupal\media\MediaInterface
* The latest saved revision of the media file.
*/
protected function loadLatestSavedRevision(): MediaInterface {
$media_entity = $this->getMediaEntity();
// $media_entity->original only exists during save. If it exists we re-use
// it here for performance reasons.
/** @var \Drupal\media\MediaInterface $original */
if (empty($media_entity->original)) {
$entity_type_id = $media_entity->getEntityTypeId();
$revision_id = $media_entity->getLoadedRevisionId();
$entity_type_manager = $this->getEntityTypeManager();
try {
$storage = $entity_type_manager->getStorage($entity_type_id);
}
catch (InvalidPluginDefinitionException | PluginNotFoundException $ex) {
// Should never happen -- otherwise, how did we even get this entity in
// the first place?!
throw new \RuntimeException(
'Could not load storage plug-in for existing entity type: ' . $ex->getMessage(),
0,
$ex
);
}
$original = $storage->loadRevision($revision_id);
}
else {
$original = $media_entity->original;
}
return $original;
}
}
