1: <?php
2:
3: namespace LaravelUi5\Core\Commands;
4:
5: use InvalidArgumentException;
6: use Illuminate\Support\Facades\File;
7: use Illuminate\Console\Command;
8:
9: class BaseGenerator extends Command
10: {
11:
12: protected function assertAppExists(string $app): bool
13: {
14: return File::exists(base_path("ui5/{$app}"));
15: }
16:
17: /**
18: * Parses and validates a name in the format AppName/ObjectName.
19: *
20: * Ensures that both parts use CamelCase and that the separator is present.
21: *
22: * @param string $input The raw input string, e.g. "ProjectKpi/CutOff"
23: * @return array{string, string} [$appName, $objectName]
24: * @throws InvalidArgumentException If format or naming is incorrect
25: */
26: protected function parseCamelCasePair(string $input): array
27: {
28: if (!str_contains($input, '/')) {
29: throw new InvalidArgumentException('Please use the format AppName/ObjectName (e.g. Projects/CutOff).');
30: }
31:
32: [$app, $object] = explode('/', $input, 2);
33:
34: foreach (['App name' => $app, 'Object name' => $object] as $label => $value) {
35: $this->assertCamelCase($label, $value);
36: }
37:
38: return [$app, $object];
39: }
40:
41: protected function assertCamelCase(string $label, string $input): void
42: {
43: if (!preg_match('/^[A-Z][a-zA-Z0-9]+$/', $input)) {
44: throw new InvalidArgumentException("{$label} must be CamelCase (e.g. ProjectKpi, CutOff).");
45: }
46: }
47:
48: /**
49: * Compiles a stub file by replacing all placeholders with the provided values.
50: *
51: * This method loads a stub file from the predefined `resources/stubs` directory
52: * and replaces all placeholder tokens (e.g., `{{ className }}`) with the corresponding
53: * values from the `$replacements` array.
54: *
55: * @param string $stubName The name of the stub file (e.g., 'TileClass.stub').
56: * @param array<string, string> $replacements An associative array of placeholder names
57: * and their replacement values.
58: * Keys should match the placeholder names
59: * without curly braces.
60: *
61: * @return string The compiled stub content with all placeholders replaced.
62: */
63: protected function compileStub(string $stubName, array $replacements): string
64: {
65: $stub = File::get(__DIR__ . "/../../resources/stubs/$stubName");
66:
67: foreach ($replacements as $key => $value) {
68: $stub = str_replace("{{ $key }}", $value, $stub);
69: }
70:
71: return $stub;
72: }
73:
74: /**
75: * @param string $sourcePath The distribution directory of the UI5 resources
76: * @param string $targetPath The src path of the LaravelUi5 module, e.g. ./ui5/Users/src
77: * @param array $toCopy Array with file names to copy
78: * @return void
79: */
80: protected function copyDistAssets(string $sourcePath, string $targetPath, array $toCopy): void
81: {
82: $source = $sourcePath;
83: $target = $targetPath . '../resources/ui5/';
84:
85: File::ensureDirectoryExists($target);
86: File::ensureDirectoryExists($target . 'i18n');
87:
88: foreach ($toCopy as $file) {
89: $from = "{$source}/{$file}";
90: $to = $target . $file;
91: if (file_exists($from)) {
92: File::copy($from, $to);
93: if ($this->output->isVerbose()) {
94: $this->info("{$file}");
95: }
96: }
97: }
98: }
99: }
100: