webdam-1.0.x-dev/src/Plugin/EntityBrowser/Widget/WebdamSearch.php
src/Plugin/EntityBrowser/Widget/WebdamSearch.php
<?php
namespace Drupal\webdam\Plugin\EntityBrowser\Widget;
use Drupal\webdam\Exception\BundleNotWebdamException;
use Drupal\webdam\Exception\BundleNotExistException;
use Drupal\webdam\Plugin\Field\FieldType\WebdamMetadataItem;
use Drupal\webdam\Plugin\media\Source\Webdam;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\Markup;
use Drupal\media\MediaInterface;
/**
* Uses a Webdam API to search and provide entity listing in a browser's widget.
*
* @EntityBrowserWidget(
* id = "webdam_search",
* label = @Translation("Webdam search"),
* description = @Translation("Adds an Webdam search field browser's widget.")
* )
*/
class WebdamSearch extends WebdamWidgetBase {
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'media_type_document' => NULL,
'media_type_video' => NULL,
'single_file_selection' => FALSE,
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['submit_text']['#access'] = FALSE;
foreach ($this->entityTypeManager->getStorage('media_type')->loadMultiple() as $type) {
/** @var \Drupal\media\MediaTypeInterface $type */
if ($type->getSource() instanceof Webdam) {
$form['media_type']['#options'][$type->id()] = $type->label();
}
}
$form['media_type']['#title'] = $this->t('Media type (Image)');
if (empty($form['media_type']['#options'])) {
$form['media_type']['#disabled'] = TRUE;
$form['media_type']['#description'] = $this->t('You must @create_type before using this widget.', [
'@create_type' => Link::createFromRoute($this->t('create a Webdam media type'), 'entity.media_type.add_form')
->toString(),
]);
}
else {
$form['media_type']['#required'] = FALSE;
$form['media_type']['#empty_option'] = $this->t('- Hide images -');
$form['media_type_document'] = [
'#type' => 'select',
'#title' => $this->t('Media type (Document)'),
'#default_value' => $this->configuration['media_type_document'],
'#required' => FALSE,
'#options' => $form['media_type']['#options'],
'#empty_option' => $this->t('- Hide documents -'),
];
$form['media_type_video'] = [
'#type' => 'select',
'#title' => $this->t('Media type (Video)'),
'#default_value' => $this->configuration['media_type_video'],
'#required' => FALSE,
'#options' => $form['media_type']['#options'],
'#empty_option' => $this->t('- Hide videos -'),
];
$form['single_file_selection'] = [
'#type' => 'checkbox',
'#title' => $this->t('Use single file selection mode'),
'#description' => $this->t('Allows users can create a custom DAT transformation on the file.'),
'#default_value' => $this->configuration['single_file_selection'],
];
}
return $form;
}
/**
* {@inheritdoc}
*/
protected function prepareEntities(array $form, FormStateInterface $form_state) {
if (!$this->checkType()) {
return [];
}
$media = [];
$selection = Json::decode($form_state->getValue('webdam_selection', ''));
$storage = $this->entityTypeManager->getStorage('media');
if (!$selection) {
return [];
}
$image_type = NULL;
$image_source_field = NULL;
$source_fields = [];
if ($this->configuration['media_type']) {
/** @var \Drupal\media\MediaTypeInterface $image_type */
$image_type = $this->entityTypeManager->getStorage('media_type')
->load($this->configuration['media_type']);
$image_source_field = $image_type->getSource()->getConfiguration()['source_field'];
$source_fields[] = $image_source_field;
}
$document_type = NULL;
$document_source_field = NULL;
if ($this->configuration['media_type_document']) {
/** @var \Drupal\media\MediaTypeInterface $document_type */
$document_type = $this->entityTypeManager->getStorage('media_type')
->load($this->configuration['media_type_document']);
$document_source_field = $document_type->getSource()->getConfiguration()['source_field'];
if ($document_source_field != $image_source_field) {
$source_fields[] = $document_source_field;
}
}
$video_type = NULL;
$video_source_field = NULL;
if ($this->configuration['media_type_video']) {
/** @var \Drupal\media\MediaTypeInterface $video_type */
$video_type = $this->entityTypeManager->getStorage('media_type')
->load($this->configuration['media_type_video']);
$video_source_field = $video_type->getSource()->getConfiguration()['source_field'];
if ($video_source_field != $image_source_field) {
$source_fields[] = $video_source_field;
}
}
foreach ($selection as $key => $webdam_info) {
$query = $storage->getQuery();
$query->accessCheck(FALSE);
$source_field_condition = $query->orConditionGroup();
foreach ($source_fields as $source_field) {
$source_field_condition->condition($source_field, $webdam_info['id']);
}
$transformation = NULL;
if (!empty($webdam_info['fileUrl']) && $transformation = $this->getTransformations($webdam_info['fileUrl'])) {
$query->condition(Webdam::TRANSFORMATIONS_FIELD_NAME, $transformation);
}
$mid = $query
->condition($source_field_condition)
->range(0, 1)
->execute();
if ($mid) {
$media[] = $storage->load(reset($mid));
}
else {
if ($webdam_info['type'] == 'IMAGE' && $image_type) {
$media[] = $storage->create([
'bundle' => $image_type->id(),
$image_source_field => $webdam_info['id'],
'name' => $webdam_info['name'],
Webdam::TRANSFORMATIONS_FIELD_NAME => $transformation,
]);
}
elseif ($webdam_info['type'] == 'DOCUMENT' && $document_type) {
$media[] = $storage->create([
'bundle' => $document_type->id(),
$document_source_field => $webdam_info['id'],
'name' => $webdam_info['name'],
]);
}
elseif ($webdam_info['type'] == 'VIDEO' && $video_type) {
$media[] = $storage->create([
'bundle' => $video_type->id(),
$video_source_field => $webdam_info['id'],
'name' => $webdam_info['name'],
]);
}
}
}
return $media;
}
/**
* {@inheritdoc}
*/
public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) {
$form = parent::getForm($original_form, $form_state, $additional_widget_parameters);
if ($form_state->getValue('errors')) {
$form['actions']['submit']['#access'] = FALSE;
return $form;
}
$form['webdam_selection'] = [
'#type' => 'hidden',
'#weight' => -1,
];
$form['#attached']['library'][] = 'webdam/search_view';
$form['#attached']['drupalSettings']['webdam']['domain'] = $this->config->get('webdam.settings')->get('account_domain');
$form['#attached']['drupalSettings']['webdam']['types'] = [];
if ($this->configuration['media_type']) {
$form['#attached']['drupalSettings']['webdam']['types'][] = 'image';
}
if ($this->configuration['media_type_document']) {
$form['#attached']['drupalSettings']['webdam']['types'][] = 'document';
}
if ($this->configuration['media_type_video']) {
$form['#attached']['drupalSettings']['webdam']['types'][] = 'video';
}
if ($this->configuration['single_file_selection']) {
$form['#attached']['drupalSettings']['webdam']['compactviewMode'] = 'SingleSelectFile';
}
else {
$cardinality = (int) $form_state->get(['entity_browser', 'validators', 'cardinality', 'cardinality']);
$form['#attached']['drupalSettings']['webdam']['compactviewMode'] = $cardinality === 1 ? 'SingleSelect' : 'MultiSelect';
}
$form['actions']['submit']['#attributes']['class'][] = 'js-hide';
$form['browser']['#markup'] = Markup::create('<div style="position: fixed; top: 44px; left: 0; right: 0; bottom: 0;" id="webdam-compactview"><div style="display: flex; height: 100%;"></div></div>');
return $form;
}
/**
* {@inheritdoc}
*/
public function submit(array &$element, array &$form, FormStateInterface $form_state) {
if (!empty($form_state->getTriggeringElement()['#eb_widget_main_submit'])) {
try {
$media = $this->prepareEntities($form, $form_state);
array_walk($media, function (MediaInterface $media_item) {
$media_item->save();
});
$this->selectEntities($media, $form_state);
}
catch (\UnexpectedValueException $e) {
$this->messenger()->addError($this->t('Webdam integration is not configured correctly. Please contact the site administrator.'));
}
}
}
/**
* {@inheritdoc}
*/
protected function checkType() {
if (parent::checkType()) {
return TRUE;
}
if ($this->configuration['media_type_document']) {
/** @var \Drupal\media\MediaTypeInterface $type */
$type = $this->entityTypeManager->getStorage('media_type')
->load($this->configuration['media_type_document']);
if (!$type) {
(new BundleNotExistException(
$this->configuration['media_type_document']
))->logException()->displayMessage();
return FALSE;
}
elseif (!($type->getSource() instanceof Webdam)) {
(new BundleNotWebdamException($type->label()))->logException()
->displayMessage();
return FALSE;
}
return TRUE;
}
if ($this->configuration['media_type_video']) {
/** @var \Drupal\media\MediaTypeInterface $type */
$type = $this->entityTypeManager->getStorage('media_type')
->load($this->configuration['media_type_video']);
if (!$type) {
(new BundleNotExistException(
$this->configuration['media_type_video']
))->logException()->displayMessage();
return FALSE;
}
elseif (!($type->getSource() instanceof Webdam)) {
(new BundleNotWebdamException($type->label()))->logException()
->displayMessage();
return FALSE;
}
return TRUE;
}
return FALSE;
}
/**
* Get user-selected transformations string.
*
* @param string $url
* The url string as returned by the compact viewer.
*
* @return string|NULL
* Transformations query or empty string if not available.
*/
public function getTransformations(string $url) {
// Cannot use UrlHelper here, because Webdam uses the same query arg for
// all transformations. E.g. ?io=transform:fo&io=filter:bar.
if ($transformations = parse_url($url, PHP_URL_QUERY)){
return $transformations;
}
return NULL;
}
}
