link_filebrowser-1.0.1/src/Plugin/Field/FieldFormatter/ExplorerLinkFormatter.php
src/Plugin/Field/FieldFormatter/ExplorerLinkFormatter.php
<?php
namespace Drupal\link_filebrowser\Plugin\Field\FieldFormatter;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Field\Attribute\FieldFormatter;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\File\FileSystemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Path\PathValidatorInterface;
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\FieldFormatter\LinkFormatter;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\user\Entity\Role;
/**
* Plugin implementation of the 'explorer_link' formatter.
*/
#[FieldFormatter(
id: 'explorer_link',
label: new TranslatableMarkup('Link with File browser'),
field_types: [
'link',
],
)]
class ExplorerLinkFormatter extends LinkFormatter {
/**
* 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 string $label
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Third party settings.
* @param \Drupal\Core\Path\PathValidatorInterface $path_validator
* The path validator service.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $streamWrapperManager
* The stream wrapper manager.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $keyValueFactory
* The key value factory service.
* @param \Drupal\Core\File\FileSystemInterface $fileSystem
* The file system service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* The entity type manager.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, PathValidatorInterface $path_validator, protected StreamWrapperManagerInterface $streamWrapperManager, protected AccountInterface $account, protected KeyValueFactoryInterface $keyValueFactory, protected FileSystemInterface $fileSystem, protected EntityTypeManagerInterface $entityTypeManager) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $path_validator);
}
/**
* {@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['label'],
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('path.validator'),
$container->get('stream_wrapper_manager'),
$container->get('current_user'),
$container->get('keyvalue'),
$container->get('file_system'),
$container->get('entity_type.manager'),
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return [
'theme' => '',
'viewer' => 'google',
'redirect_share' => '',
] + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form['theme'] = [
'#type' => 'select',
'#options' => [
'dark' => $this->t('Dark'),
],
'#empty_option' => $this->t('- Default -'),
'#title' => $this->t("Theme"),
'#default_value' => $this->getSetting('theme'),
];
$form['viewer'] = [
'#type' => 'select',
'#options' => [
'google' => $this->t('Google office'),
'microsoft' => $this->t('Microsoft office'),
],
'#empty_option' => $this->t('- Select -'),
'#title' => $this->t("Office Online Viewer"),
'#default_value' => $this->getSetting('viewer'),
];
$form['redirect_share'] = [
'#type' => 'textfield',
'#title' => $this->t("Redirect share"),
'#default_value' => $this->getSetting('redirect_share'),
'#description' => $this->t('Redirect path after file download is complete. Leaving blank will stay on the current page'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function settingsSummary(): array {
$summary = [];
if ($this->getSetting('viewer')) {
$summary['theme'] = $this->t("Theme: @theme", ['@theme' => $this->getSetting('theme') ?? 'light']);
$summary['viewer'] = $this->t("View file with @viewer viewer", ['@viewer' => $this->getSetting('viewer') ?? '']);
$summary['redirect_share'] = $this->t("Redirect share: @url", ['@url' => $this->getSetting('redirect_share') ?? '']);
}
return $summary;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode): array {
$elements = parent::viewElements($items, $langcode);
foreach ($elements as $delta => &$element) {
$path_file = $this->streamWrapperManager->getViaScheme('public')->getDirectoryPath();
$url = $element['#url'];
$base_path = base_path();
if ($url && !$url->isRouted() && !$url->isExternal() && str_starts_with($url->toString(), "$base_path$path_file")) {
$settings = $this->getSettings();
$entity = $items->getEntity();
$data_crypt = [
'entity_type' => $entity->getEntityTypeId(),
'entity_bundle' => $entity->bundle(),
'field_name' => $items->getName(),
];
$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_share = Url::fromRoute('link_filebrowser.share_page', ['crypt' => '#crypt'], ['absolute' => TRUE]);
if (!empty($settings['redirect_share'])) {
$url_share->setOption('query', ['r' => $settings['redirect_share']]);
}
$elements[$delta]["#options"]["attributes"]['data-url_share'] = $url_share->toString();
$url_download = Url::fromRoute('link_filebrowser.share', ['crypt' => '#crypt'], ['absolute' => TRUE]);
$elements[$delta]["#options"]["attributes"]['data-url_download'] = $url_download->toString();
$link_path = str_replace('base:', '', $url->getUri());
$system_path = $this->cleanPath($link_path, TRUE);
if (is_dir($this->fileSystem->realpath($system_path))) {
$elements[$delta]["#options"]["attributes"]['class'][] = 'explorer';
$directory = str_replace("$path_file/$folder", '', $link_path);
$elements[$delta]["#options"]["attributes"]['data-folder'] = $directory;
$elements[$delta]["#options"]["attributes"]['data-viewer'] = match ($settings['viewer']) {
'microsoft' => 'https://view.officeapps.live.com/op/view.aspx?src=',
default => 'https://docs.google.com/gview?embedded=true&url='
};
$elements[$delta]["#options"]["attributes"]['data-theme'] = $settings['theme'] ?? NULL;
$elements[$delta]["#options"]["attributes"]['data-url'] = trim(Url::fromUserInput('/', ['absolute' => TRUE])->toString(), '/');
// Check permission view directory.
if ($this->account->hasPermission('view link file browser')) {
$url_scan = Url::fromRoute('link_filebrowser.scan', ['crypt' => $selection_settings_key]);
$elements[$delta]["#options"]["attributes"]['data-url_scan'] = $url_scan->toString();
}
// Check permission add upload.
if ($this->account->hasPermission('add link file browser')) {
$url_upload = Url::fromRoute('link_filebrowser.upload', ['crypt' => $selection_settings_key]);
$elements[$delta]["#options"]["attributes"]['data-url_upload'] = $url_upload->toString();
}
}
$user_list = $this->entityTypeManager->getStorage('user')->loadMultiple();
$role_list = Role::loadMultiple();
$user_options = [];
if ($user_list) {
foreach ($user_list as $user_id => $user) {
$user_options[] = ['key' => $user_id, 'label' => $user->getDisplayName()];
}
}
$role_options = [];
if ($role_list) {
foreach ($role_list as $role_id => $role) {
$role_options[] = ['key' => $role_id, 'label' => $role->label()];
}
}
$element['#attached']['drupalSettings']['user_options'] = $user_options;
$element['#attached']['drupalSettings']['role_options'] = $role_options;
$element['#attached']['library'][] = 'link_filebrowser/browser';
}
}
return $elements;
}
/**
* {@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);
}
}
