Files
timebank-cc-public/app/Console/Commands/PlatformInit.php
T

103 lines
3.9 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
/**
* Create the platform folder from platform.example/. With --from-current, also copy what this installation runs on
* today: config/<TIMEBANK_CONFIG>.php to config.php, the active theme to theme.php. Never overwrites a file; the old
* files stay in place (platform:check warns while both exist).
*/
class PlatformInit extends Command
{
protected $signature = 'platform:init {--from-current : Copy the active platform config and theme into the folder}';
protected $description = 'Create the platform folder (optionally from the current config and theme)';
public function handle(): int
{
$root = platform_path();
$skeleton = base_path('platform.example');
foreach (File::allFiles($skeleton, true) as $file) {
$this->copyIfMissing($file->getPathname(), "{$root}/{$file->getRelativePathname()}");
}
if ($this->option('from-current')) {
$name = (string) config('app.timebank_config');
if (is_file(config_path("{$name}.php"))) {
$this->copyIfMissing(config_path("{$name}.php"), "{$root}/config.php");
} else {
$this->warn("No config/{$name}.php to copy.");
}
$id = theme_id();
$theme = ['id' => $id, ...(config("themes.themes.{$id}") ?? [])];
$this->writeIfMissing("{$root}/theme.php", "<?php\n\n// The theme of this platform, copied from config/themes.php ({$id}) by platform:init.\nreturn " . $this->export($theme) . ";\n");
$this->newLine();
$this->line('Brand files to copy by hand, if this platform has them:');
// The files in use now, after the fallbacks (a theme's own logo, the generated text logo, the default)
foreach ([false => 'mail-logo.png', true => 'mail-logo-inverted.png'] as $inverted => $target) {
$logo = theme_email_logo_file((bool) $inverted);
if (is_file($logo)) {
$this->line(' ' . (str_starts_with($logo, base_path() . '/') ? substr($logo, strlen(base_path()) + 1) : $logo) . " -> platform/public/{$target}");
}
}
if ($dir = theme_logo('favicon_dir')) {
$this->line(" public/{$dir}/* -> platform/public/");
}
$this->line(' a changed logo: php artisan platform:override ' . (theme_logo('svg_inline') ?: "logos.{$id}"));
}
$this->newLine();
$this->info("Platform folder: {$root}. Then: php artisan platform:link, php artisan platform:check.");
return self::SUCCESS;
}
private function copyIfMissing(string $from, string $to): void
{
if (file_exists($to)) {
$this->line(" kept {$to}");
return;
}
File::ensureDirectoryExists(dirname($to));
File::copy($from, $to);
$this->line(" created {$to}");
}
private function writeIfMissing(string $to, string $content): void
{
if (file_exists($to)) {
$this->line(" kept {$to}");
return;
}
File::ensureDirectoryExists(dirname($to));
File::put($to, $content);
$this->line(" created {$to}");
}
/** An array as PHP source with short array syntax, indented like the config files. */
private function export(mixed $value, int $depth = 0): string
{
if (!is_array($value)) {
return var_export($value, true);
}
$pad = str_repeat(' ', $depth + 1);
$isList = array_is_list($value);
$lines = array_map(
fn ($key, $item) => $pad . ($isList ? '' : var_export($key, true) . ' => ') . $this->export($item, $depth + 1) . ',',
array_keys($value),
$value
);
return $lines ? "[\n" . implode("\n", $lines) . "\n" . str_repeat(' ', $depth) . ']' : '[]';
}
}