kaltura_media-1.0.x-dev/src/Plugin/media/Source/Kaltura.php
src/Plugin/media/Source/Kaltura.php
<?php
namespace Drupal\kaltura_media\Plugin\media\Source;
use Drupal\media\MediaSourceBase;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\FieldTypePluginManagerInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\media\MediaInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\File\FileSystemInterface;
use Drupal\kaltura_media\Plugin\Field\FieldType\KalturaItem;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
/**
* Kaltura Media Source.
*
* @MediaSource(
* id = "kaltura",
* label = @Translation("Kaltura"),
* description = @Translation("Use Kaltura for reusable media."),
* allowed_field_types = {"kaltura"},
* default_thumbnail_filename = "no-thumbnail.png",
* forms = {
* "media_library_add" = "Drupal\kaltura_media\Form\KalturaForm"
* }
* )
*/
class Kaltura extends MediaSourceBase {
/**
* Thumbnail API Url.
*
* @var string
*/
protected $thumbnailApiUrl;
/**
* The file system.
*
* @var \Drupal\Core\File\FileSystemInterface
*/
protected $fileSystem;
/**
* The HTTP client.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;
/**
* Stream wrapper manager.
*
* @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface
*/
protected $streamWrapperManager;
/**
* Logger channel.
*
* @var \Drupal\Core\Logger\LoggerChannelInterface
*/
protected $logger;
/**
* Construct.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
EntityTypeManagerInterface $entity_type_manager,
EntityFieldManagerInterface $entity_field_manager,
FieldTypePluginManagerInterface $field_type_manager,
ConfigFactoryInterface $config_factory,
StreamWrapperManagerInterface $stream_wrapper_manager,
FileSystemInterface $file_system,
ClientInterface $http_client,
LoggerChannelFactoryInterface $logger_channel_factory
) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $entity_field_manager, $field_type_manager, $config_factory);
$this->streamWrapperManager = $stream_wrapper_manager;
$this->fileSystem = $file_system;
$this->httpClient = $http_client;
$this->thumbnailApiUrl = 'https://{domain}/p/{partner_id}/thumbnail/entry_id/{entry_id}';
$this->logger = $logger_channel_factory->get('kaltura_media');
}
/**
* {@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('stream_wrapper_manager'),
$container->get('file_system'),
$container->get('http_client'),
$container->get('logger.factory')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'thumbnails_directory' => 'public://kaltura_thumbnails',
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['thumbnails_directory'] = [
'#type' => 'textfield',
'#title' => $this->t('Thumbnails location'),
'#default_value' => $this->configuration['thumbnails_directory'],
'#description' => $this->t('Thumbnails will be fetched from the provider for local usage. This is the URI of the directory where they will be placed.'),
'#required' => TRUE,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$configuration = $this->getConfiguration();
$this->setConfiguration($configuration);
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$thumbnails_directory = $form_state->getValue('thumbnails_directory');
if (!$this->streamWrapperManager->isValidUri($thumbnails_directory)) {
$form_state->setErrorByName('thumbnails_directory', $this->t('@path is not a valid path.', [
'@path' => $thumbnails_directory,
]));
}
}
/**
* {@inheritdoc}
*/
public function getMetadataAttributes() {
return [
'default_name' => $this->t('Default Name'),
'thumbnail_uri' => $this->t('Thumbnail Uri'),
];
}
/**
* {@inheritdoc}
*/
public function getMetadata(MediaInterface $media, $attribute_name) {
$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();
switch ($attribute_name) {
case 'default_name':
return 'media:' . $media->bundle() . ':' . $media->uuid();
case 'thumbnail_uri':
$default_thumbnail_filename = $this->pluginDefinition['default_thumbnail_filename'];
if ($thumbnail_url = $this->getLocalThumbnailUri($field_item)) {
return $thumbnail_url;
}
return $this->configFactory->get('media.settings')->get('icon_base_uri') . '/' . $default_thumbnail_filename;
}
return NULL;
}
/**
* Returns the local URI for given media thumbnail.
*
* If the thumbnail is not already locally stored, this method will attempt
* to download it.
*
* @param \Drupal\kaltura_media\Plugin\Field\FieldType\KalturaItem $kaltura_item
* The kaltura field item.
*
* @return string|null
* The local thumbnail URI, or NULL if it could not be downloaded, or if the
* resource has no thumbnail at all.
*/
protected function getLocalThumbnailUri(KalturaItem $kaltura_item) {
$remote_thumbnail_url = $this->thumbnailApiUrl;
$remote_thumbnail_url = str_replace('{domain}', $kaltura_item->domain, $remote_thumbnail_url);
$remote_thumbnail_url = str_replace('{partner_id}', $kaltura_item->partner_id, $remote_thumbnail_url);
$remote_thumbnail_url = str_replace('{entry_id}', $kaltura_item->entry_id, $remote_thumbnail_url);
// Compute the local thumbnail URI, regardless of whether or not it exists.
$configuration = $this->getConfiguration();
$directory = $configuration['thumbnails_directory'];
$local_thumbnail_uri = "$directory/" . Crypt::hashBase64($remote_thumbnail_url) . '.jpg';
// If the local thumbnail already exists, return its URI.
if (file_exists($local_thumbnail_uri)) {
return $local_thumbnail_uri;
}
// The local thumbnail doesn't exist yet, so try to download it. First,
// ensure that the destination directory is writable, and if it's not,
// log an error and bail out.
if (!$this->fileSystem->prepareDirectory($directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
$this->logger->warning('Could not prepare thumbnail destination directory @dir for Kaltura media.', [
'@dir' => $directory,
]);
return NULL;
}
try {
$response = $this->httpClient->get($remote_thumbnail_url);
if ($response->getStatusCode() === 200) {
$this->fileSystem->saveData((string) $response->getBody(), $local_thumbnail_uri, FileSystemInterface::EXISTS_REPLACE);
return $local_thumbnail_uri;
}
}
catch (RequestException $e) {
$this->logger->warning('Could not download remote thumbnail from {url}.', [
'url' => $remote_thumbnail_url,
]);
}
catch (RequestException $e) {
$this->logger->warning($e->getMessage());
}
catch (FileException $e) {
$this->logger->warning('Could not download remote thumbnail from {url}.', [
'url' => $remote_thumbnail_url,
]);
}
return NULL;
}
}
