class ConfigUpdateController in Configuration Update Manager 8
Returns responses for Configuration Revert module operations.
Hierarchy
- class \Drupal\Core\Controller\ControllerBase implements ContainerInjectionInterface uses LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\config_update_ui\Controller\ConfigUpdateController
Expanded class hierarchy of ConfigUpdateController
File
- config_update_ui/
src/ Controller/ ConfigUpdateController.php, line 20
Namespace
Drupal\config_update_ui\ControllerView source
class ConfigUpdateController extends ControllerBase {
/**
* The config differ.
*
* @var \Drupal\config_update\ConfigDiffInterface
*/
protected $configDiff;
/**
* The config lister.
*
* @var \Drupal\config_update\ConfigListByProviderInterface
*/
protected $configList;
/**
* The config reverter.
*
* @var \Drupal\config_update\ConfigRevertInterface
*/
protected $configRevert;
/**
* The diff formatter.
*
* @var \Drupal\Core\Diff\DiffFormatter
*/
protected $diffFormatter;
/**
* The module handler.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The theme handler.
*
* @var \Drupal\Core\Extension\ThemeHandlerInterface
*/
protected $themeHandler;
/**
* The config factory.
*
* @var \Drupal\Core\config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* Constructs a ConfigUpdateController object.
*
* @param \Drupal\config_update\ConfigDiffInterface $config_diff
* The config differ.
* @param \Drupal\config_update\ConfigListByProviderInterface $config_list
* The config lister.
* @param \Drupal\config_update\ConfigRevertInterface $config_update
* The config reverter.
* @param \Drupal\Core\Diff\DiffFormatter $diff_formatter
* The diff formatter to use.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
* The theme handler.
* @param \drupal\Core\Config\ConfigFactoryInterface $config_factory
* The config factory.
*/
public function __construct(ConfigDiffInterface $config_diff, ConfigListByProviderInterface $config_list, ConfigRevertInterface $config_update, DiffFormatter $diff_formatter, ModuleHandlerInterface $module_handler, ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory) {
$this->configDiff = $config_diff;
$this->configList = $config_list;
$this->configRevert = $config_update;
$this->diffFormatter = $diff_formatter;
$this->diffFormatter->show_header = FALSE;
$this->moduleHandler = $module_handler;
$this->themeHandler = $theme_handler;
$this->configFactory = $config_factory;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('config_update.config_diff'), $container
->get('config_update.config_list'), $container
->get('config_update.config_update'), $container
->get('diff.formatter'), $container
->get('module_handler'), $container
->get('theme_handler'), $container
->get('config.factory'));
}
/**
* Shows the diff between active and provided configuration.
*
* @param string $config_type
* The type of configuration.
* @param string $config_name
* The name of the config item, without the prefix.
*
* @return array
* Render array for page showing differences between them.
*/
public function diff($config_type, $config_name) {
$diff = $this->configDiff
->diff($this->configRevert
->getFromExtension($config_type, $config_name), $this->configRevert
->getFromActive($config_type, $config_name));
$build = [];
$definition = $this->configList
->getType($config_type);
$config_type_label = $definition ? $definition
->getLabel() : $this
->t('Simple configuration');
$build['#title'] = $this
->t('Config difference for @type @name', [
'@type' => $config_type_label,
'@name' => $config_name,
]);
$build['#attached']['library'][] = 'system/diff';
$build['diff'] = [
'#type' => 'table',
'#header' => [
[
'data' => $this
->t('Source config'),
'colspan' => '2',
],
[
'data' => $this
->t('Site config'),
'colspan' => '2',
],
],
'#rows' => $this->diffFormatter
->format($diff),
'#attributes' => [
'class' => [
'diff',
],
],
];
$url = new Url('config_update_ui.report');
$build['back'] = [
'#type' => 'link',
'#attributes' => [
'class' => [
'dialog-cancel',
],
],
'#title' => $this
->t("Back to 'Updates report' page."),
'#url' => $url,
];
return $build;
}
/**
* Generates the config updates report.
*
* @param string $report_type
* (optional) Type of report to run:
* - type: Configuration entity type.
* - module: Module.
* - theme: Theme.
* - profile: Install profile.
* @param string $name
* (optional) Name of specific item to run report for (config entity type
* ID, module machine name, etc.). Ignored for profile.
*
* @return array
* Render array for report, with section at the top for selecting another
* report to run. If either $report_type or $name is missing, the report
* itself is not generated.
*/
public function report($report_type = NULL, $name = NULL) {
$links = $this
->generateReportLinks();
$report = $this
->generateReport($report_type, $name);
if (!$report) {
return $links;
}
// If there is a report, extract the title, put table of links in a
// details element, and add report to build.
$build = [];
$build['#title'] = $report['#title'];
unset($report['#title']);
$build['links_wrapper'] = [
'#type' => 'details',
'#title' => $this
->t('Generate new report'),
'#children' => $links,
];
$build['report'] = $report;
$build['#attached']['library'][] = 'config_update/report_css';
return $build;
}
/**
* Generates the operations links for running individual reports.
*
* @return array
* Render array for the operations links for running reports.
*/
protected function generateReportLinks() {
// These links are put into an 'operations' render array element. They do
// not look good outside of tables. Also note that the array index in
// operations links is used as a class on the LI element. Some classes are
// special in the Seven CSS, such as "contextual", so avoid hitting these
// accidentally by prefixing.
$build = [];
$build['links'] = [
'#type' => 'table',
'#header' => [
$this
->t('Report type'),
$this
->t('Report on'),
],
'#rows' => [],
];
// Full report of all configuration.
$links['report_full'] = [
'title' => $this
->t('Everything'),
'url' => Url::fromRoute('config_update_ui.report', [
'report_type' => 'type',
'name' => 'system.all',
]),
];
$build['links']['#rows'][] = [
$this
->t('Full report'),
[
'data' => [
'#type' => 'operations',
'#links' => $links,
],
],
];
// Reports by configuration type.
$definitions = $this->configList
->listTypes();
$links = [];
foreach ($definitions as $entity_type => $definition) {
$links['report_type_' . $entity_type] = [
'title' => $definition
->getLabel(),
'url' => Url::fromRoute('config_update_ui.report', [
'report_type' => 'type',
'name' => $entity_type,
]),
];
}
uasort($links, [
$this,
'sortLinks',
]);
$links = [
'report_type_system.simple' => [
'title' => $this
->t('Simple configuration'),
'url' => Url::fromRoute('config_update_ui.report', [
'report_type' => 'type',
'name' => 'system.simple',
]),
],
] + $links;
$build['links']['#rows'][] = [
$this
->t('Single configuration type'),
[
'data' => [
'#type' => 'operations',
'#links' => $links,
],
],
];
// Make a list of installed modules.
$profile = $this
->getProfileName();
$modules = $this->moduleHandler
->getModuleList();
$links = [];
foreach ($modules as $machine_name => $module) {
if ($machine_name != $profile && $this->configList
->providerHasConfig('module', $machine_name)) {
$links['report_module_' . $machine_name] = [
'title' => $this->moduleHandler
->getName($machine_name),
'url' => Url::fromRoute('config_update_ui.report', [
'report_type' => 'module',
'name' => $machine_name,
]),
];
}
}
uasort($links, [
$this,
'sortLinks',
]);
$build['links']['#rows'][] = [
$this
->t('Single module'),
[
'data' => [
'#type' => 'operations',
'#links' => $links,
],
],
];
// Make a list of installed themes.
$themes = $this->themeHandler
->listInfo();
$links = [];
foreach ($themes as $machine_name => $theme) {
if ($this->configList
->providerHasConfig('theme', $machine_name)) {
$links['report_theme_' . $machine_name] = [
'title' => $this->themeHandler
->getName($machine_name),
'url' => Url::fromRoute('config_update_ui.report', [
'report_type' => 'theme',
'name' => $machine_name,
]),
];
}
}
uasort($links, [
$this,
'sortLinks',
]);
$build['links']['#rows'][] = [
$this
->t('Single theme'),
[
'data' => [
'#type' => 'operations',
'#links' => $links,
],
],
];
$links = [];
// Profile is just one option.
if ($this->configList
->providerHasConfig('profile', $profile)) {
$links['report_profile_' . $profile] = [
'title' => $this->moduleHandler
->getName($profile),
'url' => Url::fromRoute('config_update_ui.report', [
'report_type' => 'profile',
]),
];
$build['links']['#rows'][] = [
$this
->t('Installation profile'),
[
'data' => [
'#type' => 'operations',
'#links' => $links,
],
],
];
}
return $build;
}
/**
* Generates a report about config updates.
*
* @param string $report_type
* Type of report to generate: 'type', 'module', 'theme', or 'profile'.
* @param string $value
* Machine name of a configuration type, module, or theme to generate the
* report for. Ignored for profile, since that uses the active profile.
*
* @return array
* Render array for the updates report. Empty if invalid or missing
* report type or value.
*/
protected function generateReport($report_type, $value) {
// Figure out what to name the report, and incidentally, validate that
// $value exists for this type of report.
switch ($report_type) {
case 'type':
if ($value == 'system.all') {
$label = $this
->t('All configuration');
}
elseif ($value == 'system.simple') {
$label = $this
->t('Simple configuration');
}
else {
$definition = $this->configList
->getType($value);
if (!$definition) {
return NULL;
}
$label = $this
->t('@name configuration', [
'@name' => $definition
->getLabel(),
]);
}
break;
case 'module':
$list = $this->moduleHandler
->getModuleList();
if (!isset($list[$value])) {
return NULL;
}
$label = $this
->t('@name module', [
'@name' => $this->moduleHandler
->getName($value),
]);
break;
case 'theme':
$list = $this->themeHandler
->listInfo();
if (!isset($list[$value])) {
return NULL;
}
$label = $this
->t('@name theme', [
'@name' => $this->themeHandler
->getName($value),
]);
break;
case 'profile':
$profile = $this
->getProfileName();
$label = $this
->t('@name profile', [
'@name' => $this->moduleHandler
->getName($profile),
]);
break;
default:
return NULL;
}
// List the active and extension-provided config.
list($active_list, $install_list, $optional_list) = $this->configList
->listConfig($report_type, $value);
// Build the report.
$build = [];
$build['#title'] = $this
->t('Configuration updates report for @label', [
'@label' => $label,
]);
$build['report_header'] = [
'#markup' => '<h3>' . $this
->t('Updates report') . '</h3>',
];
// List items missing from site.
$removed = array_diff($install_list, $active_list);
$build['removed'] = [
'#caption' => $this
->t('Missing configuration items'),
'#empty' => $this
->t('None: all provided configuration items are in your active configuration.'),
] + $this
->makeReportTable($removed, 'extension', [
'import',
]);
// List optional items that are not installed.
$inactive = array_diff($optional_list, $active_list);
$build['inactive'] = [
'#caption' => $this
->t('Inactive optional items'),
'#empty' => $this
->t('None: all optional configuration items are in your active configuration.'),
] + $this
->makeReportTable($inactive, 'extension', [
'import',
]);
// List items added to site, which only makes sense in the report for a
// config type.
$added = array_diff($active_list, $install_list, $optional_list);
if ($report_type == 'type') {
$build['added'] = [
'#caption' => $this
->t('Added configuration items'),
'#empty' => $this
->t('None: all active configuration items of this type were provided by modules, themes, or install profile.'),
] + $this
->makeReportTable($added, 'active', [
'export',
'delete',
]);
}
// For differences, we need to go through the array of config in both
// and see if each config item is the same or not.
$both = array_diff($active_list, $added);
$different = [];
foreach ($both as $name) {
if (!$this->configDiff
->same($this->configRevert
->getFromExtension('', $name), $this->configRevert
->getFromActive('', $name))) {
$different[] = $name;
}
}
$build['different'] = [
'#caption' => $this
->t('Changed configuration items'),
'#empty' => $this
->t('None: no active configuration items differ from their current provided versions.'),
] + $this
->makeReportTable($different, 'active', [
'diff',
'export',
'revert',
]);
return $build;
}
/**
* Builds a table for the report.
*
* @param string[] $names
* List of machine names of config items for the table.
* @param string $storage
* Config storage the items can be loaded from, either 'active' or
* 'extension'.
* @param string[] $actions
* Action links to include, one or more of:
* - diff
* - revert
* - export
* - import
* - delete.
*
* @return array
* Render array for the table, not including the #empty and #prefix
* properties.
*/
protected function makeReportTable(array $names, $storage, array $actions) {
$build = [];
$build['#type'] = 'table';
$build['#attributes'] = [
'class' => [
'config-update-report',
],
];
$build['#header'] = [
'name' => [
'data' => $this
->t('Machine name'),
],
'label' => [
'data' => $this
->t('Label (if any)'),
'class' => [
RESPONSIVE_PRIORITY_LOW,
],
],
'type' => [
'data' => $this
->t('Type'),
'class' => [
RESPONSIVE_PRIORITY_MEDIUM,
],
],
'provider' => [
'data' => $this
->t('Provider'),
'class' => [
RESPONSIVE_PRIORITY_LOW,
],
],
'operations' => [
'data' => $this
->t('Operations'),
],
];
$build['#rows'] = [];
foreach ($names as $name) {
$row = [];
if ($storage == 'active') {
$config = $this->configRevert
->getFromActive('', $name);
}
else {
$config = $this->configRevert
->getFromExtension('', $name);
}
// Figure out what type of config it is, and get the ID.
$entity_type = $this->configList
->getTypeNameByConfigName($name);
if (!$entity_type) {
// This is simple config.
$id = $name;
$label = '';
$type_label = $this
->t('Simple configuration');
$entity_type = 'system.simple';
}
else {
$definition = $this->configList
->getType($entity_type);
$id_key = $definition
->getKey('id');
$id = $config[$id_key];
// The label key is not required.
if ($label_key = $definition
->getKey('label')) {
$label = $config[$label_key];
}
else {
$label = '';
}
$type_label = $definition
->getLabel();
}
$row[] = $name;
$row[] = $label;
$row[] = $type_label;
$provider = $this->configList
->getConfigProvider($name);
$provider_name = '';
if (!empty($provider)) {
switch ($provider[0]) {
case 'profile':
$provider_name = $this->moduleHandler
->getName($provider[1]);
if ($provider_name) {
$provider_name = $this
->t('@name profile', [
'@name' => $provider_name,
]);
}
else {
$provider_name = '';
}
break;
case 'module':
$provider_name = $this->moduleHandler
->getName($provider[1]);
if ($provider_name) {
$provider_name = $this
->t('@name module', [
'@name' => $provider_name,
]);
}
else {
$provider_name = '';
}
break;
case 'theme':
$provider_name = $this->themeHandler
->getName($provider[1]);
if ($provider_name) {
$provider_name = $this
->t('@name theme', [
'@name' => $provider_name,
]);
}
else {
$provider_name = '';
}
break;
}
}
$row[] = $provider_name;
$links = [];
$routes = [
'export' => 'config.export_single',
'import' => 'config_update_ui.import',
'diff' => 'config_update_ui.diff',
'revert' => 'config_update_ui.revert',
'delete' => 'config_update_ui.delete',
];
$titles = [
'export' => $this
->t('Export'),
'import' => $this
->t('Import from source'),
'diff' => $this
->t('Show differences'),
'revert' => $this
->t('Revert to source'),
'delete' => $this
->t('Delete'),
];
foreach ($actions as $action) {
$links[$action] = [
'url' => Url::fromRoute($routes[$action], [
'config_type' => $entity_type,
'config_name' => $id,
]),
'title' => $titles[$action],
];
}
$row[] = [
'data' => [
'#type' => 'operations',
'#links' => $links,
],
];
$build['#rows'][] = $row;
}
return $build;
}
/**
* Compares links for uasort(), to sort by displayed link title.
*/
protected static function sortLinks($link1, $link2) {
$title1 = $link1['title'];
$title2 = $link2['title'];
if ($title1 == $title2) {
return 0;
}
return $title1 < $title2 ? -1 : 1;
}
/**
* Returns the name of the install profile.
*
* For backwards compatibility with pre/post 8.3.x, tries to get it from
* either configuration or settings.
*
* @return string
* The name of the install profile.
*/
protected function getProfileName() {
// Code adapted from DrupalKernel::getInstalProfile() in Core.
// In Core 8.3.x or later, read from config.
$profile = $this->configFactory
->get('core.extension')
->get('profile');
if (!empty($profile)) {
return $profile;
}
else {
// If system_update_8300() has not yet run, use settings.
return Settings::get('install_profile');
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
ConfigUpdateController:: |
protected | property | The config differ. | |
ConfigUpdateController:: |
protected | property |
The config factory. Overrides ControllerBase:: |
|
ConfigUpdateController:: |
protected | property | The config lister. | |
ConfigUpdateController:: |
protected | property | The config reverter. | |
ConfigUpdateController:: |
protected | property | The diff formatter. | |
ConfigUpdateController:: |
protected | property |
The module handler. Overrides ControllerBase:: |
|
ConfigUpdateController:: |
protected | property | The theme handler. | |
ConfigUpdateController:: |
public static | function |
Instantiates a new instance of this class. Overrides ControllerBase:: |
|
ConfigUpdateController:: |
public | function | Shows the diff between active and provided configuration. | |
ConfigUpdateController:: |
protected | function | Generates a report about config updates. | |
ConfigUpdateController:: |
protected | function | Generates the operations links for running individual reports. | |
ConfigUpdateController:: |
protected | function | Returns the name of the install profile. | |
ConfigUpdateController:: |
protected | function | Builds a table for the report. | |
ConfigUpdateController:: |
public | function | Generates the config updates report. | |
ConfigUpdateController:: |
protected static | function | Compares links for uasort(), to sort by displayed link title. | |
ConfigUpdateController:: |
public | function | Constructs a ConfigUpdateController object. | |
ControllerBase:: |
protected | property | The current user service. | 1 |
ControllerBase:: |
protected | property | The entity form builder. | |
ControllerBase:: |
protected | property | The entity manager. | |
ControllerBase:: |
protected | property | The entity type manager. | |
ControllerBase:: |
protected | property | The form builder. | 2 |
ControllerBase:: |
protected | property | The key-value storage. | 1 |
ControllerBase:: |
protected | property | The language manager. | 1 |
ControllerBase:: |
protected | property | The state service. | |
ControllerBase:: |
protected | function | Returns the requested cache bin. | |
ControllerBase:: |
protected | function | Retrieves a configuration object. | |
ControllerBase:: |
private | function | Returns the service container. | |
ControllerBase:: |
protected | function | Returns the current user. | 1 |
ControllerBase:: |
protected | function | Retrieves the entity form builder. | |
ControllerBase:: |
protected | function | Retrieves the entity manager service. | |
ControllerBase:: |
protected | function | Retrieves the entity type manager. | |
ControllerBase:: |
protected | function | Returns the form builder service. | 2 |
ControllerBase:: |
protected | function | Returns a key/value storage collection. | 1 |
ControllerBase:: |
protected | function | Returns the language manager service. | 1 |
ControllerBase:: |
protected | function | Returns the module handler. | 2 |
ControllerBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
ControllerBase:: |
protected | function | Returns the state storage service. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |