class Bynder in Bynder 8.3
Same name and namespace in other branches
- 8.2 src/Plugin/media/Source/Bynder.php \Drupal\bynder\Plugin\media\Source\Bynder
- 4.0.x src/Plugin/media/Source/Bynder.php \Drupal\bynder\Plugin\media\Source\Bynder
Provides media source plugin for Bynder.
Plugin annotation
@MediaSource(
id = "bynder",
label = @Translation("Bynder"),
description = @Translation("Provides business logic and metadata for Bynder."),
default_thumbnail_filename = "bynder-logo.png",
allowed_field_types = {"string", "string_long"}
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\media\MediaSourceBase implements ContainerFactoryPluginInterface, MediaSourceInterface
- class \Drupal\bynder\Plugin\media\Source\Bynder
- class \Drupal\media\MediaSourceBase implements ContainerFactoryPluginInterface, MediaSourceInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of Bynder
10 files declare their use of Bynder
- bynder.module in ./
bynder.module - Provides bynder integration.
- BynderDocumentFormatter.php in src/
Plugin/ Field/ FieldFormatter/ BynderDocumentFormatter.php - BynderFormatter.php in src/
Plugin/ Field/ FieldFormatter/ BynderFormatter.php - BynderFormatterBase.php in src/
Plugin/ Field/ FieldFormatter/ BynderFormatterBase.php - BynderMediaUsage.php in src/
Controller/ BynderMediaUsage.php
9 string references to 'Bynder'
- bynder.info.yml in ./
bynder.info.yml - bynder.info.yml
- bynder.links.menu.yml in ./
bynder.links.menu.yml - bynder.links.menu.yml
- BynderUploadWidgetTest::testUploadConfigurationForm in tests/
src/ FunctionalJavascript/ BynderUploadWidgetTest.php - Tests upload configuration form.
- bynder_help in ./
bynder.module - Implements hook_help().
- bynder_requirements in ./
bynder.install - Implements hook_requirements().
File
- src/
Plugin/ media/ Source/ Bynder.php, line 38
Namespace
Drupal\bynder\Plugin\media\SourceView source
class Bynder extends MediaSourceBase {
/**
* Bynder api service.
*
* @var \Drupal\bynder\BynderApiInterface
* Bynder api service.
*/
protected $bynderApi;
/**
* Account proxy.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $accountProxy;
/**
* The url generator.
*
* @var \Drupal\Core\Routing\UrlGeneratorInterface
*/
protected $urlGenerator;
/**
* Statically cached metadata information for the given assets.
*
* @var array
*/
protected $metadata;
/**
* The logger factory service.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $logger;
/**
* The cache service.
*
* @var \Drupal\Core\Cache\CacheBackendInterface
*/
protected $cache;
/**
* The time service.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Used to track if an API request returned a timout error.
*
* @var bool
*/
protected static $timoutDetected = FALSE;
/**
* Constructs a new class instance.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* Entity type manager service.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* Entity field manager service.
* @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_manager
* The field type plugin manager service.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory service.
* @param \Drupal\bynder\BynderApiInterface $bynder_api_service
* Bynder api service.
* @param \Drupal\Core\Session\AccountProxyInterface $account_proxy
* Account proxy.
* @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
* The url generator service.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger
* The logger factory service.
* @param \Drupal\Core\Cache\CacheBackendInterface $cache
* The cache service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, FieldTypePluginManagerInterface $field_type_manager, ConfigFactoryInterface $config_factory, BynderApiInterface $bynder_api_service, AccountProxyInterface $account_proxy, UrlGeneratorInterface $url_generator, LoggerChannelFactoryInterface $logger, CacheBackendInterface $cache, TimeInterface $time, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $field_type_manager, $config_factory);
$this->bynderApi = $bynder_api_service;
$this->accountProxy = $account_proxy;
$this->urlGenerator = $url_generator;
$this->logger = $logger;
$this->cache = $cache;
$this->time = $time;
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
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'), $container
->get('bynder_api'), $container
->get('current_user'), $container
->get('url_generator'), $container
->get('logger.factory'), $container
->get('cache.data'), $container
->get('datetime.time'), $container
->get('module_handler'));
}
/**
* {@inheritdoc}
*/
public function getMetadataAttributes() {
$fields = [
'uuid' => $this
->t('ID'),
'name' => $this
->t('Name'),
'description' => $this
->t('Description'),
'tags' => $this
->t('Tags'),
'type' => $this
->t('Type'),
'video_preview_urls' => $this
->t('Video preview urls'),
'thumbnail_urls' => $this
->t('Thumbnail urls'),
'width' => $this
->t('Width'),
'height' => $this
->t('Height'),
'created' => $this
->t('Date created'),
'modified' => $this
->t('Data modified'),
'propertyOptions' => $this
->t('Meta-property option IDs'),
];
return $fields;
}
/**
* Returns a list of remote metadata properties.
*
* @return array
* A list of remote metadata properties.
*/
public function getRemoteMetadataProperties() {
return [
'id',
'name',
'description',
'type',
'videoPreviewURLs',
'thumbnails',
'original',
'width',
'height',
'dateCreated',
'dateModified',
'propertyOptions',
];
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'source_field' => '',
];
}
/**
* Ensures the given media entity has Bynder metadata information in place.
*
* @param \Drupal\media\MediaInterface $media
* The media entity.
* @param bool $force
* (optional) By default, this will not attempt to check for updated
* metadata if there is local data available. Pass TRUE to always check for
* changed metadata.
*
* @return bool
* TRUE if the metadata is ensured. Otherwise, FALSE.
*/
public function ensureMetadata(MediaInterface $media, $force = FALSE) {
$media_uuid = $this
->getSourceFieldValue($media);
if (!empty($this->metadata[$media_uuid]) && !$force) {
return TRUE;
}
if (!$media
->hasField(BynderMetadataItem::METADATA_FIELD_NAME)) {
$this->logger
->get('bynder')
->error('The media type @type must have a Bynder metadata field named "bynder_metadata".', [
'@type' => $media
->bundle(),
]);
return FALSE;
}
if (!$media
->get(BynderMetadataItem::METADATA_FIELD_NAME)
->isEmpty() && !$force) {
$metadata = Json::decode($media
->get(BynderMetadataItem::METADATA_FIELD_NAME)->value);
if (is_array($metadata)) {
$this->metadata[$media_uuid] = $metadata;
return TRUE;
}
}
try {
// Try to fetch data if no previous request failed with a timeout.
if (!static::$timoutDetected || $force) {
$media_uuid = $this
->getSourceFieldValue($media);
$this->metadata[$media_uuid] = $this
->filterRemoteMetadata((array) $this->bynderApi
->getMediaInfo($media_uuid));
if ($this
->hasMetadataChanged($media, $this->metadata[$media_uuid])) {
$encoded_metadata = Json::encode($this->metadata[$media_uuid]);
if (!$encoded_metadata) {
$this->logger
->get('bynder')
->error('Unable to JSON encode the returned API response for the media UUID @uuid.', [
'@uuid' => $media_uuid,
]);
return FALSE;
}
$media
->set(BynderMetadataItem::METADATA_FIELD_NAME, $encoded_metadata)
->save();
return TRUE;
}
return TRUE;
}
} catch (GuzzleException $e) {
if ($e instanceof ConnectException) {
$handler_context = $e
->getHandlerContext();
if (isset($handler_context['errno']) && $handler_context['errno'] == 28) {
static::$timoutDetected = TRUE;
}
}
$this->logger
->get('bynder')
->error('Unable to fetch info about the asset represented by media @name (@id) with message @message.', [
'@name' => $media
->label(),
'@id' => $media
->id(),
'@message' => $e
->getMessage(),
]);
}
return FALSE;
}
/**
* Returns a list of filtered remote metadata properties.
*
* @param array $metadata
* The metadata items.
*
* @return array
* Filtered list of remote metadata properties.
*/
public function filterRemoteMetadata(array $metadata) {
return array_intersect_key($metadata, array_combine($this
->getRemoteMetadataProperties(), $this
->getRemoteMetadataProperties()));
}
/**
* Compares the local metadata and the remote metadata in case it changed.
*
* @param \Drupal\media\MediaInterface $media
* The media entity.
* @param array $remote_metadata
* The remote metadata.
*
* @return bool
* TRUE if the remote metadata has changed. Otherwise, FALSE.
*/
public function hasMetadataChanged(MediaInterface $media, array $remote_metadata) {
$remote_metadata = $this
->filterRemoteMetadata($remote_metadata);
if ($media
->get(BynderMetadataItem::METADATA_FIELD_NAME)
->isEmpty() && !empty($remote_metadata)) {
return TRUE;
}
$local_metadata = (array) Json::decode((string) $media
->get(BynderMetadataItem::METADATA_FIELD_NAME)->value);
return $local_metadata !== $remote_metadata;
}
/**
* {@inheritdoc}
*/
public function getMetadata(MediaInterface $media, $name) {
$remote_uuid = $this
->getSourceFieldValue($media);
if ($name == 'uuid') {
return $remote_uuid;
}
// Ensure the metadata information are fetched.
if ($this
->ensureMetadata($media)) {
switch ($name) {
case 'video_preview_urls':
return isset($this->metadata[$remote_uuid]['videoPreviewURLs']) ? $this->metadata[$remote_uuid]['videoPreviewURLs'] : FALSE;
case 'thumbnail_urls':
return isset($this->metadata[$remote_uuid]['thumbnails']) ? $this->metadata[$remote_uuid]['thumbnails'] : FALSE;
case 'thumbnail_uri':
if (!empty($this->metadata[$remote_uuid]['thumbnails']['webimage'])) {
if ($this
->useRemoteImages()) {
return $this->metadata[$remote_uuid]['thumbnails']['webimage'];
}
elseif ($file = system_retrieve_file($this->metadata[$remote_uuid]['thumbnails']['webimage'], NULL, TRUE)) {
return $file
->getFileUri();
}
}
return parent::getMetadata($media, 'thumbnail_uri');
case 'created':
return isset($this->metadata[$remote_uuid]['dateCreated']) ? $this->metadata[$remote_uuid]['dateCreated'] : FALSE;
case 'modified':
return isset($this->metadata[$remote_uuid]['dateModified']) ? $this->metadata[$remote_uuid]['dateModified'] : FALSE;
case 'default_name':
return isset($this->metadata[$remote_uuid]['name']) ? $this->metadata[$remote_uuid]['name'] : parent::getMetadata($media, 'default_name');
default:
return isset($this->metadata[$remote_uuid][$name]) ? $this->metadata[$remote_uuid][$name] : FALSE;
}
}
return FALSE;
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
// Check the connection with bynder.
try {
$this->bynderApi
->getBrands();
} catch (\Exception $exception) {
if ($this->accountProxy
->hasPermission('administer bynder configuration')) {
$this
->messenger()
->addError($this
->t('Connecting with Bynder failed. Check if the configuration is set properly <a href=":url">here</a>.', [
':url' => $this->urlGenerator
->generateFromRoute('bynder.configuration_form'),
]));
}
else {
$this
->messenger()
->addError($this
->t('Something went wrong with the Bynder connection. Please contact the site administrator.'));
}
}
return parent::buildConfigurationForm($form, $form_state);
}
/**
* Get the primary value stored in the source field.
*
* @todo This helper method was added to MediaSourceBase in 8.5.0 but we
* replicate it here because we want to support 8.4.0 sites as well. This
* method can be safely removed once there is no need to support 8.4 anymore,
* and we ensure the core Media dependency is bumped to 8.5.0 at least.
*
* @param \Drupal\media\MediaInterface $media
* A media item.
*
* @return mixed
* The source value.
*
* @throws \RuntimeException
* If the source field for the media source is not defined.
*/
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.');
}
/** @var \Drupal\Core\Field\FieldItemInterface $field_item */
$field_item = $media
->get($source_field)
->first();
return $field_item->{$field_item
->mainPropertyName()};
}
/**
* Creates the metadata field storage definition.
*
* @return \Drupal\field\FieldStorageConfigInterface
* The unsaved field storage definition.
*/
public function createMetadataFieldStorage() {
return $this->entityTypeManager
->getStorage('field_storage_config')
->create([
'entity_type' => 'media',
'field_name' => BynderMetadataItem::METADATA_FIELD_NAME,
'type' => 'bynder_metadata',
'cardinality' => 1,
'locked' => TRUE,
]);
}
/**
* Creates the metadata field definition.
*
* @param \Drupal\media\MediaTypeInterface $type
* The media type.
*
* @return \Drupal\field\FieldConfigInterface
* The unsaved field definition. The field storage definition, if new,
* should also be unsaved.
*/
public function createMetadataField(MediaTypeInterface $type) {
return $this->entityTypeManager
->getStorage('field_config')
->create([
'entity_type' => 'media',
'field_name' => BynderMetadataItem::METADATA_FIELD_NAME,
'bundle' => $type
->id(),
'label' => 'Bynder Metadata',
'translatable' => FALSE,
'field_type' => 'bynder_metadata',
]);
}
/**
* Checks if remote images should be used.
*
* This checks to see if the configuration for using remote images is enabled
* and that the Remote Stream Wrapper module is still enabled.
*
* @return bool
* TRUE if remote images should be used, or FALSE otherwise.
*/
protected function useRemoteImages() {
return $this->configFactory
->get('bynder.settings')
->get('use_remote_images') || $this->moduleHandler
->moduleExists('remote_stream_wrapper');
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
Bynder:: |
protected | property | Account proxy. | |
Bynder:: |
protected | property | Bynder api service. | |
Bynder:: |
protected | property | The cache service. | |
Bynder:: |
protected | property | The logger factory service. | |
Bynder:: |
protected | property | Statically cached metadata information for the given assets. | |
Bynder:: |
protected | property | The module handler. | |
Bynder:: |
protected | property | The time service. | |
Bynder:: |
protected static | property | Used to track if an API request returned a timout error. | |
Bynder:: |
protected | property | The url generator. | |
Bynder:: |
public | function |
Form constructor. Overrides MediaSourceBase:: |
|
Bynder:: |
public static | function |
Creates an instance of the plugin. Overrides MediaSourceBase:: |
|
Bynder:: |
public | function | Creates the metadata field definition. | |
Bynder:: |
public | function | Creates the metadata field storage definition. | |
Bynder:: |
public | function |
Gets default configuration for this plugin. Overrides MediaSourceBase:: |
|
Bynder:: |
public | function | Ensures the given media entity has Bynder metadata information in place. | |
Bynder:: |
public | function | Returns a list of filtered remote metadata properties. | |
Bynder:: |
public | function |
Gets the value for a metadata attribute for a given media item. Overrides MediaSourceBase:: |
|
Bynder:: |
public | function |
Gets a list of metadata attributes provided by this plugin. Overrides MediaSourceInterface:: |
|
Bynder:: |
public | function | Returns a list of remote metadata properties. | |
Bynder:: |
public | function |
Get the primary value stored in the source field. Overrides MediaSourceBase:: |
|
Bynder:: |
public | function | Compares the local metadata and the remote metadata in case it changed. | |
Bynder:: |
protected | function | Checks if remote images should be used. | |
Bynder:: |
public | function |
Constructs a new class instance. Overrides MediaSourceBase:: |
|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MediaSourceBase:: |
protected | property | The config factory service. | |
MediaSourceBase:: |
protected | property | The entity field manager service. | |
MediaSourceBase:: |
protected | property | The entity type manager service. | |
MediaSourceBase:: |
protected | property | The field type plugin manager service. | |
MediaSourceBase:: |
protected | property | Plugin label. | |
MediaSourceBase:: |
public | function |
Calculates dependencies for the configured plugin. Overrides DependentPluginInterface:: |
|
MediaSourceBase:: |
public | function |
Creates the source field definition for a type. Overrides MediaSourceInterface:: |
2 |
MediaSourceBase:: |
protected | function | Creates the source field storage definition. | |
MediaSourceBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
MediaSourceBase:: |
public | function |
Get the source field definition for a media type. Overrides MediaSourceInterface:: |
|
MediaSourceBase:: |
protected | function | Determine the name of the source field. | 2 |
MediaSourceBase:: |
protected | function | Get the source field options for the media type form. | |
MediaSourceBase:: |
protected | function | Returns the source field storage definition. | |
MediaSourceBase:: |
public | function |
Prepares the media type fields for this source in the form display. Overrides MediaSourceInterface:: |
3 |
MediaSourceBase:: |
public | function |
Prepares the media type fields for this source in the view display. Overrides MediaSourceInterface:: |
6 |
MediaSourceBase:: |
public | function |
Sets the configuration for this plugin instance. Overrides ConfigurableInterface:: |
|
MediaSourceBase:: |
public | function |
Form submission handler. Overrides PluginFormInterface:: |
1 |
MediaSourceBase:: |
public | function |
Form validation handler. Overrides PluginFormInterface:: |
1 |
MediaSourceInterface:: |
constant | Default empty value for metadata fields. | ||
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |