ThemeController.php 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. <?php
  2. namespace Drupal\system\Controller;
  3. use Drupal\Core\Config\ConfigFactoryInterface;
  4. use Drupal\Core\Config\PreExistingConfigException;
  5. use Drupal\Core\Config\UnmetDependenciesException;
  6. use Drupal\Core\Controller\ControllerBase;
  7. use Drupal\Core\Extension\ThemeHandlerInterface;
  8. use Symfony\Component\DependencyInjection\ContainerInterface;
  9. use Symfony\Component\HttpFoundation\Request;
  10. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  11. /**
  12. * Controller for theme handling.
  13. */
  14. class ThemeController extends ControllerBase {
  15. /**
  16. * The theme handler service.
  17. *
  18. * @var \Drupal\Core\Extension\ThemeHandlerInterface
  19. */
  20. protected $themeHandler;
  21. /**
  22. * Constructs a new ThemeController.
  23. *
  24. * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
  25. * The theme handler.
  26. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
  27. * The config factory.
  28. */
  29. public function __construct(ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory) {
  30. $this->themeHandler = $theme_handler;
  31. $this->configFactory = $config_factory;
  32. }
  33. /**
  34. * {@inheritdoc}
  35. */
  36. public static function create(ContainerInterface $container) {
  37. return new static(
  38. $container->get('theme_handler'),
  39. $container->get('config.factory')
  40. );
  41. }
  42. /**
  43. * Uninstalls a theme.
  44. *
  45. * @param \Symfony\Component\HttpFoundation\Request $request
  46. * A request object containing a theme name and a valid token.
  47. *
  48. * @return \Symfony\Component\HttpFoundation\RedirectResponse
  49. * Redirects back to the appearance admin page.
  50. *
  51. * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  52. * Throws access denied when no theme or token is set in the request or when
  53. * the token is invalid.
  54. */
  55. public function uninstall(Request $request) {
  56. $theme = $request->query->get('theme');
  57. $config = $this->config('system.theme');
  58. if (isset($theme)) {
  59. // Get current list of themes.
  60. $themes = $this->themeHandler->listInfo();
  61. // Check if the specified theme is one recognized by the system.
  62. if (!empty($themes[$theme])) {
  63. // Do not uninstall the default or admin theme.
  64. if ($theme === $config->get('default') || $theme === $config->get('admin')) {
  65. $this->messenger()->addError($this->t('%theme is the default theme and cannot be uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
  66. }
  67. else {
  68. $this->themeHandler->uninstall([$theme]);
  69. $this->messenger()->addStatus($this->t('The %theme theme has been uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
  70. }
  71. }
  72. else {
  73. $this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
  74. }
  75. return $this->redirect('system.themes_page');
  76. }
  77. throw new AccessDeniedHttpException();
  78. }
  79. /**
  80. * Installs a theme.
  81. *
  82. * @param \Symfony\Component\HttpFoundation\Request $request
  83. * A request object containing a theme name and a valid token.
  84. *
  85. * @return \Symfony\Component\HttpFoundation\RedirectResponse
  86. * Redirects back to the appearance admin page.
  87. *
  88. * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  89. * Throws access denied when no theme or token is set in the request or when
  90. * the token is invalid.
  91. */
  92. public function install(Request $request) {
  93. $theme = $request->query->get('theme');
  94. if (isset($theme)) {
  95. try {
  96. if ($this->themeHandler->install([$theme])) {
  97. $themes = $this->themeHandler->listInfo();
  98. $this->messenger()->addStatus($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']]));
  99. }
  100. else {
  101. $this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
  102. }
  103. }
  104. catch (PreExistingConfigException $e) {
  105. $config_objects = $e->flattenConfigObjects($e->getConfigObjects());
  106. $this->messenger()->addError(
  107. $this->formatPlural(
  108. count($config_objects),
  109. 'Unable to install @extension, %config_names already exists in active configuration.',
  110. 'Unable to install @extension, %config_names already exist in active configuration.',
  111. [
  112. '%config_names' => implode(', ', $config_objects),
  113. '@extension' => $theme,
  114. ])
  115. );
  116. }
  117. catch (UnmetDependenciesException $e) {
  118. $this->messenger()->addError($e->getTranslatedMessage($this->getStringTranslation(), $theme));
  119. }
  120. return $this->redirect('system.themes_page');
  121. }
  122. throw new AccessDeniedHttpException();
  123. }
  124. /**
  125. * Set the default theme.
  126. *
  127. * @param \Symfony\Component\HttpFoundation\Request $request
  128. * A request object containing a theme name.
  129. *
  130. * @return \Symfony\Component\HttpFoundation\RedirectResponse
  131. * Redirects back to the appearance admin page.
  132. *
  133. * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
  134. * Throws access denied when no theme is set in the request.
  135. */
  136. public function setDefaultTheme(Request $request) {
  137. $config = $this->configFactory->getEditable('system.theme');
  138. $theme = $request->query->get('theme');
  139. if (isset($theme)) {
  140. // Get current list of themes.
  141. $themes = $this->themeHandler->listInfo();
  142. // Check if the specified theme is one recognized by the system.
  143. // Or try to install the theme.
  144. if (isset($themes[$theme]) || $this->themeHandler->install([$theme])) {
  145. $themes = $this->themeHandler->listInfo();
  146. // Set the default theme.
  147. $config->set('default', $theme)->save();
  148. // The status message depends on whether an admin theme is currently in
  149. // use: a value of 0 means the admin theme is set to be the default
  150. // theme.
  151. $admin_theme = $config->get('admin');
  152. if ($admin_theme != 0 && $admin_theme != $theme) {
  153. $this->messenger()
  154. ->addStatus($this->t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', [
  155. '%admin_theme' => $themes[$admin_theme]->info['name'],
  156. '%selected_theme' => $themes[$theme]->info['name'],
  157. ]));
  158. }
  159. else {
  160. $this->messenger()->addStatus($this->t('%theme is now the default theme.', ['%theme' => $themes[$theme]->info['name']]));
  161. }
  162. }
  163. else {
  164. $this->messenger()->addError($this->t('The %theme theme was not found.', ['%theme' => $theme]));
  165. }
  166. return $this->redirect('system.themes_page');
  167. }
  168. throw new AccessDeniedHttpException();
  169. }
  170. }