HEX
Server: nginx/1.28.3
System: Linux lightweb-s1 5.15.0-173-generic #183-Ubuntu SMP Fri Mar 6 13:29:34 UTC 2026 x86_64
User: drdrivek-71 (1047)
PHP: 8.3.30
Disabled: NONE
Upload Files
File: /home/mocapict-106/mocapictures.kr/app/Services/MakeTheme.php
<?php

declare(strict_types=1);

namespace Hexadog\ThemesManager\Console\Generators;

use Hexadog\ThemesManager\Console\Commands\Traits\BlockMessage;
use Hexadog\ThemesManager\Console\Commands\Traits\SectionMessage;
use Hexadog\ThemesManager\Facades\ThemesManager;
use Illuminate\Config\Repository;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class MakeTheme extends Command
{
    use BlockMessage;
    use SectionMessage;

    /**
     * The console command name.
     */
    protected $name = 'amuz-cms:theme';

    /**
     * The console command description.
     */
    protected $description = 'Create a new Theme';

    /**
     * Config.
     */
    protected Repository $config;

    protected Filesystem $files;

    /**
     * Create Theme Info.
     */
    protected array $theme = [];

    /**
     * Theme folder path.
     */
    protected string $themePath;

    /**
     * Create a new command instance.
     */
    public function __construct(Repository $config, Filesystem $filesystem)
    {
        $this->config = $config;
        $this->files = $filesystem;

        parent::__construct();
    }

    /**
     * Execute the console command.
     */
    public function handle(): void
    {
        $this->themePath = $this->config->get('themes-manager.directory', 'amuz-themes');

        $this->sectionMessage('Create Theme for AMUZ CMS', 'Create new Theme');
        if ($this->validateName()) {
            $this->askAuthor();
            $this->askDescription();
            $this->askVersion();
            $this->askParent();

            try {
                $this->generateTheme();

                $this->alert('Theme successfully created');
                $this->warn('생성된 테마는 아래 명령을 통해 Git 저장소를 등록해야합니다.');
                $this->comment("https://github.com/organizations/amuzcorp/repositories/new");
                $this->comment("위 주소로 접속하여 {$this->theme['name']} 이름으로 새 저장소를 생성합니다.");
                $this->comment('생성이 완료되면 아래 명령을 통해 저장소와 연결할 수 있습니다.');
                $this->info("cd amuz-themes/{$this->theme['vendor']}/{$this->theme['name']} && git init && git add . && git commit -m 'first commit' && git branch -M main && git remote add origin https://github.com/amuzcorp/{$this->theme['name']}.git && git push -u origin main && cd ../../../");
                $this->comment("이후에는 테마에 포함된 README.md를 참고하여 적절히 활용할 수 있습니다.");

            } catch (\Exception $e) {
                $this->error($e->getMessage());
            }
        }
    }

    /**
     * Validate theme name provided.
     */
    protected function validateName()
    {
        $this->askName();

        if (Str::contains($this->theme['name'], '\\')) {
            $nameParts = explode('\\', str_replace('\\\\', '\\', $this->theme['name']));
            if (count($nameParts) === 2) {
                $this->theme['vendor'] = mb_strtolower($nameParts[0]);
                $this->theme['name'] = Str::kebab($nameParts[1]);
            } else {
                // ask for vendor
                $this->askVendor();
                $this->theme['name'] = Str::kebab($this->theme['name']);
            }
        } else {
            if (Str::contains($this->theme['name'], '/')) {
                [$vendor, $name] = explode('/', $this->theme['name']);
                $this->theme['vendor'] = mb_strtolower($vendor);
                $this->theme['name'] = Str::kebab($name);
            } else {
                $this->askVendor();
                $this->theme['name'] = Str::kebab($this->theme['name']);
            }
        }

        if (ThemesManager::has("{$this->theme['vendor']}/{$this->theme['name']}")) {
            $this->error("Theme with name {$this->theme['vendor']}/{$this->theme['name']} already exists!");

            return false;
        }

        return true;
    }

    /**
     * Replace placeholders in generated file.
     */
    protected function replacePlaceholders(\Symfony\Component\Finder\SplFileInfo $file): string
    {
        $this->sectionMessage('File generation', "{$file->getPathName()}");

        $find = [
            'DummyAuthorName',
            'DummyAuthorEmail',
            'DummyDescription',
            'DummyName',
            'DummyParent',
            'DummyVendor',
            'DummyVersion',
            'DummyScreenshot',
        ];

        $replace = [
            Str::title(Arr::get($this->theme, 'author-name', '')),
            Arr::get($this->theme, 'author-email', ''),
            Arr::get($this->theme, 'description', ''),
            Arr::get($this->theme, 'name', ''),
            Arr::get($this->theme, 'parent', ''),
            Arr::get($this->theme, 'vendor', ''),
            Arr::get($this->theme, 'version', '1.0'),
            Arr::get($this->theme, 'screenshot', 'screenshot.png'),
        ];

        return str_replace($find, $replace, $file->getContents());
    }

    /**
     * Ask for theme author information.
     * Notice: if value is set in themes-manager.composer.author.name and themes-manager.composer.author.email config value
     * then this value will be used.
     */
    protected function askAuthor(): void
    {
        $this->theme['author-name'] = $this->config->get('themes-manager.composer.author.name') ?? $this->ask('Author name');
        $this->theme['author-email'] = $this->config->get('themes-manager.composer.author.email') ?? $this->ask('Author email');
    }

    /**
     * Ask for theme description.
     */
    protected function askDescription(): void
    {
        $this->theme['description'] = $this->ask('Description');
    }

    /**
     * Ask for theme name.
     */
    protected function askName(): void
    {
        do {
            $this->theme['name'] = $this->ask('Theme Name');
        } while (! strlen($this->theme['name']));
    }

    /**
     * Ask for parent theme name.
     */
    protected function askParent(): void
    {
        if ($this->confirm('Is it a child theme?')) {
            $this->theme['parent'] = $this->ask('Parent theme name');
            $this->theme['parent'] = mb_strtolower($this->theme['parent']);
        }
    }

    /**
     * Ask for theme vendor.
     * Notice: if value is set in themes-manager.composer.vendor config value
     * then this value will be used.
     */
    protected function askVendor(): void
    {
        do {
            $this->theme['vendor'] = mb_strtolower($this->config->get('themes-manager.composer.vendor') ?? $this->ask('Vendor name'));
        } while (! strlen($this->theme['vendor']));
    }

    /**
     * Ask for theme version.
     */
    protected function askVersion(): void
    {
        $this->theme['version'] = $this->ask('Version number');

        if (! strlen($this->theme['version'])) {
            $this->theme['version'] = null;
        }
    }

    /**
     * Generate Theme structure in target directory.
     */
    private function generateTheme(): void
    {
        $this->sectionMessage('Files generation', 'start files generation process...');

        $basepath = base_path($this->themePath);

        $directory = $basepath . DIRECTORY_SEPARATOR . $this->theme['vendor'] . DIRECTORY_SEPARATOR . $this->theme['name'];

        // Make directory
        if ($this->files->isDirectory($directory)) {
            throw new \Exception("Theme {$this->theme['name']} already exists");
        }
        $this->files->makeDirectory($directory, 0755, true);

        $source = app_path('Stubs/_theme-structure');

        $this->files->copyDirectory($source, $directory, null);

        /**
         * Replace files placeholder.
         */
        $files = $this->files->allFiles($directory);
        foreach ($files as $file) {
            $contents = $this->replacePlaceholders($file);
            $filePath = $directory . DIRECTORY_SEPARATOR . $file->getRelativePathname();

            $this->files->put($filePath, $contents);
        }
    }
}