View source
<?php
namespace Drupal\media;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Entity\Display\EntityFormDisplayInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class MediaSourceBase extends PluginBase implements MediaSourceInterface, ContainerFactoryPluginInterface {
protected $label;
protected $entityTypeManager;
protected $entityFieldManager;
protected $fieldTypeManager;
protected $configFactory;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, ConfigFactoryInterface $config_factory) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->entityFieldManager = $entity_field_manager;
$this->fieldTypeManager = $field_type_manager;
$this->configFactory = $config_factory;
$this
->setConfiguration($configuration);
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('entity_field.manager'), $container
->get('plugin.manager.field.field_type'), $container
->get('config.factory'));
}
public function setConfiguration(array $configuration) {
$this->configuration = NestedArray::mergeDeep($this
->defaultConfiguration(), $configuration);
}
public function getConfiguration() {
return $this->configuration;
}
public function defaultConfiguration() {
return [
'source_field' => '',
];
}
public function getMetadata(MediaInterface $media, $attribute_name) {
switch ($attribute_name) {
case 'default_name':
return 'media:' . $media
->bundle() . ':' . $media
->uuid();
case 'thumbnail_uri':
$default_thumbnail_filename = $this->pluginDefinition['default_thumbnail_filename'];
return $this->configFactory
->get('media.settings')
->get('icon_base_uri') . '/' . $default_thumbnail_filename;
}
return NULL;
}
public function calculateDependencies() {
return [];
}
protected function getSourceFieldOptions() {
$options = [];
foreach ($this->entityFieldManager
->getFieldStorageDefinitions('media') as $field_name => $field) {
$allowed_type = in_array($field
->getType(), $this->pluginDefinition['allowed_field_types'], TRUE);
if ($allowed_type && !$field
->isBaseField()) {
$options[$field_name] = $field
->getLabel();
}
}
return $options;
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$options = $this
->getSourceFieldOptions();
$form['source_field'] = [
'#type' => 'select',
'#title' => $this
->t('Field with source information'),
'#default_value' => $this->configuration['source_field'],
'#empty_option' => $this
->t('- Create -'),
'#options' => $options,
'#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.'),
];
if (!$options && $form_state
->get('operation') === 'add') {
$form['source_field']['#access'] = FALSE;
$field_definition = $this->fieldTypeManager
->getDefinition(reset($this->pluginDefinition['allowed_field_types']));
$form['source_field_message'] = [
'#markup' => $this
->t('%field_type field will be automatically created on this type to store the essential information about the media item.', [
'%field_type' => $field_definition['label'],
]),
];
}
elseif ($form_state
->get('operation') === 'edit') {
$form['source_field']['#access'] = FALSE;
$fields = $this->entityFieldManager
->getFieldDefinitions('media', $form_state
->get('type')
->id());
$form['source_field_message'] = [
'#markup' => $this
->t('%field_name field is used to store the essential information about the media item.', [
'%field_name' => $fields[$this->configuration['source_field']]
->getLabel(),
]),
];
}
return $form;
}
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
}
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
foreach (array_intersect_key($form_state
->getValues(), $this->configuration) as $config_key => $config_value) {
$this->configuration[$config_key] = $config_value;
}
if (empty($this->configuration['source_field'])) {
$field_storage = $this
->createSourceFieldStorage();
$field_storage
->save();
$this->configuration['source_field'] = $field_storage
->getName();
}
}
protected function createSourceFieldStorage() {
return $this->entityTypeManager
->getStorage('field_storage_config')
->create([
'entity_type' => 'media',
'field_name' => $this
->getSourceFieldName(),
'type' => reset($this->pluginDefinition['allowed_field_types']),
]);
}
protected function getSourceFieldStorage() {
$field = $this->configuration['source_field'];
if ($field) {
$fields = $this->entityFieldManager
->getFieldStorageDefinitions('media');
return isset($fields[$field]) ? $fields[$field] : NULL;
}
return NULL;
}
public function getSourceFieldDefinition(MediaTypeInterface $type) {
$field = $this->configuration['source_field'];
if ($field) {
$fields = $this->entityFieldManager
->getFieldDefinitions('media', $type
->id());
return isset($fields[$field]) ? $fields[$field] : NULL;
}
return NULL;
}
public function createSourceField(MediaTypeInterface $type) {
$storage = $this
->getSourceFieldStorage() ?: $this
->createSourceFieldStorage();
return $this->entityTypeManager
->getStorage('field_config')
->create([
'field_storage' => $storage,
'bundle' => $type
->id(),
'label' => $this->pluginDefinition['label'],
'required' => TRUE,
]);
}
protected function getSourceFieldName() {
$base_id = 'field_media_' . str_replace(static::DERIVATIVE_SEPARATOR, '_', $this
->getPluginId());
$tries = 0;
$storage = $this->entityTypeManager
->getStorage('field_storage_config');
do {
$id = $base_id;
if ($tries) {
$id .= '_' . $tries;
}
$field = $storage
->load('media.' . $id);
$tries++;
} while ($field);
return $id;
}
public function getSourceFieldValue(MediaInterface $media) {
$source_field = $this->configuration['source_field'];
if (empty($source_field)) {
throw new \RuntimeException('Source field for media source is not defined.');
}
$items = $media
->get($source_field);
if ($items
->isEmpty()) {
return NULL;
}
$field_item = $items
->first();
return $field_item->{$field_item
->mainPropertyName()};
}
public function prepareViewDisplay(MediaTypeInterface $type, EntityViewDisplayInterface $display) {
$display
->setComponent($this
->getSourceFieldDefinition($type)
->getName(), [
'label' => 'visually_hidden',
]);
}
public function prepareFormDisplay(MediaTypeInterface $type, EntityFormDisplayInterface $display) {
$name_component = $display
->getComponent('name');
$source_field_weight = $name_component && isset($name_component['weight']) ? $name_component['weight'] + 5 : -50;
$display
->setComponent($this
->getSourceFieldDefinition($type)
->getName(), [
'weight' => $source_field_weight,
]);
}
}