View source
<?php
namespace Drupal\at_theme_generator\Theme;
use Drupal\Component\Utility\Html;
use Drupal\Component\Serialization\Yaml;
use Drupal\at_theme_generator\File\FileOperations;
use Drupal\at_theme_generator\File\DirectoryOperations;
class ThemeGenerator {
protected $machine_name;
protected $friendly_name;
protected $sub_theme_type;
protected $clone_source;
protected $skin_base;
protected $templates;
protected $block_config;
protected $scss;
protected $color;
protected $theme_settings_file;
protected $dir_option;
protected $description;
protected $version;
protected $datetime;
protected $generic_description;
protected $path;
protected $at_generator_path;
protected $source;
protected $target;
protected $config;
public function __construct($values) {
$this->machine_name = $values['generate']['generate_machine_name'];
$this->friendly_name = Html::escape(trim($values['generate']['generate_friendly_name']));
$this->sub_theme_type = $values['generate']['generate_type'];
$this->clone_source = $values['generate']['generate_clone_source'] ?: '';
$this->skin_base = $values['generate']['generate_skin_base'] ?: '';
$this->templates = $values['generate']['options']['generate_templates'];
$this->block_config = $values['generate']['options']['generate_block_config'];
$this->layout = $values['generate']['options']['generate_layout'];
$this->scss = $values['generate']['options']['generate_scss'];
$this->color = $values['generate']['options']['generate_color'];
$this->theme_settings_file = $values['generate']['options']['generate_themesettingsfile'];
$this->dir_option = $values['generate']['options']['generate_directory'];
$this->dir_option_custom = $values['generate']['options']['generate_directory_custom'] ?: '';
$this->description = preg_replace('/[^\\p{Latin}\\d\\s\\p{P}]/u', '', Html::escape(trim($values['generate']['options']['generate_description'])));
if (!empty($values['generate']['options']['generate_version'])) {
$this->version = Html::escape(str_replace(' ', '', trim($values['generate']['options']['generate_version'])));
}
else {
$this->version = '8.x-1.0';
}
$this->datetime = \Drupal::service('date.formatter')
->format(REQUEST_TIME, 'custom', 'D jS, M, Y - G:i');
$this->generic_description = 'Adaptivetheme sub-theme';
$this->fileOperations = new FileOperations();
$this->directoryOperations = new DirectoryOperations();
$this->source = $this
->sourceTheme();
$this->target = $this
->targetDirectory();
$this->info = $this
->getInfoYml();
$this->base_theme_info = $this
->getBaseThemeInfoYml();
$this->layout_library = $this
->getLayout();
$this->config = $this
->getConfig();
$this->clone_source_config = $this
->getCloneSourceConfigSettings();
$this->at_core_path = drupal_get_path('theme', 'at_core');
$this->at_generator_path = drupal_get_path('module', 'at_theme_generator');
}
public function targetDirectory() {
if ($this->dir_option === 'custom') {
$target_dir = $this->dir_option_custom;
}
elseif ($this->dir_option === 'public://') {
$target_path = 'public://generated_themes';
$target_dir = $this->directoryOperations
->directoryPrepare([
$target_path,
]);
}
else {
$target_dir = 'themes';
}
return $target_dir . '/' . $this->machine_name;
}
public function sourceTheme() {
$source = [];
if ($this->sub_theme_type === 'clone') {
$source['name'] = $this->clone_source;
$source['path'] = drupal_get_path('theme', $this->clone_source);
}
else {
$source['name'] = strtoupper($this->sub_theme_type);
$source['path'] = drupal_get_path('module', 'at_theme_generator') . '/starterkits/' . $this->sub_theme_type;
}
return $source;
}
public function copySource() {
if (is_dir($this->source['path'])) {
$this->directoryOperations
->directoryRecursiveCopy($this->source['path'], $this->target);
}
}
public function renameYmlFiles($yml_files) {
foreach ($yml_files as $file) {
$this->fileOperations
->fileRename($this->target . '/' . $this->source['name'] . '.' . $file . '.yml', $this->target . '/' . $this->machine_name . '.' . $file . '.yml');
}
}
public function rewriteLibrariesYml($needle) {
$this->fileOperations
->fileStrReplace($this->target . '/' . $this->machine_name . '.libraries.yml', $needle, $this->version);
}
public function renameThemeFile() {
$this->fileOperations
->fileRename($this->target . '/' . $this->source['name'] . '.theme', $this->target . '/' . $this->machine_name . '.theme');
}
public function rewriteThemeFile($needle) {
$this->fileOperations
->fileStrReplace($this->target . '/' . $this->machine_name . '.theme', $needle, $this->machine_name);
}
public function rewriteThemeSettingsFile($needle) {
$this->fileOperations
->fileStrReplace($this->target . '/theme-settings.php', $needle, $this->machine_name);
}
public function removeThemeSettingsFile() {
$this->directoryOperations
->directoryRemove($this->target . '/theme-settings.php');
}
public function getConfig() {
if (file_exists($this->source['path'] . '/config')) {
return $this->directoryOperations
->directoryScanRecursive($this->source['path'] . '/config');
}
else {
return [];
}
}
public function renameConfigFiles() {
if (!empty($this->config)) {
foreach ($this->config as $config_path => $config_files) {
$dir = $this->target . '/config/' . $config_path;
if (is_dir($dir)) {
foreach ($config_files as $config_file) {
$new_config_file = str_replace($this->source['name'], $this->machine_name, $config_file) ?: '';
$target_config_path = $this->target . '/config/' . $config_path;
$this->fileOperations
->fileRename($target_config_path . '/' . $config_file, $target_config_path . '/' . $new_config_file);
}
}
}
}
}
public function rewriteConfigFiles() {
if (!empty($this->config)) {
foreach ($this->config as $config_path => $config_files) {
$dir = $this->target . '/config/' . $config_path;
if (is_dir($dir)) {
foreach ($config_files as $config_file) {
$new_config_file = str_replace($this->source['name'], $this->machine_name, $config_file) ?: '';
$target_config_path = $this->target . '/config/' . $config_path;
$this->fileOperations
->fileStrReplace($target_config_path . '/' . $new_config_file, 'TARGET', $this->target);
$this->fileOperations
->fileStrReplace($target_config_path . '/' . $new_config_file, $this->source['name'], $this->machine_name);
}
}
}
}
}
public function getCloneSourceConfigSettings() {
return \Drupal::config($this->clone_source . '.settings')
->get();
}
public function replaceCloneConfigSettings() {
if (!empty($this->clone_source_config)) {
if (array_key_exists('_core', $this->clone_source_config)) {
unset($this->clone_source_config['_core']);
}
$old_config = "{$this->target}/config/install/{$this->machine_name}.settings.yml";
$new_config = Yaml::encode($this->clone_source_config);
$find_generated_files = "themes/{$this->clone_source}/styles/css/generated";
$replace_generated_files = "themes/{$this->machine_name}/styles/css/generated";
$new_config = str_replace($find_generated_files, $replace_generated_files, $new_config);
$this->fileOperations
->fileReplace($new_config, $old_config);
$this->fileOperations
->fileStrReplace($old_config, $this->clone_source, $this->machine_name);
}
}
public function removeConfigFiles() {
$dir = $this->target . '/config/optional';
if (is_dir($dir)) {
$this->directoryOperations
->directoryRemove($this->target . '/config/optional');
}
}
public function getGeneratedCssFiles() {
return $this->directoryOperations
->directoryScan($this->target . '/styles/css/generated');
}
public function rewritePageLayoutCSS() {
if (file_exists($this->target . '/styles/css/generated/FLOAT.layout.page.css')) {
$file_path = $this->target . '/styles/css/generated/STARTERKIT.layout.page.css';
$data = file_get_contents($this->target . '/styles/css/generated/FLOAT.layout.page.css', NULL, NULL, 0, 5000);
if ($this->layout !== 'flex') {
$this->fileOperations
->fileReplace($data, $file_path);
}
unlink($this->target . '/styles/css/generated/FLOAT.layout.page.css');
}
}
public function renameGeneratedCssFiles() {
$generated_css_files = $this
->getGeneratedCssFiles();
$generated_css_files_path = $this->target . '/styles/css/generated/';
foreach ($generated_css_files as $old_css_file) {
$new_css_file = str_replace($this->source['name'], $this->machine_name, $old_css_file);
$this->fileOperations
->fileRename($generated_css_files_path . '/' . $old_css_file, $generated_css_files_path . '/' . $new_css_file);
}
}
public function removeUnusedLayout() {
if ($this->layout === 'flex') {
$remove[] = 'page-layout-float';
$remove[] = 'plugin-layout-float';
}
else {
$remove[] = 'page-layout-flex';
$remove[] = 'plugin-layout-flex';
}
foreach ($remove as $key => $value) {
$this->directoryOperations
->directoryRemove($this->target . '/layout/' . $value);
}
}
public function renameLayouts() {
if ($this->layout === 'flex') {
$rename_dir['page-layout'] = 'page-layout-flex';
$rename_dir['plugin-layout'] = 'plugin-layout-flex';
}
else {
$rename_dir['page-layout'] = 'page-layout-float';
$rename_dir['plugin-layout'] = 'plugin-layout-float';
}
foreach ($rename_dir as $key => $value) {
$this->fileOperations
->fileRename($this->target . '/layout/' . $value, $this->target . '/layout/' . $key);
}
}
public function rewriteUikitPartials() {
if (file_exists($this->target . '/styles/uikit/components/partials/base/_base.scss')) {
$this->fileOperations
->fileStrReplace($this->target . '/styles/uikit/components/partials/base/_base.scss', 'page-layout-flex', 'page-layout');
}
}
public function rewritePageTemplateLibrary() {
$this->fileOperations
->fileStrReplace($this->target . '/templates/generated/page.html.twig', $this->source['name'], $this->machine_name);
}
public function copyTemplates() {
$this->directoryOperations
->directoryRecursiveCopy($this->at_core_path . '/templates', $this->target . '/templates');
}
public function removeColorDirectory() {
$this->directoryOperations
->directoryRemove($this->target . '/color');
}
public function getComponentCssFiles() {
return $this->directoryOperations
->directoryScan($this->target . '/styles/css/components');
}
public function removeCssSourceMaps() {
$this->fileOperations
->fileDeleteByExtension($this->target . '/styles/css/components', 'map');
$dir = $this->target . '/styles/css/components/maps';
if (is_dir($dir)) {
$this->directoryOperations
->directoryRemove($dir);
}
}
public function processSkinStyles($type) {
$this->fileOperations
->fileRename($this->target . '/styles/css/' . $type . '.css', $this->target . '/styles/css/' . $this->machine_name . '.css');
$this->fileOperations
->fileRename($this->target . '/styles/scss/' . $type . '.scss', $this->target . '/styles/scss/' . $this->machine_name . '.scss');
$this->fileOperations
->fileStrReplace($this->target . '/' . $this->machine_name . '.libraries.yml', $type, $this->machine_name);
}
public function replaceSkinLogos() {
$skin_base_path = drupal_get_path('theme', $this->skin_base);
foreach ([
'svg',
'png',
] as $ext) {
$logo = $skin_base_path . '/logo.' . $ext;
if (file_exists($logo)) {
file_unmanaged_copy($logo, $this->target, FILE_EXISTS_REPLACE);
}
}
}
public function removeCssSourceMappingURL() {
$component_css_files = $this
->getComponentCssFiles();
$component_css_files_path = $this->target . '/styles/css/components/';
foreach ($component_css_files as $component_file_key => $component_file) {
$map_string = '/*# sourceMappingURL=' . str_replace('.css', '.css.map', $component_file) . ' */';
if (file_exists($component_css_files_path . '/' . $component_file)) {
$this->fileOperations
->fileStrReplace($component_css_files_path . '/' . $component_file, $map_string, '');
}
}
}
public function removeScss() {
$dirs = [
'/styles/scss',
'/styles/uikit',
'/layout/page-layout/sass',
'/layout/plugin-layout/sass',
'/bower_components',
'/node_modules',
];
foreach ($dirs as $dir) {
if (is_dir($this->target . '/' . $dir)) {
$this->directoryOperations
->directoryRemove($this->target . '/' . $dir);
}
}
}
public function removeScssTools() {
$scss_tools = [
'bower.json',
'package.json',
'.csslintrc',
'Gruntfile.js',
'Gemfile',
'Gemfile.lock',
'.gitignore',
];
foreach ($scss_tools as $tool) {
if (file_exists($this->target . '/' . $tool)) {
unlink($this->target . '/' . $tool);
}
}
}
public function getLayout() {
return 'page-layout';
}
public function getInfoYml() {
return \Drupal::service('info_parser')
->parse($this->source['path'] . '/' . $this->source['name'] . '.info.yml');
}
public function getBaseThemeInfoYml() {
$base_theme = $this->info['base theme'];
if ($this->sub_theme_type === 'skin') {
$base_theme = $this->skin_base;
}
return \Drupal::service('info_parser')
->parse(drupal_get_path('theme', $base_theme) . '/' . $base_theme . '.info.yml');
}
public function infoYmlDescription($desc) {
$text = $desc['text'] ? $desc['text'] . ' <br>' : '';
$clone = isset($desc['clone']) ? 'Clone of: ' . $desc['clone'] . ' <br>' : '';
$skin = isset($desc['skin']) ? 'Skin of: ' . $desc['skin'] . ' <br>' : '';
$base = $desc['base'] ? 'Base: ' . $desc['base'] . ' <br>' : '';
$time = $desc['time'] ? 'Generated: ' . $desc['time'] : '';
return $text . $clone . $skin . $base . $time;
}
public function infoYml($info) {
$rebuilt_info = $this->fileOperations
->fileBuildInfoYml($info);
$this->fileOperations
->fileReplace($rebuilt_info, $this->target . '/' . $this->machine_name . '.info.yml');
}
}