View source
<?php
namespace Drupal\media_acquiadam\Plugin\EntityBrowser\Widget;
use cweagans\webdam\Entity\Asset;
use cweagans\webdam\Entity\Folder;
use cweagans\webdam\Exception\InvalidCredentialsException;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\entity_browser\WidgetBase;
use Drupal\entity_browser\WidgetValidationManager;
use Drupal\media\MediaSourceManager;
use Drupal\media_acquiadam\AcquiadamInterface;
use Drupal\media_acquiadam\Form\AcquiadamConfig;
use Drupal\user\UserDataInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
class Acquiadam extends WidgetBase {
protected $acquiadam;
protected $user;
protected $languageManager;
protected $moduleHandler;
protected $sourceManager;
protected $entityFieldManager;
protected $userData;
protected $requestStack;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EventDispatcherInterface $event_dispatcher, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, WidgetValidationManager $validation_manager, AcquiadamInterface $acquiadam, AccountInterface $account, LanguageManagerInterface $languageManager, ModuleHandlerInterface $moduleHandler, MediaSourceManager $sourceManager, UserDataInterface $userData, RequestStack $requestStack, ConfigFactoryInterface $config) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $event_dispatcher, $entity_type_manager, $validation_manager);
$this->acquiadam = $acquiadam;
$this->user = $account;
$this->languageManager = $languageManager;
$this->moduleHandler = $moduleHandler;
$this->sourceManager = $sourceManager;
$this->entityFieldManager = $entity_field_manager;
$this->userData = $userData;
$this->requestStack = $requestStack;
$this->config = $config;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('event_dispatcher'), $container
->get('entity_type.manager'), $container
->get('entity_field.manager'), $container
->get('plugin.manager.entity_browser.widget_validation'), $container
->get('media_acquiadam.acquiadam_user_creds'), $container
->get('current_user'), $container
->get('language_manager'), $container
->get('module_handler'), $container
->get('plugin.manager.media.source'), $container
->get('user.data'), $container
->get('request_stack'), $container
->get('config.factory'));
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$media_type_options = [];
$media_types = $this->entityTypeManager
->getStorage('media_type')
->loadByProperties([
'source' => 'acquiadam_asset',
]);
foreach ($media_types as $media_type) {
$media_type_options[$media_type
->id()] = $media_type
->label();
}
if (empty($media_type_options)) {
$url = Url::fromRoute('entity.media_type.add_form')
->toString();
$form['media_type'] = [
'#markup' => $this
->t("You don't have media type of the Acquia DAM asset type. You should <a href='!link'>create one</a>", [
'!link' => $url,
]),
];
}
else {
$form['media_type'] = [
'#type' => 'select',
'#title' => $this
->t('Media type'),
'#default_value' => $this->configuration['media_type'],
'#options' => $media_type_options,
];
}
return $form;
}
public function defaultConfiguration() {
return [
'media_type' => NULL,
'submit_text' => $this
->t('Select assets'),
] + parent::defaultConfiguration();
}
public function getForm(array &$original_form, FormStateInterface $form_state, array $additional_widget_parameters) {
$config = $this->config
->get('media_acquiadam.settings');
$media_type_storage = $this->entityTypeManager
->getStorage('media_type');
if (!$this->configuration['media_type'] || !($media_type = $media_type_storage
->load($this->configuration['media_type']))) {
return [
'#markup' => $this
->t('The media type is not configured correctly.'),
];
}
elseif ($media_type
->getSource()
->getPluginId() != 'acquiadam_asset') {
return [
'#markup' => $this
->t('The configured media type is not using the acquiadam_asset plugin.'),
];
}
elseif ($this
->uuid() != $form_state
->getStorage()['entity_browser_current_widget']) {
return [];
}
$auth = $this->acquiadam
->getAuthState();
if (empty($auth['valid_token'])) {
try {
$auth = $this->acquiadam
->checkAuth();
if (!empty($auth['valid_token'])) {
$this->userData
->set('media_acquiadam', $this->user
->id(), 'acquiadam_access_token', $auth['access_token']);
$this->userData
->set('media_acquiadam', $this->user
->id(), 'acquiadam_access_token_expiration', $auth['access_token_expiry']);
$this->userData
->set('media_acquiadam', $this->user
->id(), 'acquiadam_refresh_token', $auth['refresh_token']);
}
} catch (InvalidCredentialsException $x) {
$message = '';
if ($config
->get('samesite_cookie_disable') || $this->requestStack
->getCurrentRequest()
->getScheme() == "http") {
$message = $this
->t("You are not authenticated. %authenticate first, then re-open this modal to browse Acquia DAM assets..", [
'%authenticate' => Link::createFromRoute('authenticate', 'media_acquiadam.auth_start', [], [
'attributes' => [
'target' => '_blank',
],
])
->toString(),
]);
}
else {
$message = $this
->t('You are not authenticated. Please %authenticate to browse Acquia DAM assets.', [
'%authenticate' => Link::createFromRoute('authenticate', 'media_acquiadam.auth_start', [
'auth_finish_redirect' => $this->requestStack
->getCurrentRequest()
->getRequestUri(),
])
->toString(),
]);
}
$form['message'] = [
'#theme' => 'asset_browser_message',
'#message' => $message,
'#attached' => [
'library' => [
'media_acquiadam/asset_browser',
],
],
];
return $form;
}
}
$form = parent::getForm($original_form, $form_state, $additional_widget_parameters);
$form['#attached']['library'][] = 'core/drupal.dialog.ajax';
$trigger_elem = $form_state
->getTriggeringElement();
$current_folder = new Folder();
$current_folder->id = 0;
$current_folder->parent = 0;
$current_folder->name = 'Home';
$page = 0;
$num_per_page = $config
->get('num_images_per_page') ?? AcquiadamConfig::NUM_IMAGES_PER_PAGE;
$breadcrumbs = [
'0' => 'Home',
];
if (isset($form_state
->getCompleteForm()['widget']) && isset($trigger_elem) && $trigger_elem['#name'] != 'filter_sort_reset') {
$widget = $form_state
->getCompleteForm()['widget'];
if (isset($widget['pager-container']) && is_numeric($widget['pager-container']['#page'])) {
$page = intval($widget['pager-container']['#page']);
}
if (isset($widget['asset-container']) && is_numeric($widget['asset-container']['#acquiadam_folder_id'])) {
$current_folder->id = $widget['asset-container']['#acquiadam_folder_id'];
}
if (isset($widget['breadcrumb-container']) && is_array($widget['breadcrumb-container']['#breadcrumbs'])) {
$breadcrumbs = $widget['breadcrumb-container']['#breadcrumbs'];
}
if ($form_state
->getValue('assets')) {
$current_selections = $form_state
->getValue('current_selections', []) + array_filter($form_state
->getValue('assets', []));
$form['current_selections'] = [
'#type' => 'value',
'#value' => $current_selections,
];
}
}
if (isset($trigger_elem)) {
if ($trigger_elem['#name'] == 'acquiadam_folder') {
$current_folder->id = intval($trigger_elem['#acquiadam_folder_id']);
$page = 0;
}
if ($trigger_elem['#name'] == 'acquiadam_pager') {
$page = intval($trigger_elem['#acquiadam_page']);
}
if ($trigger_elem['#name'] == 'filter_sort_submit') {
$page = 0;
}
if ($trigger_elem['#name'] == 'filter_sort_reset') {
$user_input = $form_state
->getUserInput();
$clean_val_key = $form_state
->getCleanValueKeys();
foreach ($user_input as $key => $item) {
if (!in_array($key, $clean_val_key)) {
unset($user_input[$key]);
}
}
$form_state
->setUserInput($user_input);
$form_state
->setValues($user_input);
$form_state
->setRebuild();
$page = 0;
}
}
$offset = $num_per_page * $page;
$params = [
'limit' => $num_per_page,
'offset' => $offset,
'sortby' => $form_state
->getValue('sortby'),
'sortdir' => $form_state
->getValue('sortdir'),
'types' => $form_state
->getValue('types'),
'query' => $form_state
->getValue('query'),
'folderid' => $current_folder->id,
];
if ($current_folder->id) {
$current_folder = $this->acquiadam
->getFolder($current_folder->id);
$folders = $current_folder->folders;
$folder_assets = $this->acquiadam
->getFolderAssets($current_folder->id, $params);
$current_folder->numassets = $folder_assets->total_count;
if (!empty($params['types'])) {
$current_folder->numassets = $folder_assets->facets->types->{$params['types']};
}
$items = $folder_assets->items;
}
else {
$folders = $this->acquiadam
->getTopLevelFolders();
}
if (!empty($params['query'])) {
$search_results = $this->acquiadam
->searchAssets($params);
$current_folder->numassets = $search_results['total_count'];
$items = isset($search_results['assets']) ? $search_results['assets'] : [];
}
$form += $this
->getFilterSort();
$form += $this
->getBreadcrumb($current_folder, $breadcrumbs);
$form['asset-container'] = [
'#type' => 'container',
'#acquiadam_folder_id' => $current_folder->id,
'#attributes' => [
'class' => [
'acquiadam-asset-browser',
],
],
];
$modulePath = $this->moduleHandler
->getModule('media_acquiadam')
->getPath();
if (empty($params['query'])) {
foreach ($folders as $folder) {
$form['asset-container']['folders'][$folder->name] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'acquiadam-browser-folder-link',
],
'style' => 'background-image:url("/' . $modulePath . '/img/folder.png")',
],
];
$backgroundImageStyle = '';
if (isset($folder->thumbnailurls) && !empty($folder->thumbnailurls[0]->url)) {
$backgroundImageStyle .= 'background-image:url("' . $folder->thumbnailurls[0]->url . '")';
}
$form['asset-container']['folders'][$folder->name][$folder->id] = [
'#type' => 'button',
'#value' => $folder->name,
'#name' => 'acquiadam_folder',
'#acquiadam_folder_id' => $folder->id,
'#acquiadam_parent_folder_id' => $current_folder->parent,
'#attributes' => [
'class' => [
'acquiadam-folder-link-button',
],
'style' => $backgroundImageStyle,
],
];
$form['asset-container']['folders'][$folder->name]['title'] = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $folder->name,
];
}
}
$assets = [];
$assets_status = [];
if (isset($items)) {
foreach ($items as $folder_item) {
$assets_status[$folder_item->id]['#disabled'] = $folder_item->status !== 'active';
$assets[$folder_item->id] = $this
->layoutMediaEntity($folder_item);
}
}
$form['asset-container']['assets'] = [
'#type' => 'checkboxes',
'#theme_wrappers' => [
'checkboxes__acquiadam_assets',
],
'#title_display' => 'invisible',
'#options' => $assets,
'#attached' => [
'library' => [
'media_acquiadam/asset_browser',
],
],
] + $assets_status;
if ($current_folder->numassets > $num_per_page) {
$form['actions'] += $this
->getPager($current_folder, $page, $num_per_page);
}
return $form;
}
public function getFilterSort() {
$form['filter-sort-container'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'filter-sort-container',
],
],
];
$form['filter-sort-container']['sortby'] = [
'#type' => 'select',
'#title' => 'Sort by',
'#options' => [
'filename' => 'File name',
'filesize' => 'File size',
'datecreated' => 'Date created',
'datemodified' => 'Date modified',
],
'#default_value' => 'datecreated',
];
$form['filter-sort-container']['sortdir'] = [
'#type' => 'select',
'#title' => 'Sort direction',
'#options' => [
'asc' => 'Ascending',
'desc' => 'Descending',
],
'#default_value' => 'asc',
];
$form['filter-sort-container']['types'] = [
'#type' => 'select',
'#title' => 'File type',
'#options' => [
'' => 'All',
'image' => 'Image',
'audiovideo' => 'Audio/Video',
'document' => 'Document',
'presentation' => 'Presentation',
'other' => 'Other',
],
'#default_value' => '',
];
$form['filter-sort-container']['query'] = [
'#type' => 'textfield',
'#title' => 'Search',
'#size' => 24,
];
$form['filter-sort-container']['filter-sort-submit'] = [
'#type' => 'button',
'#value' => 'Apply',
'#name' => 'filter_sort_submit',
];
$form['filter-sort-container']['filter-sort-reset'] = [
'#type' => 'button',
'#value' => 'Reset',
'#name' => 'filter_sort_reset',
];
return $form;
}
public function getBreadcrumb(Folder $current_folder, array $breadcrumbs = []) {
if (array_key_exists($current_folder->id, $breadcrumbs) && count($breadcrumbs) > 1) {
do {
end($breadcrumbs);
$id = key($breadcrumbs);
if ($id != $current_folder->id && count($breadcrumbs) > 1) {
array_pop($breadcrumbs);
}
} while ($id != $current_folder->id && count($breadcrumbs) > 1);
}
if (is_object($current_folder) && property_exists($current_folder, 'parent') && array_key_exists($current_folder->parent, $breadcrumbs)) {
end($breadcrumbs);
if (key($breadcrumbs) == $current_folder->parent) {
$breadcrumbs[$current_folder->id] = $current_folder->name;
}
}
reset($breadcrumbs);
$form['breadcrumb-container'] = [
'#type' => 'container',
'#breadcrumbs' => $breadcrumbs,
'#attributes' => [
'class' => [
'breadcrumb acquiadam-browser-breadcrumb-container',
],
],
];
foreach ($breadcrumbs as $folder_id => $folder_name) {
$form['breadcrumb-container'][$folder_id] = [
'#type' => 'button',
'#value' => $folder_name,
'#name' => 'acquiadam_folder',
'#acquiadam_folder_id' => $folder_id,
'#acquiadam_parent_folder_id' => $folder_name,
'#prefix' => '<li>',
'#suffix' => '</li>',
'#attributes' => [
'class' => [
'acquiadam-browser-breadcrumb',
],
],
];
}
return $form;
}
public function layoutMediaEntity(Asset $acquiadamAsset) {
$modulePath = $this->moduleHandler
->getModule('media_acquiadam')
->getPath();
$assetName = $acquiadamAsset->status !== 'active' ? "{$acquiadamAsset->name} ({$acquiadamAsset->status})" : $acquiadamAsset->name;
if (!empty($acquiadamAsset->thumbnailurls)) {
$thumbnail = '<div class="acquiadam-asset-thumb"><img src="' . $acquiadamAsset->thumbnailurls[2]->url . '" alt="' . $assetName . '" /></div>';
}
else {
$thumbnail = '<span class="acquiadam-browser-empty">No preview available.</span>';
}
$element = '<div class="acquiadam-asset-checkbox">' . $thumbnail . '<div class="acquiadam-asset-details"><a href="/acquiadam/asset/' . $acquiadamAsset->id . '" class="use-ajax" data-dialog-type="modal"><img src="/' . $modulePath . '/img/ext-link.png" alt="Folder link" class="acquiadam-asset-browser-icon" /></a><p class="acquiadam-asset-filename">' . $assetName . '</p></div></div>';
return $element;
}
public function getPager(Folder $current_folder, $page, $num_per_page) {
$form['pager-container'] = [
'#type' => 'container',
'#page' => $page,
'#attributes' => [
'class' => [
'acquiadam-asset-browser-pager',
],
],
];
if ($page > 0) {
$form['pager-container']['first'] = [
'#type' => 'button',
'#value' => '<<',
'#name' => 'acquiadam_pager',
'#acquiadam_page' => 0,
'#attributes' => [
'class' => [
'page-button',
'page-first',
],
],
];
$form['pager-container']['previous'] = [
'#type' => 'button',
'#value' => '<',
'#name' => 'acquiadam_pager',
'#acquiadam_page' => $page - 1,
'#attributes' => [
'class' => [
'page-button',
'page-previous',
],
],
];
}
$last_page = floor(($current_folder->numassets - 1) / $num_per_page);
$start_page = max(0, $page - 4);
$end_page = min($start_page + 9, $last_page);
for ($i = $start_page; $i <= $end_page; $i++) {
$form['pager-container']['page_' . $i] = [
'#type' => 'button',
'#value' => $i + 1,
'#name' => 'acquiadam_pager',
'#acquiadam_page' => $i,
'#attributes' => [
'class' => [
$i == $page ? 'page-current' : '',
'page-button',
],
],
];
}
if ($end_page > $page) {
$form['pager-container']['next'] = [
'#type' => 'button',
'#value' => '>',
'#name' => 'acquiadam_pager',
'#acquiadam_page' => $page + 1,
'#attributes' => [
'class' => [
'page-button',
'page-next',
],
],
];
$form['pager-container']['last'] = [
'#type' => 'button',
'#value' => '>>',
'#name' => 'acquiadam_pager',
'#acquiadam_page' => $last_page,
'#attributes' => [
'class' => [
'page-button',
'page-last',
],
],
];
}
return $form;
}
public function validate(array &$form, FormStateInterface $form_state) {
if (!empty($form_state
->getTriggeringElement()['#eb_widget_main_submit'])) {
$media_bundle = $this->entityTypeManager
->getStorage('media_type')
->load($this->configuration['media_type']);
$field_definitions = $this->entityFieldManager
->getFieldDefinitions('media', $media_bundle
->id());
$field_map = $media_bundle
->getFieldMap();
if (!isset($field_map['file'])) {
$message = $this
->t('Missing file mapping. Check your media configuration.');
$form_state
->setError($form['widget']['asset-container']['assets'], $message);
return;
}
$file_extensions = $field_definitions[$field_map['file']]
->getItemDefinition()
->getSetting('file_extensions');
$supported_extensions = explode(',', preg_replace('/,?\\s/', ',', $file_extensions));
$assets = array_filter($form_state
->getValue('assets'));
$dam_assets = $this->acquiadam
->getAssetMultiple($assets);
$field_cardinality = $form_state
->get([
'entity_browser',
'validators',
'cardinality',
'cardinality',
]);
if (!count($assets)) {
$form_state
->setError($form['widget']['asset-container'], $this
->t('Please select an asset.'));
}
if ($field_cardinality > 0 && count($assets) > $field_cardinality) {
$message = $this
->formatPlural($field_cardinality, 'You can not select more than 1 entity.', 'You can not select more than @count entities.');
$form_state
->setError($form['widget']['asset-container']['assets'], $message);
}
foreach ($dam_assets as $asset) {
$filetype = $asset->filetype;
$type_is_supported = in_array($filetype, $supported_extensions);
if (!$type_is_supported) {
$message = $this
->t('Please make another selection. The "@filetype" file type is not one of the supported file types (@supported_types).', [
'@filetype' => $filetype,
'@supported_types' => implode(', ', $supported_extensions),
]);
$form_state
->setError($form['widget']['asset-container']['assets'], $message);
}
}
}
}
public function submit(array &$element, array &$form, FormStateInterface $form_state) {
$assets = [];
if (!empty($form_state
->getTriggeringElement()['#eb_widget_main_submit'])) {
$assets = $this
->prepareEntities($form, $form_state);
}
$this
->selectEntities($assets, $form_state);
}
protected function prepareEntities(array $form, FormStateInterface $form_state) {
$asset_ids = $form_state
->getValue('current_selections', []) + array_filter($form_state
->getValue('assets', []));
$media_type = $this->entityTypeManager
->getStorage('media_type')
->load($this->configuration['media_type']);
$source_field = $media_type
->getSource()
->getSourceFieldDefinition($media_type)
->getName();
$existing_ids = $this->entityTypeManager
->getStorage('media')
->getQuery()
->condition('bundle', $media_type
->id())
->condition($source_field, $asset_ids, 'IN')
->execute();
$entities = $this->entityTypeManager
->getStorage('media')
->loadMultiple($existing_ids);
foreach ($entities as $entity) {
$asset_id = $entity
->get($source_field)->value;
if (in_array($asset_id, $asset_ids)) {
unset($asset_ids[$asset_id]);
}
}
$assets = $this->acquiadam
->getAssetMultiple($asset_ids);
foreach ($assets as $asset) {
$entity_values = [
'bundle' => $media_type
->id(),
'uid' => $this->user
->id(),
'langcode' => $this->languageManager
->getCurrentLanguage()
->getId(),
'status' => $asset->status === 'active',
'name' => $asset->name,
$source_field => $asset->id,
];
$entity = $this->entityTypeManager
->getStorage('media')
->create($entity_values);
$entity
->save();
$entity = $this->entityTypeManager
->getStorage('media')
->load($entity
->id());
$entities[] = $entity;
}
return $entities;
}
}