protected function themeDetail(DrupalStyle $io, $themeId) { $theme = null; $themes = $this->themeHandler->rebuildThemeData(); if (isset($themes[$themeId])) { $theme = $themes[$themeId]; } else { foreach ($themes as $themeAvailableId => $themeAvailable) { if ($themeAvailable->info['name'] == $themeId) { $themeId = $themeAvailableId; $theme = $themeAvailable; break; } } } if ($theme) { $theme = $themes[$themeId]; $status = $this->getThemeStatus($themeId); $io->info($theme->info['name']); $io->comment(sprintf('%s : ', $this->trans('commands.theme.debug.messages.status')), false); $io->writeln($status); $io->comment(sprintf('%s : ', $this->trans('commands.theme.debug.messages.version')), false); $io->writeln($theme->info['version']); $io->comment($this->trans('commands.theme.debug.messages.regions')); $tableRows = $this->addThemeAttributes($theme->info['regions'], $tableRows); $io->table([], $tableRows); } else { $io->error(sprintf($this->trans('commands.theme.debug.messages.invalid-theme'), $themeId)); } }
/** * Tests rebuild the theme data with theme parents. */ public function testRebuildThemeDataWithThemeParents() { $this->extensionDiscovery->expects($this->at(0))->method('scan')->with('theme')->will($this->returnValue(array('test_subtheme' => new Extension($this->root, 'theme', $this->root . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml', 'test_subtheme.info.yml'), 'test_basetheme' => new Extension($this->root, 'theme', $this->root . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml', 'test_basetheme.info.yml')))); $this->extensionDiscovery->expects($this->at(1))->method('scan')->with('theme_engine')->will($this->returnValue(array('twig' => new Extension($this->root, 'theme_engine', $this->root . '/core/themes/engines/twig/twig.info.yml', 'twig.engine')))); $this->infoParser->expects($this->at(0))->method('parse')->with($this->root . '/core/modules/system/tests/themes/test_subtheme/test_subtheme.info.yml')->will($this->returnCallback(function ($file) { $info_parser = new InfoParser(); return $info_parser->parse($file); })); $this->infoParser->expects($this->at(1))->method('parse')->with($this->root . '/core/modules/system/tests/themes/test_basetheme/test_basetheme.info.yml')->will($this->returnCallback(function ($file) { $info_parser = new InfoParser(); return $info_parser->parse($file); })); $this->moduleHandler->expects($this->once())->method('buildModuleDependencies')->will($this->returnArgument(0)); $theme_data = $this->themeHandler->rebuildThemeData(); $this->assertCount(2, $theme_data); $info_basetheme = $theme_data['test_basetheme']; $info_subtheme = $theme_data['test_subtheme']; // Ensure some basic properties. $this->assertInstanceOf('Drupal\\Core\\Extension\\Extension', $info_basetheme); $this->assertEquals('test_basetheme', $info_basetheme->getName()); $this->assertInstanceOf('Drupal\\Core\\Extension\\Extension', $info_subtheme); $this->assertEquals('test_subtheme', $info_subtheme->getName()); // Test the parent/child-theme properties. $info_subtheme->info['base theme'] = 'test_basetheme'; $info_basetheme->sub_themes = array('test_subtheme'); $this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info_basetheme->owner); $this->assertEquals('twig', $info_basetheme->prefix); $this->assertEquals($this->root . '/core/themes/engines/twig/twig.engine', $info_subtheme->owner); $this->assertEquals('twig', $info_subtheme->prefix); }
protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $config = $this->configFactory->getEditable('system.theme'); $this->themeHandler->refreshInfo(); $theme = $input->getArgument('theme'); $default = $input->getOption('set-default'); if ($default && count($theme) > 1) { $io->error($this->trans('commands.theme.install.messages.invalid-theme-default')); return; } $themes = $this->themeHandler->rebuildThemeData(); $themesAvailable = []; $themesInstalled = []; $themesUnavailable = []; foreach ($theme as $themeName) { if (isset($themes[$themeName]) && $themes[$themeName]->status == 0) { $themesAvailable[] = $themes[$themeName]->info['name']; } elseif (isset($themes[$themeName]) && $themes[$themeName]->status == 1) { $themesInstalled[] = $themes[$themeName]->info['name']; } else { $themesUnavailable[] = $themeName; } } if (count($themesAvailable) > 0) { try { if ($this->themeHandler->install($theme)) { if (count($themesAvailable) > 1) { $io->info(sprintf($this->trans('commands.theme.install.messages.themes-success'), implode(',', $themesAvailable))); } else { if ($default) { // Set the default theme. $config->set('default', $theme[0])->save(); $io->info(sprintf($this->trans('commands.theme.install.messages.theme-default-success'), $themesAvailable[0])); } else { $io->info(sprintf($this->trans('commands.theme.install.messages.theme-success'), $themesAvailable[0])); } } } } catch (UnmetDependenciesException $e) { $io->error(sprintf($this->trans('commands.theme.install.messages.success'), $theme)); drupal_set_message($e->getTranslatedMessage($this->getStringTranslation(), $theme), 'error'); } } elseif (empty($themesAvailable) && count($themesInstalled) > 0) { if (count($themesInstalled) > 1) { $io->info(sprintf($this->trans('commands.theme.install.messages.themes-nothing'), implode(',', $themesInstalled))); } else { $io->info(sprintf($this->trans('commands.theme.install.messages.theme-nothing'), implode(',', $themesInstalled))); } } else { if (count($themesUnavailable) > 1) { $io->error(sprintf($this->trans('commands.theme.install.messages.themes-missing'), implode(',', $themesUnavailable))); } else { $io->error(sprintf($this->trans('commands.theme.install.messages.theme-missing'), implode(',', $themesUnavailable))); } } // Run cache rebuild to see changes in Web UI $this->chainQueue->addCommand('cache:rebuild', ['cache' => 'all']); }
/** * {@inheritdoc} */ protected function interact(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); try { $theme = $input->getOption('theme') ? $this->validator->validateModuleName($input->getOption('theme')) : null; } catch (\Exception $error) { $io->error($error->getMessage()); return; } if (!$theme) { $validators = $this->validator; $theme = $io->ask($this->trans('commands.generate.theme.questions.theme'), '', function ($theme) use($validators) { return $validators->validateModuleName($theme); }); $input->setOption('theme', $theme); } try { $machine_name = $input->getOption('machine-name') ? $this->validator->validateModule($input->getOption('machine-name')) : null; } catch (\Exception $error) { $io->error($error->getMessage()); return; } if (!$machine_name) { $machine_name = $io->ask($this->trans('commands.generate.module.questions.machine-name'), $this->stringConverter->createMachineName($theme), function ($machine_name) use($validators) { return $validators->validateMachineName($machine_name); }); $input->setOption('machine-name', $machine_name); } $theme_path = $input->getOption('theme-path'); if (!$theme_path) { $drupalRoot = $this->appRoot; $theme_path = $io->ask($this->trans('commands.generate.theme.questions.theme-path'), '/themes/custom', function ($theme_path) use($drupalRoot, $machine_name) { $theme_path = ($theme_path[0] != '/' ? '/' : '') . $theme_path; $full_path = $drupalRoot . $theme_path . '/' . $machine_name; if (file_exists($full_path)) { throw new \InvalidArgumentException(sprintf($this->trans('commands.generate.theme.errors.directory-exists'), $full_path)); } else { return $theme_path; } }); $input->setOption('theme-path', $theme_path); } $description = $input->getOption('description'); if (!$description) { $description = $io->ask($this->trans('commands.generate.theme.questions.description'), 'My Awesome theme'); $input->setOption('description', $description); } $package = $input->getOption('package'); if (!$package) { $package = $io->ask($this->trans('commands.generate.theme.questions.package'), 'Other'); $input->setOption('package', $package); } $core = $input->getOption('core'); if (!$core) { $core = $io->ask($this->trans('commands.generate.theme.questions.core'), '8.x'); $input->setOption('core', $core); } $base_theme = $input->getOption('base-theme'); if (!$base_theme) { $themes = $this->themeHandler->rebuildThemeData(); $themes['false'] = ''; uasort($themes, 'system_sort_modules_by_info_name'); $base_theme = $io->choiceNoList($this->trans('commands.generate.theme.options.base-theme'), array_keys($themes)); $input->setOption('base-theme', $base_theme); } $global_library = $input->getOption('global-library'); if (!$global_library) { $global_library = $io->ask($this->trans('commands.generate.theme.questions.global-library'), 'global-styling'); $input->setOption('global-library', $global_library); } // --regions option. $regions = $input->getOption('regions'); if (!$regions) { if ($io->confirm($this->trans('commands.generate.theme.questions.regions'), true)) { // @see \Drupal\Console\Command\Shared\ThemeRegionTrait::regionQuestion $regions = $this->regionQuestion($io); $input->setOption('regions', $regions); } } // --breakpoints option. $breakpoints = $input->getOption('breakpoints'); if (!$breakpoints) { if ($io->confirm($this->trans('commands.generate.theme.questions.breakpoints'), true)) { // @see \Drupal\Console\Command\Shared\ThemeRegionTrait::regionQuestion $breakpoints = $this->breakpointQuestion($io); $input->setOption('breakpoints', $breakpoints); } } }