--- /dev/null
+<?php
+
+namespace Drupal\system\Controller;
+
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Config\PreExistingConfigException;
+use Drupal\Core\Config\UnmetDependenciesException;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Extension\ThemeHandlerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+
+/**
+ * Controller for theme handling.
+ */
+class ThemeController extends ControllerBase {
+
+ /**
+ * The theme handler service.
+ *
+ * @var \Drupal\Core\Extension\ThemeHandlerInterface
+ */
+ protected $themeHandler;
+
+ /**
+ * Constructs a new ThemeController.
+ *
+ * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
+ * The theme handler.
+ * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+ * The config factory.
+ */
+ public function __construct(ThemeHandlerInterface $theme_handler, ConfigFactoryInterface $config_factory) {
+ $this->themeHandler = $theme_handler;
+ $this->configFactory = $config_factory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('theme_handler'),
+ $container->get('config.factory')
+ );
+ }
+
+ /**
+ * Uninstalls a theme.
+ *
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * A request object containing a theme name and a valid token.
+ *
+ * @return \Symfony\Component\HttpFoundation\RedirectResponse
+ * Redirects back to the appearance admin page.
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+ * Throws access denied when no theme or token is set in the request or when
+ * the token is invalid.
+ */
+ public function uninstall(Request $request) {
+ $theme = $request->query->get('theme');
+ $config = $this->config('system.theme');
+
+ if (isset($theme)) {
+ // Get current list of themes.
+ $themes = $this->themeHandler->listInfo();
+
+ // Check if the specified theme is one recognized by the system.
+ if (!empty($themes[$theme])) {
+ // Do not uninstall the default or admin theme.
+ if ($theme === $config->get('default') || $theme === $config->get('admin')) {
+ drupal_set_message($this->t('%theme is the default theme and cannot be uninstalled.', ['%theme' => $themes[$theme]->info['name']]), 'error');
+ }
+ else {
+ $this->themeHandler->uninstall([$theme]);
+ drupal_set_message($this->t('The %theme theme has been uninstalled.', ['%theme' => $themes[$theme]->info['name']]));
+ }
+ }
+ else {
+ drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error');
+ }
+
+ return $this->redirect('system.themes_page');
+ }
+
+ throw new AccessDeniedHttpException();
+ }
+
+ /**
+ * Installs a theme.
+ *
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * A request object containing a theme name and a valid token.
+ *
+ * @return \Symfony\Component\HttpFoundation\RedirectResponse
+ * Redirects back to the appearance admin page.
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+ * Throws access denied when no theme or token is set in the request or when
+ * the token is invalid.
+ */
+ public function install(Request $request) {
+ $theme = $request->query->get('theme');
+
+ if (isset($theme)) {
+ try {
+ if ($this->themeHandler->install([$theme])) {
+ $themes = $this->themeHandler->listInfo();
+ drupal_set_message($this->t('The %theme theme has been installed.', ['%theme' => $themes[$theme]->info['name']]));
+ }
+ else {
+ drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error');
+ }
+ }
+ catch (PreExistingConfigException $e) {
+ $config_objects = $e->flattenConfigObjects($e->getConfigObjects());
+ drupal_set_message(
+ $this->formatPlural(
+ count($config_objects),
+ 'Unable to install @extension, %config_names already exists in active configuration.',
+ 'Unable to install @extension, %config_names already exist in active configuration.',
+ [
+ '%config_names' => implode(', ', $config_objects),
+ '@extension' => $theme,
+ ]),
+ 'error'
+ );
+ }
+ catch (UnmetDependenciesException $e) {
+ drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $theme), 'error');
+ }
+
+ return $this->redirect('system.themes_page');
+ }
+
+ throw new AccessDeniedHttpException();
+ }
+
+ /**
+ * Set the default theme.
+ *
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * A request object containing a theme name.
+ *
+ * @return \Symfony\Component\HttpFoundation\RedirectResponse
+ * Redirects back to the appearance admin page.
+ *
+ * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
+ * Throws access denied when no theme is set in the request.
+ */
+ public function setDefaultTheme(Request $request) {
+ $config = $this->configFactory->getEditable('system.theme');
+ $theme = $request->query->get('theme');
+
+ if (isset($theme)) {
+ // Get current list of themes.
+ $themes = $this->themeHandler->listInfo();
+
+ // Check if the specified theme is one recognized by the system.
+ // Or try to install the theme.
+ if (isset($themes[$theme]) || $this->themeHandler->install([$theme])) {
+ $themes = $this->themeHandler->listInfo();
+
+ // Set the default theme.
+ $config->set('default', $theme)->save();
+
+ // The status message depends on whether an admin theme is currently in
+ // use: a value of 0 means the admin theme is set to be the default
+ // theme.
+ $admin_theme = $config->get('admin');
+ if ($admin_theme != 0 && $admin_theme != $theme) {
+ drupal_set_message($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.', [
+ '%admin_theme' => $themes[$admin_theme]->info['name'],
+ '%selected_theme' => $themes[$theme]->info['name'],
+ ]));
+ }
+ else {
+ drupal_set_message($this->t('%theme is now the default theme.', ['%theme' => $themes[$theme]->info['name']]));
+ }
+ }
+ else {
+ drupal_set_message($this->t('The %theme theme was not found.', ['%theme' => $theme]), 'error');
+ }
+
+ return $this->redirect('system.themes_page');
+
+ }
+ throw new AccessDeniedHttpException();
+ }
+
+}