Eli Zoller
4 years ago
committed by
GitHub
9 changed files with 697 additions and 0 deletions
@ -0,0 +1,28 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora_audio\Plugin\Field\FieldFormatter; |
||||||
|
|
||||||
|
use Drupal\islandora\Plugin\Field\FieldFormatter\IslandoraFileMediaFormatterBase; |
||||||
|
|
||||||
|
/** |
||||||
|
* Plugin implementation of the 'file_audio' formatter. |
||||||
|
* |
||||||
|
* @FieldFormatter( |
||||||
|
* id = "islandora_file_audio", |
||||||
|
* label = @Translation("Audio with Captions"), |
||||||
|
* description = @Translation("Display the file using an HTML5 audio tag."), |
||||||
|
* field_types = { |
||||||
|
* "file" |
||||||
|
* } |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class IslandoraFileAudioFormatter extends IslandoraFileMediaFormatterBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function getMediaType() { |
||||||
|
return 'audio'; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,28 @@ |
|||||||
|
{# |
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Default theme implementation to display the file entity as an audio tag. |
||||||
|
* |
||||||
|
* Available variables: |
||||||
|
* - attributes: An array of HTML attributes, intended to be added to the |
||||||
|
* audio tag. |
||||||
|
* - files: And array of files to be added as sources for the audio tag. Each |
||||||
|
* element is an array with the following elements: |
||||||
|
* - file: The full file object. |
||||||
|
* - source_attributes: An array of HTML attributes for to be added to the |
||||||
|
* source tag. |
||||||
|
* |
||||||
|
* @ingroup themeable |
||||||
|
*/ |
||||||
|
#} |
||||||
|
<audio {{ attributes }}> |
||||||
|
{% for file in files %} |
||||||
|
<source {{ file.source_attributes }} /> |
||||||
|
{% if tracks %} |
||||||
|
{% for track in tracks %} |
||||||
|
<track {{ track.track_attributes }} |
||||||
|
{% endfor %} |
||||||
|
{% endif %} |
||||||
|
{% endfor %} |
||||||
|
</audio> |
||||||
|
|
@ -0,0 +1,95 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora_video\Plugin\Field\FieldFormatter; |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\islandora\Plugin\Field\FieldFormatter\IslandoraFileMediaFormatterBase; |
||||||
|
|
||||||
|
/** |
||||||
|
* Plugin implementation of the 'file_video' formatter. |
||||||
|
* |
||||||
|
* @FieldFormatter( |
||||||
|
* id = "islandora_file_video", |
||||||
|
* label = @Translation("Video with Captions"), |
||||||
|
* description = @Translation("Display the file using an HTML5 video tag."), |
||||||
|
* field_types = { |
||||||
|
* "file" |
||||||
|
* } |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class IslandoraFileVideoFormatter extends IslandoraFileMediaFormatterBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function getMediaType() { |
||||||
|
return 'video'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function defaultSettings() { |
||||||
|
return [ |
||||||
|
'muted' => FALSE, |
||||||
|
'width' => 640, |
||||||
|
'height' => 480, |
||||||
|
] + parent::defaultSettings(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function settingsForm(array $form, FormStateInterface $form_state) { |
||||||
|
return parent::settingsForm($form, $form_state) + [ |
||||||
|
'muted' => [ |
||||||
|
'#title' => $this->t('Muted'), |
||||||
|
'#type' => 'checkbox', |
||||||
|
'#default_value' => $this->getSetting('muted'), |
||||||
|
], |
||||||
|
'width' => [ |
||||||
|
'#type' => 'number', |
||||||
|
'#title' => $this->t('Width'), |
||||||
|
'#default_value' => $this->getSetting('width'), |
||||||
|
'#size' => 5, |
||||||
|
'#maxlength' => 5, |
||||||
|
'#field_suffix' => $this->t('pixels'), |
||||||
|
'#min' => 0, |
||||||
|
'#required' => TRUE, |
||||||
|
], |
||||||
|
'height' => [ |
||||||
|
'#type' => 'number', |
||||||
|
'#title' => $this->t('Height'), |
||||||
|
'#default_value' => $this->getSetting('height'), |
||||||
|
'#size' => 5, |
||||||
|
'#maxlength' => 5, |
||||||
|
'#field_suffix' => $this->t('pixels'), |
||||||
|
'#min' => 0, |
||||||
|
'#required' => TRUE, |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function settingsSummary() { |
||||||
|
$summary = parent::settingsSummary(); |
||||||
|
$summary[] = $this->t('Muted: %muted', ['%muted' => $this->getSetting('muted') ? $this->t('yes') : $this->t('no')]); |
||||||
|
$summary[] = $this->t('Size: %width x %height pixels', [ |
||||||
|
'%width' => $this->getSetting('width'), |
||||||
|
'%height' => $this->getSetting('height'), |
||||||
|
]); |
||||||
|
return $summary; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
protected function prepareAttributes(array $additional_attributes = []) { |
||||||
|
return parent::prepareAttributes(['muted']) |
||||||
|
->setAttribute('width', $this->getSetting('width')) |
||||||
|
->setAttribute('height', $this->getSetting('height')); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,27 @@ |
|||||||
|
{# |
||||||
|
/** |
||||||
|
* @file |
||||||
|
* Default theme implementation to display the file entity as a video tag. |
||||||
|
* |
||||||
|
* Available variables: |
||||||
|
* - attributes: An array of HTML attributes, intended to be added to the |
||||||
|
* video tag. |
||||||
|
* - files: And array of files to be added as sources for the video tag. Each |
||||||
|
* element is an array with the following elements: |
||||||
|
* - file: The full file object. |
||||||
|
* - source_attributes: An array of HTML attributes for to be added to the |
||||||
|
* source tag. |
||||||
|
* |
||||||
|
* @ingroup themeable |
||||||
|
*/ |
||||||
|
#} |
||||||
|
<video {{ attributes }}> |
||||||
|
{% for file in files %} |
||||||
|
<source {{ file.source_attributes }} /> |
||||||
|
{% endfor %} |
||||||
|
{% if tracks %} |
||||||
|
{% for track in tracks %} |
||||||
|
<track {{ track.track_attributes }} |
||||||
|
{% endfor %} |
||||||
|
{% endif %} |
||||||
|
</video> |
@ -0,0 +1,92 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora\Plugin\Field\FieldFormatter; |
||||||
|
|
||||||
|
use Drupal\file\Plugin\Field\FieldFormatter\FileMediaFormatterBase; |
||||||
|
use Drupal\Core\Field\EntityReferenceFieldItemListInterface; |
||||||
|
use Drupal\Core\Field\FieldItemListInterface; |
||||||
|
use Drupal\Core\Cache\Cache; |
||||||
|
use Drupal\Core\Template\Attribute; |
||||||
|
|
||||||
|
/** |
||||||
|
* Extension of FileMediaFormatterBase that enables captions. |
||||||
|
*/ |
||||||
|
abstract class IslandoraFileMediaFormatterBase extends FileMediaFormatterBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function viewElements(FieldItemListInterface $items, $langcode) { |
||||||
|
$elements = []; |
||||||
|
|
||||||
|
$source_files = $this->getSourceFiles($items, $langcode); |
||||||
|
$track_files = $this->getTrackFiles($items, $langcode); |
||||||
|
if (!empty($source_files)) { |
||||||
|
$attributes = $this->prepareAttributes(); |
||||||
|
foreach ($source_files as $delta => $files) { |
||||||
|
$elements[$delta] = [ |
||||||
|
'#theme' => $this->getPluginId(), |
||||||
|
'#attributes' => $attributes, |
||||||
|
'#files' => $files, |
||||||
|
'#tracks' => isset($track_files[$delta]) ? $track_files[$delta] : [], |
||||||
|
'#cache' => ['tags' => []], |
||||||
|
]; |
||||||
|
|
||||||
|
$cache_tags = []; |
||||||
|
foreach ($files as $file) { |
||||||
|
$cache_tags = Cache::mergeTags($cache_tags, $file['file']->getCacheTags()); |
||||||
|
} |
||||||
|
$elements[$delta]['#cache']['tags'] = $cache_tags; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return $elements; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets the track files with attributes. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Field\EntityReferenceFieldItemListInterface $items |
||||||
|
* The items. |
||||||
|
* @param string $langcode |
||||||
|
* The langcode. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Numerically indexed array, which again contains an associative array with |
||||||
|
* the following key/values: |
||||||
|
* - file => \Drupal\file\Entity\File |
||||||
|
* - track_attributes => \Drupal\Core\Template\Attribute |
||||||
|
*/ |
||||||
|
protected function getTrackFiles(EntityReferenceFieldItemListInterface $items, $langcode) { |
||||||
|
$track_files = []; |
||||||
|
$media_entity = $items->getParent()->getEntity(); |
||||||
|
$fields = $media_entity->getFields(); |
||||||
|
foreach ($fields as $key => $field) { |
||||||
|
$definition = $field->getFieldDefinition(); |
||||||
|
if (method_exists($definition, 'get')) { |
||||||
|
if ($definition->get('field_type') == 'media_track') { |
||||||
|
// Extract the info for each track. |
||||||
|
$entities = $field->referencedEntities(); |
||||||
|
$values = $field->getValue(); |
||||||
|
foreach ($entities as $delta => $file) { |
||||||
|
$track_attributes = new Attribute(); |
||||||
|
$track_attributes |
||||||
|
->setAttribute('src', $file->createFileUrl()) |
||||||
|
->setAttribute('srclang', $values[$delta]['srclang']) |
||||||
|
->setAttribute('label', $values[$delta]['label']) |
||||||
|
->setAttribute('kind', $values[$delta]['kind']); |
||||||
|
if ($values[$delta]['default']) { |
||||||
|
$track_attributes->setAttribute('default', 'default'); |
||||||
|
} |
||||||
|
$track_files[0][] = [ |
||||||
|
'file' => $file, |
||||||
|
'track_attributes' => $track_attributes, |
||||||
|
]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return $track_files; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,224 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora\Plugin\Field\FieldType; |
||||||
|
|
||||||
|
use Drupal\Core\Field\FieldDefinitionInterface; |
||||||
|
use Drupal\Core\Field\FieldStorageDefinitionInterface; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\Core\StreamWrapper\StreamWrapperInterface; |
||||||
|
use Drupal\Core\TypedData\DataDefinition; |
||||||
|
use Drupal\file\Plugin\Field\FieldType\FileItem; |
||||||
|
|
||||||
|
/** |
||||||
|
* Plugin implementation of the 'media_track' field type. |
||||||
|
* |
||||||
|
* @FieldType( |
||||||
|
* id = "media_track", |
||||||
|
* label = @Translation("Media track"), |
||||||
|
* description = @Translation("This field stores the ID of a media track file as an integer value."), |
||||||
|
* category = @Translation("Reference"), |
||||||
|
* default_widget = "media_track", |
||||||
|
* default_formatter = "file_default", |
||||||
|
* column_groups = { |
||||||
|
* "file" = { |
||||||
|
* "label" = @Translation("File"), |
||||||
|
* "columns" = { |
||||||
|
* "target_id" |
||||||
|
* }, |
||||||
|
* "require_all_groups_for_translation" = TRUE |
||||||
|
* }, |
||||||
|
* "label" = { |
||||||
|
* "label" = @Translation("Track label"), |
||||||
|
* "translatable" = FALSE, |
||||||
|
* }, |
||||||
|
* "kind" = { |
||||||
|
* "label" = @Translation("Kind"), |
||||||
|
* "translatable" = FALSE |
||||||
|
* }, |
||||||
|
* "srclang" = { |
||||||
|
* "label" = @Translation("SRC Language"), |
||||||
|
* "translatable" = FALSE |
||||||
|
* }, |
||||||
|
* "default" = { |
||||||
|
* "label" = @Translation("Default"), |
||||||
|
* "translatable" = FALSE |
||||||
|
* }, |
||||||
|
* }, |
||||||
|
* list_class = "\Drupal\file\Plugin\Field\FieldType\FileFieldItemList", |
||||||
|
* constraints = {"ReferenceAccess" = {}, "FileValidation" = {}} |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class MediaTrackItem extends FileItem { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function defaultFieldSettings() { |
||||||
|
$settings = [ |
||||||
|
'file_extensions' => 'vtt', |
||||||
|
'languages' => 'installed', |
||||||
|
] + parent::defaultFieldSettings(); |
||||||
|
|
||||||
|
unset($settings['description_field']); |
||||||
|
return $settings; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function schema(FieldStorageDefinitionInterface $field_definition) { |
||||||
|
return [ |
||||||
|
'columns' => [ |
||||||
|
'target_id' => [ |
||||||
|
'description' => 'The ID of the file entity.', |
||||||
|
'type' => 'int', |
||||||
|
'unsigned' => TRUE, |
||||||
|
], |
||||||
|
'label' => [ |
||||||
|
'description' => "Label of track, for the track's 'label' attribute.", |
||||||
|
'type' => 'varchar', |
||||||
|
'length' => 128, |
||||||
|
], |
||||||
|
'kind' => [ |
||||||
|
'description' => "Type of track, for the track's 'kind' attribute.", |
||||||
|
'type' => 'varchar', |
||||||
|
'length' => 20, |
||||||
|
], |
||||||
|
'srclang' => [ |
||||||
|
'description' => "Language of track, for the track's 'srclang' attribute.", |
||||||
|
'type' => 'varchar', |
||||||
|
'length' => 20, |
||||||
|
], |
||||||
|
'default' => [ |
||||||
|
'description' => "Flag to indicate whether to use this as the default track of this kind.", |
||||||
|
'type' => 'int', |
||||||
|
'size' => 'tiny', |
||||||
|
'unsigned' => TRUE, |
||||||
|
'default' => 0, |
||||||
|
], |
||||||
|
], |
||||||
|
'indexes' => [ |
||||||
|
'target_id' => ['target_id'], |
||||||
|
], |
||||||
|
'foreign keys' => [ |
||||||
|
'target_id' => [ |
||||||
|
'table' => 'file_managed', |
||||||
|
'columns' => ['target_id' => 'fid'], |
||||||
|
], |
||||||
|
], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function propertyDefinitions(FieldStorageDefinitionInterface $field_definition) { |
||||||
|
$properties = parent::propertyDefinitions($field_definition); |
||||||
|
|
||||||
|
unset($properties['display']); |
||||||
|
unset($properties['description']); |
||||||
|
|
||||||
|
$properties['label'] = DataDefinition::create('string') |
||||||
|
->setLabel(t('Label')) |
||||||
|
->setDescription(t("Label of track, for the track's 'label' attribute.")); |
||||||
|
|
||||||
|
$properties['kind'] = DataDefinition::create('string') |
||||||
|
->setLabel(t('Track kind')) |
||||||
|
->setDescription(t("Type of track, for the track's 'kind' attribute.")); |
||||||
|
|
||||||
|
$properties['srclang'] = DataDefinition::create('string') |
||||||
|
->setLabel(t('SRC Language')) |
||||||
|
->setDescription(t("Language of track, for the track's 'srclang' attribute.")); |
||||||
|
|
||||||
|
$properties['default'] = DataDefinition::create('boolean') |
||||||
|
->setLabel(t('Default')) |
||||||
|
->setDescription(t("Flag to indicate whether to use this as the default track of this kind.")); |
||||||
|
|
||||||
|
return $properties; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) { |
||||||
|
$element = []; |
||||||
|
|
||||||
|
$scheme_options = \Drupal::service('stream_wrapper_manager')->getNames(StreamWrapperInterface::WRITE_VISIBLE); |
||||||
|
$element['uri_scheme'] = [ |
||||||
|
'#type' => 'radios', |
||||||
|
'#title' => t('Upload destination'), |
||||||
|
'#options' => $scheme_options, |
||||||
|
'#default_value' => $this->getSetting('uri_scheme'), |
||||||
|
'#description' => t('Select where the final files should be stored. Private file storage has significantly more overhead than public files, but allows restricted access to files within this field.'), |
||||||
|
]; |
||||||
|
|
||||||
|
return $element; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function fieldSettingsForm(array $form, FormStateInterface $form_state) { |
||||||
|
// Get base form from FileItem. |
||||||
|
$element = parent::fieldSettingsForm($form, $form_state); |
||||||
|
$settings = $this->getSettings(); |
||||||
|
|
||||||
|
// Remove the description option. |
||||||
|
unset($element['description_field']); |
||||||
|
|
||||||
|
$element['languages'] = [ |
||||||
|
'#type' => 'radios', |
||||||
|
'#title' => $this->t('List all languages'), |
||||||
|
'#description' => $this->t('Allow the user to select all languages or only the currently installed languages?'), |
||||||
|
'#options' => [ |
||||||
|
'all' => $this->t('All Languages'), |
||||||
|
'installed' => $this->t('Currently Installed Languages'), |
||||||
|
], |
||||||
|
'#default_value' => $settings['languages'] ?: 'installed', |
||||||
|
]; |
||||||
|
|
||||||
|
return $element; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function generateSampleValue(FieldDefinitionInterface $field_definition) { |
||||||
|
// @todo This will need to generate a text file, containing a sequence of |
||||||
|
// timestamps and nonsense text. Include some gap periods where nothing is |
||||||
|
// displayed. |
||||||
|
// See the ImageItem::generateSampleValue() for how the files are saved. |
||||||
|
// The part about "Generate a max of 5 different images" is a good idea |
||||||
|
// here too. We only need a WebVTT few files. |
||||||
|
// See one of the text item implementation for how to generate nonsense. |
||||||
|
// Pseudocode plan... |
||||||
|
// $sample_file_text = 'WEBVTT'; // start of file. |
||||||
|
// for ($i = 0; $ < $utterances; $i++) { |
||||||
|
// $sample_file_text += \n\n |
||||||
|
// $timestamp += 3-10seconds // start of display |
||||||
|
// $sample_file_text += $timestamp |
||||||
|
// $timestamp += 3-10seconds // end of display |
||||||
|
// $sample_file_text += $timestamp |
||||||
|
// $sample_file_text += randomText() |
||||||
|
// } |
||||||
|
// $file = file_write($sample_file_text, 'random_filename.vtt'); |
||||||
|
$values = [ |
||||||
|
'target_id' => $file->id(), |
||||||
|
// Randomize the rest of these... |
||||||
|
'label' => '', |
||||||
|
'kind' => '', |
||||||
|
'srclang' => '', |
||||||
|
// Careful with this one, complex validation. |
||||||
|
'default' => '', |
||||||
|
]; |
||||||
|
return $values; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function isDisplayed() { |
||||||
|
return TRUE; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,173 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora\Plugin\Field\FieldWidget; |
||||||
|
|
||||||
|
use Drupal\Core\Field\FieldItemListInterface; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\Core\Language\LanguageManager; |
||||||
|
use Drupal\file\Plugin\Field\FieldWidget\FileWidget; |
||||||
|
|
||||||
|
/** |
||||||
|
* Plugin implementation of the 'media_track' widget. |
||||||
|
* |
||||||
|
* @FieldWidget( |
||||||
|
* id = "media_track", |
||||||
|
* label = @Translation("Media Track"), |
||||||
|
* field_types = { |
||||||
|
* "media_track" |
||||||
|
* } |
||||||
|
* ) |
||||||
|
*/ |
||||||
|
class MediaTrackWidget extends FileWidget { |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function defaultSettings() { |
||||||
|
return [ |
||||||
|
'progress_indicator' => 'throbber', |
||||||
|
] + parent::defaultSettings(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Overrides FileWidget::formMultipleElements(). |
||||||
|
* |
||||||
|
* Special handling for draggable multiple widgets and 'add more' button. |
||||||
|
*/ |
||||||
|
protected function formMultipleElements(FieldItemListInterface $items, array &$form, FormStateInterface $form_state) { |
||||||
|
$elements = parent::formMultipleElements($items, $form, $form_state); |
||||||
|
|
||||||
|
$cardinality = $this->fieldDefinition->getFieldStorageDefinition()->getCardinality(); |
||||||
|
$file_upload_help = [ |
||||||
|
'#theme' => 'file_upload_help', |
||||||
|
'#description' => '', |
||||||
|
'#upload_validators' => $elements[0]['#upload_validators'], |
||||||
|
'#cardinality' => $cardinality, |
||||||
|
]; |
||||||
|
if ($cardinality == 1) { |
||||||
|
// If there's only one field, return it as delta 0. |
||||||
|
if (empty($elements[0]['#default_value']['fids'])) { |
||||||
|
$file_upload_help['#description'] = $this->getFilteredDescription(); |
||||||
|
$elements[0]['#description'] = \Drupal::service('renderer')->renderPlain($file_upload_help); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
$elements['#file_upload_description'] = $file_upload_help; |
||||||
|
} |
||||||
|
|
||||||
|
return $elements; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritDoc} |
||||||
|
* |
||||||
|
* Add the field settings so they can be used in the process method. |
||||||
|
*/ |
||||||
|
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) { |
||||||
|
$element = parent::formElement($items, $delta, $element, $form, $form_state); |
||||||
|
$element['#field_settings'] = $this->getFieldSettings(); |
||||||
|
|
||||||
|
return $element; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Form API callback: Processes a media_track field element. |
||||||
|
* |
||||||
|
* Expands the media_track type to include the alt and title fields. |
||||||
|
* |
||||||
|
* This method is assigned as a #process callback in formElement() method. |
||||||
|
*/ |
||||||
|
public static function process($element, FormStateInterface $form_state, $form) { |
||||||
|
$item = $element['#value']; |
||||||
|
$item['fids'] = $element['fids']['#value']; |
||||||
|
|
||||||
|
$element['label'] = [ |
||||||
|
'#title' => t('Label'), |
||||||
|
'#type' => 'textfield', |
||||||
|
'#default_value' => isset($item['label']) ? $item['label'] : '', |
||||||
|
'#description' => t('Label for the track file.'), |
||||||
|
'#maxlength' => 128, |
||||||
|
'#access' => (bool) $item['fids'], |
||||||
|
]; |
||||||
|
$element['kind'] = [ |
||||||
|
'#title' => t('Kind'), |
||||||
|
'#type' => 'select', |
||||||
|
'#description' => t('The kind of media track.'), |
||||||
|
'#options' => [ |
||||||
|
'subtitles' => t('Subtitles'), |
||||||
|
'captions' => t('Captions'), |
||||||
|
'descriptions' => t('Descriptions'), |
||||||
|
'chapters' => t('Chapters'), |
||||||
|
'metadata' => t('Metadata'), |
||||||
|
], |
||||||
|
'#default_value' => isset($item['kind']) ? $item['kind'] : '', |
||||||
|
'#access' => (bool) $item['fids'], |
||||||
|
]; |
||||||
|
|
||||||
|
$srclang_options = []; |
||||||
|
if ($element['#field_settings']['languages'] == 'all') { |
||||||
|
// Need to list all languages. |
||||||
|
$languages = LanguageManager::getStandardLanguageList(); |
||||||
|
foreach ($languages as $key => $language) { |
||||||
|
if ($language[0] == $language[1]) { |
||||||
|
// Both the native language name and the English language name are |
||||||
|
// the same, so only show one of them. |
||||||
|
$srclang_options[$key] = $language[0]; |
||||||
|
} |
||||||
|
else { |
||||||
|
// The native language name and English language name are different |
||||||
|
// so show both of them. |
||||||
|
$srclang_options[$key] = t('@lang0 / @lang1', [ |
||||||
|
'@lang0' => $language[0], |
||||||
|
'@lang1' => $language[1], |
||||||
|
]); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
// Only list the installed languages. |
||||||
|
$languages = \Drupal::languageManager()->getLanguages(); |
||||||
|
foreach ($languages as $key => $language) { |
||||||
|
$srclang_options[$key] = $language->getName(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$element['srclang'] = [ |
||||||
|
'#title' => t('SRC Language'), |
||||||
|
'#description' => t('Choose from one of the installed languages.'), |
||||||
|
'#type' => 'select', |
||||||
|
'#options' => $srclang_options, |
||||||
|
'#default_value' => isset($item['srclang']) ? $item['srclang'] : '', |
||||||
|
'#maxlength' => 20, |
||||||
|
'#access' => (bool) $item['fids'], |
||||||
|
'#element_validate' => [[get_called_class(), 'validateRequiredFields']], |
||||||
|
]; |
||||||
|
// @see https://www.w3.org/TR/html/semantics-embedded-content.html#elementdef-track |
||||||
|
$element['default'] = [ |
||||||
|
'#type' => 'checkbox', |
||||||
|
'#title' => t('Default track'), |
||||||
|
'#default_value' => isset($item['default']) ? $item['default'] : '', |
||||||
|
'#description' => t('Use this as the default track of this kind.'), |
||||||
|
'#access' => (bool) $item['fids'], |
||||||
|
]; |
||||||
|
|
||||||
|
return parent::process($element, $form_state, $form); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Validate callback for kind/srclang/label/default. |
||||||
|
* |
||||||
|
* This is separated in a validate function instead of a #required flag to |
||||||
|
* avoid being validated on the process callback. |
||||||
|
* The 'default' track has complex validation, see HTML5.2 for details. |
||||||
|
*/ |
||||||
|
public static function validateRequiredFields($element, FormStateInterface $form_state) { |
||||||
|
// Only do validation if the function is triggered from other places than |
||||||
|
// the image process form. |
||||||
|
$triggering_element = $form_state->getTriggeringElement(); |
||||||
|
if (!empty($triggering_element['#submit']) && in_array('file_managed_file_submit', $triggering_element['#submit'], TRUE)) { |
||||||
|
$form_state->setLimitValidationErrors([]); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
Loading…
Reference in new issue