foldershare-8.x-1.2/src/Form/AdminSettingsTraits/AdminSettingsServicesTab.php
src/Form/AdminSettingsTraits/AdminSettingsServicesTab.php
<?php
namespace Drupal\foldershare\Form\AdminSettingsTraits;
use Drupal\Core\Form\FormStateInterface;
use Drupal\foldershare\Constants;
use Drupal\foldershare\Settings;
use Drupal\foldershare\Utilities\ConfigurationUtilities;
use Drupal\foldershare\Utilities\LinkUtilities;
use Drupal\foldershare\ManageUsageStatistics;
use Drupal\foldershare\ManageSearch;
/**
* The "Services" 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 AdminSettingsServicesTab {
/*---------------------------------------------------------------------
*
* Build.
*
*---------------------------------------------------------------------*/
/**
* Builds the services 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 buildServicesTab(
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');
$dblogInstalled = $mh->moduleExists('dblog');
$searchInstalled = $mh->moduleExists('search');
//
// Set up tab names.
// -----------------
// Create the machine name for the tab and the tab's title.
$tabMachineName = 'services';
$tabTitle = $this->t('Services');
$tabPaneTitle = $this->t('Manage services');
//
// 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';
$noteClass = $moduleName . '-note';
$clearSearchButton = $moduleName . '_search_clear';
$restoreSearchButton = $moduleName . '_search_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 activity logging, search indexing, and usage data.'),
'#attributes' => [
'class' => [
$moduleName . '-settings-description',
],
],
],
],
'#attributes' => [
'class' => [
$moduleName . '-settings-tab ',
$moduleName . '-services-tab',
],
],
];
//
// Manage logging.
// ---------------
// Add a checkbox for logging.
//
// Drupal's logger API routes log messages to all installed loggers.
// The core "dblog" module is one such logger, but there are contributed
// modules for many more types of loggers. Unfortunately, there is no
// direct way to ask Drupal if there are any loggers at all. If there
// are none installed, all logging is silently ignored.
//
// Since we cannot determine if there is a logger installed, we cannot
// disable this UI if there are no loggers. Just leave it enabled.
//
// In the very common case where core's "dblog" logger is installed,
// add a link to its pages.
if ($dblogInstalled === TRUE &&
$helpInstalled === TRUE) {
$description = $this->t(
'Activity logging records each time a file or folder is created, deleted, downloaded, or changed. Activity is shown on the page of @dblogListLink (see @dblogHelpLink).',
[
'@dblogListLink' => LinkUtilities::createRouteLink(
'dblog.overview'),
'@dblogHelpLink' => LinkUtilities::createHelpLink(
'dblog',
$this->t('help')),
]);
}
elseif ($dblogInstalled === TRUE &&
$helpInstalled === FALSE) {
$description = $this->t(
'Activity logging records each time a file or folder is created, deleted, downloaded, or changed. Activity is shown on the page of @dblogListLink.',
[
'@dblogListLink' => LinkUtilities::createRouteLink(
'dblog.overview'),
]);
}
else {
$description = $this->t(
'Activity logging records each time a file or folder is created, deleted, downloaded, or changed.');
}
$form[$tabName]['manage-logging'] = [
'#type' => 'details',
'#title' => $this->t('Activity logs'),
'#open' => FALSE,
'#attributes' => [
'class' => [$sectionWrapperClass],
],
'section' => [
'#type' => 'container',
'#attributes' => [
'class' => [$sectionClass],
],
'section-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $description,
'#attributes' => [
'class' => [$sectionDescriptionClass],
],
],
// Checkbox to enable/disable logging.
'enable-logging' => [
'#type' => 'checkbox',
'#title' => $this->t('Enable activity logging'),
'#default_value' => Settings::getActivityLogEnable(),
'#return_value' => 'enabled',
'#required' => FALSE,
'#name' => 'enable-logging',
],
// The default setting.
'enable-logging-default' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Default: Disable activity logging'),
'#attributes' => [
'class' => [
$itemDefaultClass,
$itemNoteClass,
],
],
],
// A note about logging on busy sites.
'enable-logging-note' => [
'#type' => 'container',
'#attributes' => [
'class' => [
$noteClass,
$itemNoteClass,
],
],
'#states' => [
'visible' => [
'input[name="enable-logging"]' => [
'checked' => TRUE,
],
],
],
'note' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
"For busy sites, activity logging can create a large number of log entries."),
],
],
],
];
//
// Manage search
// -------------
// The search configuration is created by the core search module.
//
// The description changes a bit for different configurations:
//
// SEARCH HELP MESSAGE
// no no basic message + search enable.
// no yes basic message + search enable.
// yes no basic message + search pages + plugin.
// yes yes basic message + search pages + plugin + help.
if ($searchInstalled === TRUE) {
$searchName = $mh->getName('search');
}
else {
$searchName = 'Search';
}
$searchEnableLink = LinkUtilities::createRouteLink(
'system.modules_list',
'module-search',
$searchName);
$cronLink = LinkUtilities::createRouteLink(
'system.cron_settings');
$status = ManageSearch::getIndexStatus();
if ((int) $status['total'] !== 0) {
$remaining = (float) $status['remaining'];
$total = (float) $status['total'];
$percent = ((int) (100.0 * ($total - $remaining) / $total));
$nothingToIndex = FALSE;
}
else {
$nothingToIndex = TRUE;
$percent = '';
}
if ($searchInstalled === TRUE) {
if ($nothingToIndex === TRUE) {
$indexStatus = $this->t(
'There are currently no files and folders to index.');
}
elseif ($percent === 100) {
$indexStatus = $this->t(
'The files and folders search index is complete for @total items.',
[
'@total' => $status['total'],
]);
}
else {
$indexStatus = $this->t(
'The files and folders search index is @percent % complete, with @remaining out of @total items to index.',
[
'@percent' => $percent,
'@total' => $status['total'],
'@remaining' => $status['remaining'],
]);
}
$intervalDescription = $this->t(
"The search index can be updated automatically as pages are processed, or by using the site's @cronLink configuration.",
[
'@cronLink' => $cronLink,
]);
$restoreButtonDescription = $this->t(
'Restore the @searchPluginLink to its default values.',
[
'@searchPluginLink' => LinkUtilities::createRouteLink(
'entity.search_page.edit_form',
'',
$this->t('plugin'),
[
'search_page' => Constants::SEARCH_PLUGIN,
]),
]);
}
else {
$indexStatus = '';
$intervalDescription = '';
$restoreButtonDescription = '';
}
if ($searchInstalled === TRUE &&
$helpInstalled === TRUE) {
// Search module installed and help available.
$description = $this->t(
"A @searchPluginLink for the %searchPagesLink module (see @searchHelpLink) supports searching for files and folders.",
[
'@searchPluginLink' => LinkUtilities::createRouteLink(
'entity.search_page.edit_form',
'',
$this->t('plugin'),
[
'search_page' => Constants::SEARCH_PLUGIN,
]),
'%searchPagesLink' => LinkUtilities::createRouteLink(
'entity.search_page.collection',
'',
$searchName),
'@searchHelpLink' => LinkUtilities::createHelpLink(
'search',
$this->t('help')),
]);
}
elseif ($searchInstalled === TRUE &&
$helpInstalled === FALSE) {
// Search module installed, but no help.
$description = $this->t(
"A @searchPluginLink for the %searchPagesLink module supports searching for files and folders. Search index updates can be done automatically as pages are processed, or by using the site's @cronLink configuration.",
[
'@searchPluginLink' => LinkUtilities::createRouteLink(
'entity.search_page.edit_form',
'',
$this->t('plugin'),
[
'search_page' => Constants::SEARCH_PLUGIN,
]),
'%searchPagesLink' => LinkUtilities::createRouteLink(
'entity.search_page.collection',
'',
$searchName),
'@cronLink' => $cronLink,
]);
}
else {
// All other cases.
$description = $this->t(
'A plugin supports searching for files and folders.');
}
$form[$tabName]['manage-search'] = [
'#type' => 'details',
'#title' => $this->t('Search indexing'),
'#open' => FALSE,
'#attributes' => [
'class' => [$sectionWrapperClass],
],
'section' => [
'#type' => 'container',
'#attributes' => [
'class' => [$sectionClass],
],
'section-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $description,
'#attributes' => [
'class' => [$sectionDescriptionClass],
],
],
'search-clear-group' => [
'#type' => 'container',
// A note about the current search index state.
'search-clear-progress' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $indexStatus,
'#weight' => 1,
],
// A button to clear the search index.
$clearSearchButton => [
'#type' => 'submit',
'#value' => $this->t('Re-index'),
'#name' => $clearSearchButton,
'#weight' => 2,
'#attributes' => [
'class' => [
$clearSearchButton,
],
],
],
// A description for the clear button.
'search-clear-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Re-index files and folders.'),
'#weight' => 3,
'#attributes' => [
'class' => [
$clearSearchButton . '_description',
],
],
],
],
'search-interval-group' => [
'#type' => 'container',
// A description for search indexing intervals.
'search-interval-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $intervalDescription,
'#weight' => 1,
],
// Menu to select the indexing interval.
'search-index-interval' => [
'#type' => 'select',
'#options' => [
'system' => $this->t('Use Cron for updates'),
'1min' => $this->t('Update every minute'),
'5min' => $this->t('Update every 5 minutes'),
'10min' => $this->t('Update every 10 minutes'),
'15min' => $this->t('Update every 15 minutes'),
'30min' => $this->t('Update every 30 minutes'),
'hourly' => $this->t('Update every hour'),
'daily' => $this->t('Update every day'),
],
'#default_value' => Settings::getSearchIndexInterval(),
'#disabled' => ($searchInstalled === FALSE),
'#name' => 'search-index-interval',
'#weight' => 2,
],
// The default setting.
'search-index-interval-default' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Default: Use Cron for updates'),
'#weight' => 3,
'#attributes' => [
'class' => [
$itemDefaultClass,
$itemNoteClass,
],
],
],
// A note about indexing using CRON.
'search-index-interval-note' => [
'#type' => 'container',
'#weight' => 4,
'#attributes' => [
'class' => [
$itemNoteClass,
],
],
'#states' => [
'visible' => [
'select[name="search-index-interval"]' => [
'value' => 'system',
],
],
],
'note' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'To keep search indexes uptodate, configure @cronLink to run frequently.',
[
'@cronLink' => $cronLink,
]),
],
],
],
'search-restore-group' => [
'#type' => 'container',
// A button to restore the search plugin configuration.
$restoreSearchButton => [
'#type' => 'submit',
'#value' => $this->t('Restore'),
'#name' => $restoreSearchButton,
'#weight' => 1,
'#attributes' => [
'class' => [
$restoreSearchButton,
],
],
],
// A description for the restore button.
'search-restore-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $restoreButtonDescription,
'#weight' => 2,
'#attributes' => [
'class' => [
$restoreSearchButton . '_description',
],
],
],
],
// A warning note if the search module is not installed.
'search-disabled-warning' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
'Search features are disabled because the %searchEnableLink module is not installed.',
[
'%searchEnableLink' => $searchEnableLink,
]),
'#attributes' => [
'class' => [
$warningClass,
$itemNoteClass,
],
],
],
],
];
if ($searchInstalled === TRUE) {
// Search is installed. Remove the warning about it not being installed.
unset($form[$tabName]['manage-search']['section']['search-disabled-warning']);
}
else {
// Search is not installed. Remove the UI.
unset($form[$tabName]['manage-search']['section']['search-restore-group']);
unset($form[$tabName]['manage-search']['section']['search-clear-group']);
unset($form[$tabName]['manage-search']['section']['search-interval-group']);
}
//
// Manage usage reporting.
// -----------------------
// Add a menu for the usage table update interval.
$usageReportLink = LinkUtilities::createRouteLink(
Constants::ROUTE_USAGE,
'',
$this->t('Usage report'));
$form[$tabName]['manage-usage-statistics'] = [
'#type' => 'details',
'#title' => $this->t('Usage reporting'),
'#attributes' => [
'class' => [$sectionWrapperClass],
],
'section' => [
'#type' => 'container',
'#attributes' => [
'class' => [$sectionClass],
],
'section-description' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t(
"The @usageReportLink shows the number of files and folders owned by each user. Data can be updated automatically as pages are processed, or only when needed.",
[
'@usageReportLink' => $usageReportLink,
]),
'#attributes' => [
'class' => [$sectionDescriptionClass],
],
],
// Menu to select the update interval.
'usage-update-interval' => [
'#type' => 'select',
'#options' => [
'manualy' => $this->t('Update manually'),
'hourly' => $this->t('Update every hour'),
'daily' => $this->t('Update every day'),
'weekly' => $this->t('Update every week'),
],
'#default_value' => Settings::getUsageUpdateInterval(),
'#name' => 'usage-update-interval',
],
// The default setting.
'usage-update-interval-default' => [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Default: Update manually'),
'#attributes' => [
'class' => [
$itemDefaultClass,
$itemNoteClass,
],
],
],
// Manual update note.
'usage-update-interval-note' => [
'#type' => 'container',
'#markup' => $this->t(
'Manual updates may be started on the @usageReportLink.',
[
'@usageReportLink' => $usageReportLink,
]),
'#attributes' => [
'class' => [
$itemNoteClass,
],
],
'#states' => [
'visible' => [
'select[name="usage-update-interval"]' => [
'value' => 'manualy',
],
],
],
],
],
];
}
/*---------------------------------------------------------------------
*
* Validate.
*
*---------------------------------------------------------------------*/
/**
* Validates form values.
*
* @param array $form
* The form configuration.
* @param \Drupal\Core\Form\FormStateInterface $formState
* The entered values for the form.
*/
private function validateServicesTab(
array &$form,
FormStateInterface $formState) {
$moduleName = self::makeCssSafe(Constants::MODULE);
$trigger = $formState->getTriggeringElement();
//
// Restore search configuration.
// -----------------------------
// Reset the search index update interval, restore the search plugin's
// settings, and report the change.
$restoreSearchButton = $moduleName . '_search_restore';
if ($trigger['#name'] === $restoreSearchButton) {
// Reset the search index update interval.
$default = Settings::getSearchIndexIntervalDefault();
Settings::setSearchIndexInterval($default);
$formInput = $formState->getUserInput();
$formInput['search-index-interval'] = $default;
$formState->setUserInput($formInput);
// Reset the search plugin configuration.
$status = ConfigurationUtilities::revertConfiguration(
'core',
'search.page.foldershare_search');
$formState->setRebuild(TRUE);
$formState->cleanValues();
$formState->setTriggeringElement(NULL);
if ($status === TRUE) {
// Clear the search index.
ManageSearch::clearIndex();
\Drupal::messenger()->addMessage(
$this->t('Search features have been restored to their defaults and the search index cleared.'),
'status');
}
else {
\Drupal::messenger()->addMessage(
$this->t('Search features could not be restored to their defaults due to an unexpected problem.'),
'error');
}
return;
}
//
// Clear search index.
// -------------------
// Clear the files and folders search index.
$clearSearchButton = $moduleName . '_search_clear';
if ($trigger['#name'] === $clearSearchButton) {
ManageSearch::clearIndex();
$formState->setRebuild(TRUE);
$formState->cleanValues();
$formState->setTriggeringElement(NULL);
\Drupal::messenger()->addMessage(
$this->t('Files and folders search index reset for re-indexing.'),
'status');
return;
}
}
/*---------------------------------------------------------------------
*
* 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 submitServicesTab(
array &$form,
FormStateInterface $formState) {
// Set activity logging.
$value = $formState->getValue('enable-logging');
$enabled = ($value === 'enabled') ? TRUE : FALSE;
Settings::setActivityLogEnable($enabled);
// Set search indexing interval.
$value = $formState->getValue('search-index-interval');
Settings::setSearchIndexInterval($value);
ManageSearch::scheduleSearchIndexing();
// Set usage statistics update interval.
$value = $formState->getValue('usage-update-interval');
Settings::setUsageUpdateInterval($value);
ManageUsageStatistics::scheduleUsageUpdate();
}
}
