io-8.x-1.x-dev/modules/io_browser/src/IoBrowser.php
modules/io_browser/src/IoBrowser.php
<?php
namespace Drupal\io_browser;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\blazy\BlazyEntityInterface;
use Drupal\blazy\BlazyFormatterInterface;
use Drupal\blazy\Field\BlazyField;
use Drupal\blazy\Form\BlazyAdminInterface;
use Drupal\io\IoManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines a IO Browser.
*/
class IoBrowser implements IoBrowserInterface {
use StringTranslationTrait;
/**
* The io manager interface.
*
* @var \Drupal\io\IoManagerInterface
*/
protected $ioManager;
/**
* The blazy admin.
*
* @var \Drupal\blazy\Form\BlazyAdminInterface
*/
protected $admin;
/**
* The blazy entity interface.
*
* @var \Drupal\blazy\BlazyEntityInterface
*/
protected $blazyEntity;
/**
* The field formatter manager.
*
* @var \Drupal\blazy\BlazyFormatterInterface
*/
protected $formatter;
/**
* The current page path.
*
* @var string
*/
protected $currentPath;
/**
* Constructs a IoBrowser instance.
*/
public function __construct(
IoManagerInterface $io_manager,
BlazyAdminInterface $admin,
BlazyEntityInterface $blazy_entity,
BlazyFormatterInterface $formatter,
) {
$this->ioManager = $io_manager;
$this->admin = $admin;
$this->blazyEntity = $blazy_entity;
$this->formatter = $formatter;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('io.manager'),
$container->get('blazy.admin.formatter'),
$container->get('blazy.entity'),
$container->get('blazy.formatter')
);
}
/**
* {@inheritdoc}
*/
public function ioManager() {
return $this->ioManager;
}
/**
* {@inheritdoc}
*/
public function admin() {
return $this->admin;
}
/**
* {@inheritdoc}
*/
public function blazyEntity() {
return $this->blazyEntity;
}
/**
* {@inheritdoc}
*/
public function formatter() {
return $this->formatter;
}
/**
* {@inheritdoc}
*/
public function buildWigetSettingsForm(array &$form, array $definition) {
$this->checkFieldDefinitions($definition);
$settings = $definition['settings'];
$cardinality = $definition['cardinality'] ?? '';
$plugin_id_widget = $definition['plugin_id_widget'] ?? '';
$plugin_id_widget = $definition['plugin_id_entity_display'] ?? $plugin_id_widget;
$target_type = $definition['target_type'] ?? '';
$definition['grid_form'] = $cardinality != 1;
$definition['grid_simple'] = TRUE;
$definition['no_layouts'] = TRUE;
$definition['no_grid_header'] = TRUE;
$definition['responsive_image'] = FALSE;
$definition['style'] = TRUE;
$definition['vanilla'] = FALSE;
$definition['libraries'] = ['io_browser/admin'];
if ($target_type == 'file') {
$definition['no_view_mode'] = !$this->formatter->moduleExists('file_entity');
}
// Build form elements.
$this->admin->buildSettingsForm($form, $definition);
// $form['closing']['#attached']['library'][] = 'io_browser/admin';
$field_name = $definition['field_name'] ?? $settings['field_name'] ?? '';
if ($field_name) {
$form['field_name'] = [
'#type' => 'hidden',
'#default_value' => $field_name,
];
}
// IO Browser can display a plain static grid or slick carousel.
if (isset($form['style'])) {
$form['opening']['#prefix'] = '<h3>' . $this->t('IO Browser') . '</h3><p>' . $this->t('To disable, leave Display style empty.') . '</p>';
$description = $form['style']['#description'] ?? '';
$form['style']['#description'] = $description . ' ' . $this->t('Leave empty to disable IO Browser widget.');
// Single image preview should only have one option.
if ($cardinality == 1) {
$form['style']['#options'] = [];
$form['style']['#options']['single'] = $this->t('Single Preview');
}
}
if (isset($form['view_mode'])) {
$form['view_mode']['#weight'] = 22;
$form['view_mode']['#description'] = $this->t('Will fallback to this view mode, else entity label. Be sure to enable and configure the view mode. Leave it Default if unsure.');
}
// The media_library_widget has no image style defined.
if (isset($form['image_style'])) {
$form['image_style']['#description'] = $this->t('Choose image style for the preview, if applicable. If any defined above, this will override it.');
}
if ($target_type && !in_array($target_type, ['file', 'media'])) {
unset($form['image_style'], $form['thumbnail_style']);
}
if (isset($form['elevatezoomplus'])) {
unset($form['elevatezoomplus']);
}
/*
foreach (Element::children($form) as $key) {
if (in_array($key, ['style', 'opening', 'closing'])) {
continue;
}
$form[$key]['#states'] = [
'visible' => [
'select[name$="[style]"]' => ['!value' => ''],
],
];
}
*/
}
/**
* {@inheritdoc}
*/
public function preprocessViewsView(array &$variables) {
$view = $variables['view'];
$attrs = &$variables['attributes'];
if ($plugin_id = $view->getStyle()->getPluginId()) {
if ($plugin_id == 'io_browser') {
$attrs['class'][] = 'ib';
$attrs['class'][] = 'view--ib';
// Adds class based on entity type ID for further styling.
if ($entity_type = $view->getBaseEntityType()->id()) {
$attrs['class'][] = 'view--' . str_replace('_', '-', $entity_type);
}
// Adds class based on pager to position it either fixed, or relative.
if ($pager_id = $view->getPager()->getPluginId()) {
$attrs['class'][] = 'view--pager-' . str_replace('_', '-', $pager_id);
}
}
}
// Adds the active grid/ list (table-like) class regardless style plugin.
if (isset($view->exposed_widgets['#ib_settings'])) {
$attrs['class'][] = 'view--ib-' . $view->exposed_widgets['#ib_settings']['active'];
}
}
/**
* {@inheritdoc}
*/
public function preprocessBlazy(array &$variables): void {
$settings = &$variables['settings'];
$blazies = $settings['blazies'];
if ($blazies->is('io_browser')) {
$buttons = ['select', 'info'];
$variables['postscript']['ib_buttons'] = IoBrowserUtil::buildButtons($buttons);
}
}
/**
* Returns available bundles.
*
* @todo use BlazyField::getAvailableBundles($field) post blazy:2.17.
*/
public function getAvailableBundles($field): array {
$target_type = $field->getSetting('target_type');
$views_ui = $field->getSetting('handler') == 'default';
$handlers = $field->getSetting('handler_settings');
$targets = $handlers ? ($handlers['target_bundles'] ?? []) : [];
$bundles = $views_ui ? [] : $targets;
// Fix for Views UI not recognizing Media bundles, unlike Formatters.
if (empty($bundles)
&& $target_type
&& $service = $this->formatter->service('entity_type.bundle.info')) {
$bundles = $service->getBundleInfo($target_type);
}
return $bundles;
}
/**
* Checks for the current definitions with various AJAX contents.
*
* @see /admin/structure/types/manage/page/form-display
*/
public function checkFieldDefinitions(array &$definition) {
$field = $definition['field_definition'] ?? NULL;
if (!$field) {
return;
}
$target_type = $field->getSetting('target_type');
$definition['cardinality'] = $cardinality = $field->getFieldStorageDefinition()->getCardinality();
$multiple = $cardinality != 1;
BlazyField::settings($definition, $field);
$settings = $definition['settings'];
$blazies = $definition['blazies'];
$is_grid = !empty($settings['style'])
&& !empty($settings['grid']);
$blazies->set('cardinality', $cardinality)
->set('is.grid', $is_grid)
->set('is.multiple', $multiple);
$bundles = $this->getAvailableBundles($field);
if ($bundles && $target_type == 'media') {
$definition['fieldable_form'] = TRUE;
$definition['multimedia'] = TRUE;
$definition['images'] = $this->getFieldOptions($bundles, ['image'], $target_type);
}
}
/**
* Returns fields as options. Passing empty array will return them all.
*
* @return array
* The available fields as options.
*/
public function getFieldOptions(array $bundles = [], array $names = [], $target_type = NULL): array {
return $this->admin->getFieldOptions($bundles, $names, $target_type);
}
/**
* Overrides image style since preview is not always available.
*
* Not called after AJAX.
*/
public function toBlazy(array $display, array &$sets, $delta = 0, $label = NULL): array {
$blazies = $sets['blazies']->reset($sets);
// Convert core image formatter to theme_blazy for consistency.
if (!empty($sets['image_style']) && isset($display['#style_name'])) {
foreach (['height', 'width', 'uri'] as $key) {
$value = $display['#' . $key] ?? NULL;
$sets[$key] = $value;
$blazies->set('image.' . $key, $value);
}
$build = [];
$sets['delta'] = $delta;
$blazies->set('delta', $delta)
->set('is.unlazy', TRUE);
if ($label) {
$label = is_string($label) ? ['#markup' => $label] : $label;
$ib_label = $this->formatter->toHtml($label, 'div', 'ib__label');
$build['overlay']['ib_label'] = $ib_label;
}
// $data['wrapper_attributes']['class'][] = 'grid__content';
// $build['media_attributes']['class'][] = 'ib__preview';
$build['#delta'] = $delta;
$build['#settings'] = $sets;
return $this->formatter->getBlazy($build);
}
return $display;
}
/**
* Checks if IO Browser is applicable.
*/
public function isApplicable(array &$settings) {
$blazies = $this->formatter->verifySafely($settings);
$id = $blazies->get('view.plugin_id');
$is_browser = $id == 'io_browser';
$is_widget = ($settings['ib_context'] ?? NULL) == 'widget';
if ($is_widget || $is_browser) {
$blazies->set('is.io_browser', $is_browser)
->set('is.io_widget', $is_widget);
return TRUE;
}
return FALSE;
}
}
