link_filebrowser-1.0.1/src/Plugin/Field/FieldWidget/ExplorerLinkWidget.php
src/Plugin/Field/FieldWidget/ExplorerLinkWidget.php
<?php
namespace Drupal\link_filebrowser\Plugin\Field\FieldWidget;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Field\Attribute\FieldWidget;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Site\Settings;
use Drupal\Core\StreamWrapper\StreamWrapperManagerInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\link\Plugin\Field\FieldWidget\LinkWidget;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Defines the 'explorer_link' field widget.
*/
#[FieldWidget(
id: 'explorer_link',
label: new TranslatableMarkup('Link with File browser'),
description: new TranslatableMarkup('Link with File browser to select folder or file.'),
field_types: ['link'],
)]
class ExplorerLinkWidget extends LinkWidget {
/**
* Constructs a new LinkFormatter.
*
* @param string $plugin_id
* The plugin ID for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The definition of the field to which the formatter is associated.
* @param array $settings
* The formatter settings.
* @param array $third_party_settings
* Third party settings.
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $keyValueFactory
* The key value factory service.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $streamWrapperManager
* The stream wrapper manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, protected KeyValueFactoryInterface $keyValueFactory, protected StreamWrapperManagerInterface $streamWrapperManager, protected AccountInterface $account) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['third_party_settings'],
$container->get('keyvalue'),
$container->get('stream_wrapper_manager'),
$container->get('current_user'),
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings(): array {
return [
'theme' => '',
'folder' => '',
'all' => FALSE,
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state): array {
$element = parent::settingsForm($form, $form_state);
$element['theme'] = [
'#type' => 'select',
'#options' => [
'dark' => $this->t('Dark'),
],
'#empty_option' => $this->t('- Default -'),
'#title' => $this->t("Theme"),
'#default_value' => $this->getSetting('theme'),
];
$element['folder'] = [
'#type' => 'textfield',
'#title' => $this->t('Path folder to browser'),
'#default_value' => $this->getSetting('folder'),
'#required' => TRUE,
'#element_validate' => [[$this, 'validateDirectory']],
'#description' => $this->t('Folder must be in public://.'),
];
$element['all'] = [
'#type' => 'checkbox',
'#title' => $this->t('Load all subfolders/files'),
'#default_value' => $this->getSetting('all'),
'#description' => $this->t('Use for small directory'),
];
return $element;
}
/**
* {@inheritdoc}
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state): array {
$element = parent::formElement($items, $delta, $element, $form, $form_state);
$entity_type = $this->fieldDefinition->getTargetEntityTypeId();
$entity_bundle = $this->fieldDefinition->getTargetBundle();
$field_name = $this->fieldDefinition->getName();
$data_crypt = [
'entity_type' => $entity_type,
'entity_bundle' => $entity_bundle,
'field_name' => $field_name,
];
$path_file = $this->streamWrapperManager->getViaScheme('public')->getDirectoryPath();
$selection_settings_key = Crypt::hmacBase64(serialize($data_crypt), Settings::getHashSalt());
$selection_settings = $this->keyValueFactory->get('filebrowser')->get($selection_settings_key);
$folder = $selection_settings['folder'] ?? '';
$url_upload = NULL;
if ($this->account->hasPermission('add link file browser')) {
$url_upload = Url::fromRoute('link_filebrowser.upload', ['crypt' => $selection_settings_key]);
}
$baseId = $this->fieldDefinition->get('id');
$id = "$baseId-$delta";
$options = [
'attributes' => [
'class' => [
'button',
'button-action',
'button--primary',
'button--small',
'btn-explorer',
'btn',
'btn-sm',
'btn-primary',
'browser',
],
'role' => "button",
'data-theme' => $this->getSetting('theme') ?? NULL,
'data-folder' => "/$path_file/$folder",
'data-upload' => $url_upload?->toString(),
'id' => $id,
],
];
if ($this->account->hasPermission('view link file browser')) {
$url_scan = Url::fromRoute('link_filebrowser.scan', ['crypt' => $selection_settings_key], $options);
}
$link = Link::fromTextAndUrl($this->t('FILE BROWSER'), $url_scan ?? NULL);
$description = $this->t('For a document or a folder hosted on a file server, click on the button FILE BROWSER');
$element["uri"]["#description"] = $description . '<br/>' . $link->toString();
$element["uri"]["#attributes"]["data-url_field_id"] = $id;
$element["title"]["#attributes"]["data-text_field_id"] = $id;
$element["#attached"]["library"][] = 'link_filebrowser/browser';
return $element;
}
/**
* {@inheritdoc}
*/
public function settingsSummary(): array {
$summary = parent::settingsSummary();
$summary[] = $this->t('Theme: @theme', ['@theme' => $this->getSetting('theme') ?? '']);
$summary[] = $this->t('Folder: @folder', ['@folder' => $this->getSetting('folder')]);
$summary[] = $this->t('All sub folder: @all', ['@all' => !empty($this->getSetting('all'))]);
return $summary;
}
/**
* {@inheritdoc}
*/
public function validateDirectory(array $form, FormStateInterface $form_state) :void {
$field_name = $this->fieldDefinition->getName();
$entity_type = $this->fieldDefinition->getTargetEntityTypeId();
$entity_bundle = $this->fieldDefinition->getTargetBundle();
$folder = $form_state->getValue(['fields', $field_name, 'settings_edit_form', 'settings', 'folder']);
$folder = $this->cleanPath($folder);
$all = $form_state->getValue(['fields', $field_name, 'settings_edit_form', 'settings', 'all']);
$data_crypt = [
'entity_type' => $entity_type,
'entity_bundle' => $entity_bundle,
'field_name' => $field_name,
];
$selection_settings_key = Crypt::hmacBase64(serialize($data_crypt), Settings::getHashSalt());
$data_crypt['folder'] = $folder;
$data_crypt['all'] = $all;
$this->keyValueFactory->get('filebrowser')->set($selection_settings_key, $data_crypt);
}
/**
* {@inheritdoc}
*/
public function cleanPath(string $path, $isReplaceSeparatorSystem = FALSE) :string {
$path = preg_replace('/^\/+|\/+$/', '', $path);
$path = preg_replace('/\/+/', '/', $path);
if ($isReplaceSeparatorSystem) {
$path = str_replace('/', DIRECTORY_SEPARATOR, $path);
}
return html_entity_decode($path);
}
}
