foldershare-8.x-1.2/src/Form/AdminSettingsTraits/AdminSettingsFilesTab.php
src/Form/AdminSettingsTraits/AdminSettingsFilesTab.php
<?php
namespace Drupal\foldershare\Form\AdminSettingsTraits;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StreamWrapper\PrivateStream;
use Drupal\foldershare\Constants;
use Drupal\foldershare\ManageFilenameExtensions;
use Drupal\foldershare\Settings;
use Drupal\foldershare\Utilities\LinkUtilities;
use Drupal\foldershare\Entity\FolderShare;
/**
* Manages the "Files" tab for the module's settings form.
*
* <B>Warning:</B> This is an internal trait that is strictly used by
* the AdminSettings form class. It is a mechanism to group functionality
* to improve code management.
*
* @ingroup foldershare
*/
trait AdminSettingsFilesTab {
/*---------------------------------------------------------------------
*
* Build.
*
*---------------------------------------------------------------------*/
/**
* Builds the fiels tab.
*
* @param array $form
* An associative array containing the structure of the form. The form
* is modified to include additional render elements for the tab.
* @param \Drupal\Core\Form\FormStateInterface $formState
* The current state of the form.
* @param string $tabGroup
* The name of the tab group.
*/
private function buildFilesTab(
array &$form,
FormStateInterface $formState,
string $tabGroup) {
//
// Find installed modules.
// -----------------------
// Tab sections vary their presentation based upon what modules are
// installed at the site.
$mh = \Drupal::service('module_handler');
$helpInstalled = $mh->moduleExists('help');
//
// Set up tab names.
// -----------------
// Create the machine name for the tab and the tab's title.
$tabMachineName = 'files';
$tabTitle = $this->t('Files');
$tabPaneTitle = $this->t('Manage files');
//
// Set up class names.
// -------------------
// Use a set of standard class names for tab sections.
$moduleName = self::makeCssSafe(Constants::MODULE);
$tabName = $moduleName . '_' . $tabMachineName . '_tab';
$tabSubtitleClass = $moduleName . '-settings-subtitle';
$sectionWrapperClass = $moduleName . '-settings-section-wrapper';
$sectionClass = $moduleName . '-settings-section';
$sectionDescriptionClass = $moduleName . '-settings-section-description';
$itemDefaultClass = $moduleName . '-settings-item-default';
$itemNoteClass = $moduleName . '-settings-item-note';
$warningClass = $moduleName . '-warning';
$restoreExtensionsButton = $moduleName . '_extensions_restore';
//
// Create the tab
// --------------
// Start the tab with a title, subtitle, and description.
$form[$tabName] = [
'#type' => 'details',
'#open' => FALSE,
'#group' => $tabGroup,
'#title' => $tabTitle,
'#description' => [
'subtitle' => [
'#type' => 'html_tag',
'#tag' => 'h2',
'#value' => $tabPaneTitle,
'#attributes' => [
'class' => [$tabSubtitleClass],
],
],
'description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'Control where files are saved and the file name extensions supported.'),
'#attributes' => [
'class' => [
$moduleName . '-settings-description',
],
],
],
],
'#attributes' => [
'class' => [
$moduleName . '-settings-tab',
$moduleName . '-files-tab',
],
],
];
//
// File system.
// ------------
// If the site currently has stored files, then the storage scheme
// and subdirectory choice cannot be changed.
//
// If the site doesn't have stored files, but the private file system
// has not been configured, then the storage scheme cannot be changed.
$inUseWarning = '';
$noPrivateWarning = '';
$storageSchemeDisabled = FALSE;
if (FolderShare::hasFiles() === TRUE) {
// Create a link to the Drupal core system page to delete all content
// for the entity type.
$inUseWarning = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'This setting is disabled because there are still files managed by this module. You must @deleteAllLink files first.',
[
'@deleteAllLink' => LinkUtilities::createRouteLink(
'system.prepare_modules_entity_uninstall',
'',
$this->t('Delete all'),
[
'entity_type_id' => FolderShare::ENTITY_TYPE_ID,
]),
]),
'#attributes' => [
'class' => [
$warningClass,
$itemNoteClass,
],
],
];
$storageSchemeDisabled = TRUE;
}
if (empty(PrivateStream::basePath()) === TRUE) {
if ($helpInstalled === TRUE) {
$noPrivateWarning = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'This setting is limited to the <em>Public</em> directory because a <em>Private</em> directory has not been set up yet (see @fileHelpLink and @fileDocLink, @fileSettingsLink settings, and the "file_private_path" setting in the site\'s "settings.php" file).',
[
'@fileSettingsLink' => LinkUtilities::createRouteLink(
'system.file_system_settings',
'',
$this->t('File system')),
'@fileHelpLink' => LinkUtilities::createHelpLink(
'file',
$this->t('File help')),
'@fileDocLink' => LinkUtilities::createDocLink(
'file',
$this->t('File documentation')),
]),
'#attributes' => [
'class' => [
$warningClass,
$itemNoteClass,
],
],
];
}
else {
$noPrivateWarning = [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'This setting is limited to the <em>Public</em> directory because a <em>Private</em> directory has not been set up yet (see @fileDocLink, @fileSettingsLink settings, and the "file_private_path" setting in the site\'s "settings.php" file).',
[
'@fileSettingsLink' => LinkUtilities::createRouteLink(
'system.file_system_settings',
'',
$this->t('File system')),
'@fileDocLink' => LinkUtilities::createDocLink(
'file',
$this->t('File documentation')),
]),
'#attributes' => [
'class' => [
$warningClass,
$itemNoteClass,
],
],
];
}
$storageSchemeDisabled = TRUE;
}
$options = [
'public' => $this->t('Public directory'),
'private' => $this->t('Private directory'),
];
$form[$tabName]['directories'] = [
'#type' => 'details',
'#title' => $this->t('Directories'),
'#open' => FALSE,
'#attributes' => [
'class' => [$sectionWrapperClass],
],
'section' => [
'#type' => 'container',
'#attributes' => [
'class' => [$sectionClass],
],
'section-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
"Store files locally in the site's <em>Public</em> or <em>Private</em> directories. <em>Private</em> directories provide better security."),
'#attributes' => [
'class' => [$sectionDescriptionClass],
],
],
'directory-choice' => [
'#type' => 'select',
'#options' => $options,
'#default_value' => Settings::getFileScheme(),
'#disabled' => $storageSchemeDisabled,
'#name' => 'directory-choice',
],
// The default setting.
'directory-choice-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'Default: @default',
[
'@default' => $options[Settings::getFileSchemeDefault()],
]),
'#attributes' => [
'class' => [
$itemDefaultClass,
$itemNoteClass,
],
],
],
],
];
// Add warning if there are things disabled.
if (empty($noPrivateWarning) === FALSE) {
$form[$tabName]['directories']['section']['warning'] = $noPrivateWarning;
}
elseif (empty($inUseWarning) === FALSE) {
$form[$tabName]['directories']['section']['warning'] = $inUseWarning;
}
//
// File name extensions
// --------------------
// Select whether file uploads should be restricted based on their
// file name extensions, and what extensions are allowed.
$form[$tabName]['fileextensions'] = [
'#type' => 'details',
'#title' => $this->t('File name extensions'),
'#open' => FALSE,
'#attributes' => [
'class' => [$sectionWrapperClass],
],
'section' => [
'#type' => 'container',
'#attributes' => [
'class' => [$sectionClass],
],
'section-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'Allow all file name extensions or restrict them.'),
'#attributes' => [
'class' => [$sectionDescriptionClass],
],
],
// A checkbox to enable/disable allowing all extensions.
'all-file-extensions' => [
'#type' => 'checkbox',
'#title' => $this->t('Allow all extensions'),
'#default_value' => (Settings::getFileRestrictExtensions() === FALSE),
'#return_value' => 'enabled',
'#name' => 'all-file-extensions',
],
// The default setting.
'all-file-extensions-default' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Default: Allow all extensions'),
'#attributes' => [
'class' => [
$itemDefaultClass,
$itemNoteClass,
],
],
],
// Specific extensions.
'set-extensions' => [
'#type' => 'container',
'#states' => [
'visible' => [
'input[name="all-file-extensions"]' => [
'checked' => FALSE,
],
],
],
// A list of allowed extensions.
'file-extensions' => [
'#type' => 'textarea',
'#title' => $this->t('Allowed extensions:'),
'#default_value' => Settings::getAllowedNameExtensions(),
'#required' => FALSE,
'#rows' => 15,
'#name' => 'file-extensions',
'#description' => $this->t(
'Separate extensions with spaces. Do not include dots. Changing this list does not affect files that are already on the site.'),
],
// A button to restore the default configuration.
$restoreExtensionsButton => [
'#type' => 'submit',
'#value' => $this->t('Restore'),
'#name' => $restoreExtensionsButton,
'#attributes' => [
'class' => [
$restoreExtensionsButton,
],
],
],
// A description for the restore button.
'extensions-restore-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Restore extensions to default values.'),
'#attributes' => [
'class' => [
$restoreExtensionsButton . '_description',
],
],
],
],
],
];
// Get the current extensions, if any, on the form.
$value = $formState->getValue('file-extensions');
if ($value !== NULL) {
$form[$tabName]['fileextensions']['section']['file-extensions']['#value'] = $value;
}
}
/*---------------------------------------------------------------------
*
* Validate.
*
*---------------------------------------------------------------------*/
/**
* Validates form values.
*
* @param array $form
* The form configuration.
* @param \Drupal\Core\Form\FormStateInterface $formState
* The entered values for the form.
*/
private function validateFilesTab(
array &$form,
FormStateInterface $formState) {
$moduleName = self::makeCssSafe(Constants::MODULE);
$trigger = $formState->getTriggeringElement();
//
// Restore filename extensions.
// ----------------------------
// Restore the list of allowed file name extensions.
$restoreExtensionsButton = $moduleName . '_extensions_restore';
if ($trigger['#name'] === $restoreExtensionsButton) {
// Revert extensions configuration.
$value = Settings::getAllowedNameExtensionsDefault();
Settings::setAllowedNameExtensions($value);
ManageFilenameExtensions::setAllowedNameExtensions($value);
// Reset the form's extensions list.
$formInput = $formState->getUserInput();
$formInput['file-extensions'] = $value;
$formState->setUserInput($formInput);
// Rebuild the page.
$formState->setRebuild(TRUE);
$formState->cleanValues();
$formState->setTriggeringElement(NULL);
\Drupal::messenger()->addMessage(
$this->t('The file extensions list has been restored to its default values.'),
'status');
return;
}
//
// Directories.
// ------------
// It must be "public" or "private". If "private", the site's private
// file system must have been configured.
$hasPrivate = empty(PrivateStream::basePath()) === FALSE;
$scheme = $formState->getValue('directory-choice');
if ($scheme !== 'public' && $scheme !== 'private') {
$formState->setErrorByName(
'directory-choice',
$this->t('The directory choice must be either <em>Public</em> or <em>Private</em>.'));
}
if ($scheme === 'private' && $hasPrivate === FALSE) {
$formState->setErrorByName(
'directory-choice',
$this->t('The <em>Private</em> directory is not available because the site has not been configured to support it yet.'));
}
}
/*---------------------------------------------------------------------
*
* Submit.
*
*---------------------------------------------------------------------*/
/**
* Stores submitted form values.
*
* @param array $form
* The form configuration.
* @param \Drupal\Core\Form\FormStateInterface $formState
* The entered values for the form.
*/
private function submitFilesTab(
array &$form,
FormStateInterface $formState) {
// File directory.
if (FolderShare::hasFiles() === FALSE) {
$value = $formState->getValue('directory-choice');
Settings::setFileScheme($value);
}
// Allow all file extensions or not.
$value = $formState->getValue('all-file-extensions');
$allowAll = ($value === 'enabled') ? TRUE : FALSE;
Settings::setFileRestrictExtensions($allowAll === FALSE);
// Specific extensions, set only if not allowing all extensions.
if ($allowAll === FALSE) {
$extensions = $formState->getValue('file-extensions');
Settings::setAllowedNameExtensions($extensions);
}
// Forward extensions to the file field.
if ($allowAll === TRUE) {
// Everything allowed. No extensions list.
ManageFilenameExtensions::setAllowedNameExtensions('');
}
else {
ManageFilenameExtensions::setAllowedNameExtensions(
Settings::getAllowedNameExtensions());
}
}
}
