link_filebrowser-1.0.1/src/Plugin/Block/FileBrowserBlock.php
src/Plugin/Block/FileBrowserBlock.php
<?php
namespace Drupal\link_filebrowser\Plugin\Block;
use Drupal\Component\Utility\Crypt;
use Drupal\Core\Block\Attribute\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\RendererInterface;
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 Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a file browser block.
*/
#[Block(
id: "link_filebrowser",
admin_label: new TranslatableMarkup("File browser"),
category: new TranslatableMarkup("File browser")
)]
class FileBrowserBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* File browser block constructor.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The render service.
* @param \Drupal\Core\KeyValueStore\KeyValueFactoryInterface $keyValueFactory
* The key value factory service.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $streamWrapperManager
* The stream wrapper manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, protected RendererInterface $renderer, protected KeyValueFactoryInterface $keyValueFactory, protected AccountInterface $account, protected StreamWrapperManagerInterface $streamWrapperManager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new self(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('renderer'),
$container->get('keyvalue'),
$container->get('current_user'),
$container->get('stream_wrapper_manager'),
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'theme' => '',
'folder' => '',
'all' => FALSE,
'modal' => FALSE,
'viewer' => 'google',
'redirect_share' => '',
];
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form['theme'] = [
'#type' => 'select',
'#options' => [
'google' => $this->t('Dark'),
],
'#empty_option' => $this->t('- Default -'),
'#title' => $this->t("Theme"),
'#default_value' => $this->configuration['theme'],
];
$form['folder'] = [
'#type' => 'textfield',
'#title' => $this->t('Path folder to browser'),
'#default_value' => $this->configuration['folder'],
'#required' => TRUE,
'#description' => $this->t('Folder must be in public://.'),
];
$form['all'] = [
'#type' => 'checkbox',
'#title' => $this->t('Load all subfolders/files'),
'#default_value' => $this->configuration['all'],
'#description' => $this->t('Use for small directory'),
];
$form['modal'] = [
'#type' => 'checkbox',
'#title' => $this->t('Open with modal'),
'#default_value' => $this->configuration['modal'],
'#description' => $this->t('Use with bootstrap modal 5'),
];
$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->configuration['viewer'],
];
$form['redirect_share'] = [
'#type' => 'textfield',
'#title' => $this->t('Redirect share'),
'#default_value' => $this->configuration['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 blockSubmit($form, FormStateInterface $form_state): void {
$values = $form_state->getValues();
$this->configuration['theme'] = $values['theme'];
$this->configuration['folder'] = $values['folder'];
$this->configuration['modal'] = $values['modal'];
$this->configuration['all'] = $values['all'];
$this->configuration['viewer'] = $values['viewer'];
$this->configuration['redirect_share'] = $values['redirect_share'];
// Render crypt key.
$data_crypt = [
'folder' => $this->cleanPath($values['folder']),
'all' => $values['all'],
];
$selection_settings_key = Crypt::hmacBase64(serialize($data_crypt), Settings::getHashSalt());
$this->keyValueFactory->get('filebrowser')->set($selection_settings_key, $data_crypt);
}
/**
* {@inheritdoc}
*/
public function build(): array {
$config = $this->getConfiguration();
$selection_settings_key = Crypt::hmacBase64(serialize([
'folder' => $this->cleanPath($config['folder']),
'all' => $config['all'],
]), Settings::getHashSalt());
$url_scan = NULL;
if ($this->account->hasPermission('view link file browser')) {
$url_scan = Url::fromRoute('link_filebrowser.list_files', ['crypt' => $selection_settings_key]);
}
$url_upload = NULL;
if ($this->account->hasPermission('add link file browser')) {
$url_upload = Url::fromRoute('link_filebrowser.upload', ['crypt' => $selection_settings_key]);
}
$path_file = $this->streamWrapperManager->getViaScheme('public')->getDirectoryPath();
$url_share = Url::fromRoute('link_filebrowser.share_page', ['crypt' => '#crypt'], ['absolute' => TRUE]);
if (!empty($config['redirect_share'])) {
$url_share->setOption('query', ['r' => $config['redirect_share']]);
}
$url_download = Url::fromRoute('link_filebrowser.share', ['crypt' => '#crypt'], ['absolute' => TRUE]);
$build['content'] = [
'#theme' => 'link_file_browser_block',
'#theme_mode' => $config['theme'] ?? NULL,
'#url_scan' => $url_scan?->toString(),
'#url_upload' => $url_upload?->toString(),
'#url_share' => $url_share->toString(),
'#url_download' => $url_download->toString(),
'#url_public' => $path_file,
'#folder' => $config['folder'],
'#modal' => !empty($config['modal']),
'#title' => $config['label'],
'#id' => $config['id'] . substr(uniqid('', TRUE), -5),
'#viewer' => $config['viewer'],
'#url' => trim(Url::fromUserInput('/', ['absolute' => TRUE])->toString(), '/'),
'#attributes' => [
'class' => [
'browser-block',
],
],
];
if (!empty($config['modal'])) {
$build['#attached']['library'][] = 'core/drupal.dialog.ajax';
}
$build['#attached']['library'][] = 'link_filebrowser/browser.block';
return $build;
}
/**
* {@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);
}
}
