@artilingo/artiframe-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/logo.png +0 -0
- package/assets/logo.svg +22 -0
- package/assets/logo.webp +0 -0
- package/assets/logo@0.5x.png +0 -0
- package/assets/logo@0.75x.png +0 -0
- package/assets/logo@1.5x.png +0 -0
- package/assets/logo@2x.png +0 -0
- package/assets/logo@3x.png +0 -0
- package/assets/logo@4x.png +0 -0
- package/bin/artiframe.js +57 -0
- package/bin/artiframe.php +45 -0
- package/core-stubs/app/ApiControl.php +81 -0
- package/core-stubs/app/Database.php +69 -0
- package/core-stubs/app/DotEnv.php +63 -0
- package/core-stubs/app/R2Manager.php +130 -0
- package/core-stubs/app/ViewControl.php +24 -0
- package/core-stubs/bin/SystemMethod.php +271 -0
- package/core-stubs/bin/ViewMethod.php +354 -0
- package/core-stubs/docs/de.html +951 -0
- package/core-stubs/docs/en.html +952 -0
- package/core-stubs/docs/es.html +947 -0
- package/core-stubs/docs/fr.html +850 -0
- package/core-stubs/docs/tr.html +951 -0
- package/core-stubs/public/assets/css/components/footer.css +0 -0
- package/core-stubs/public/assets/css/components/header.css +0 -0
- package/core-stubs/public/assets/css/components/mobilenav.css +0 -0
- package/core-stubs/public/assets/css/components/sidebar.css +0 -0
- package/core-stubs/public/assets/css/components/theme-modal.css +0 -0
- package/core-stubs/public/assets/css/root/app.css +61 -0
- package/core-stubs/public/assets/js/components/header.js +0 -0
- package/core-stubs/public/assets/js/components/mobilenav.js +0 -0
- package/core-stubs/public/assets/js/components/sidebar.js +0 -0
- package/core-stubs/public/assets/js/components/theme-modal.js +0 -0
- package/core-stubs/public/assets/js/root/app.js +30 -0
- package/core-stubs/public/includes/footer.php +5 -0
- package/core-stubs/public/includes/head.php +26 -0
- package/core-stubs/public/includes/header.php +5 -0
- package/core-stubs/public/includes/mobilenav.php +5 -0
- package/core-stubs/public/includes/sidebar.php +5 -0
- package/core-stubs/public/includes/theme-modal.php +5 -0
- package/core-stubs/readme/de.md +29 -0
- package/core-stubs/readme/en.md +29 -0
- package/core-stubs/readme/es.md +29 -0
- package/core-stubs/readme/fr.md +29 -0
- package/core-stubs/readme/tr.md +29 -0
- package/package.json +49 -0
- package/scripts/postinstall.js +21 -0
- package/src/App.php +266 -0
- package/src/Commands/MakeApiCommand.php +71 -0
- package/src/Commands/MakeClassCommand.php +88 -0
- package/src/Commands/MakeViewCommand.php +95 -0
- package/src/Commands/NewProjectCommand.php +633 -0
- package/src/Commands/VersionCommand.php +92 -0
- package/src/Lang/de.php +53 -0
- package/src/Lang/en.php +53 -0
- package/src/Lang/es.php +53 -0
- package/src/Lang/fr.php +53 -0
- package/src/Lang/tr.php +53 -0
- package/src/Services/Safeguard.php +48 -0
- package/src/Services/Translator.php +52 -0
package/src/App.php
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
|
|
6
|
+
class App
|
|
7
|
+
{
|
|
8
|
+
private array $originalArgs;
|
|
9
|
+
private array $args;
|
|
10
|
+
private Translator $translator;
|
|
11
|
+
|
|
12
|
+
public function __construct(array $argv)
|
|
13
|
+
{
|
|
14
|
+
$this->originalArgs = $argv;
|
|
15
|
+
$this->args = $argv;
|
|
16
|
+
$this->initTranslator();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private function initTranslator(): void
|
|
20
|
+
{
|
|
21
|
+
$lang = $this->getOrAskLanguage();
|
|
22
|
+
$this->translator = new Translator($lang);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private function getOrAskLanguage(): string
|
|
26
|
+
{
|
|
27
|
+
$home = getenv('HOME') ?: getenv('USERPROFILE');
|
|
28
|
+
$configFile = $home ? $home . \DIRECTORY_SEPARATOR . '.artiframe_lang' : null;
|
|
29
|
+
|
|
30
|
+
$lang = null;
|
|
31
|
+
|
|
32
|
+
// 1. Check argument --lang=
|
|
33
|
+
foreach ($this->originalArgs as $arg) {
|
|
34
|
+
if (strpos($arg, '--lang=') === 0) {
|
|
35
|
+
$lang = strtolower(substr($arg, 7, 2));
|
|
36
|
+
if ($configFile) file_put_contents($configFile, $lang);
|
|
37
|
+
return $lang;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// 2. Check config file
|
|
42
|
+
if ($configFile && file_exists($configFile)) {
|
|
43
|
+
$lang = trim(file_get_contents($configFile));
|
|
44
|
+
if (in_array($lang, ['tr', 'en', 'de', 'fr', 'es'])) {
|
|
45
|
+
return $lang;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// 3. Fallback check system env (optional, but asking is better)
|
|
50
|
+
|
|
51
|
+
// 4. Ask user
|
|
52
|
+
echo PHP_EOL;
|
|
53
|
+
echo "\033[1;32mWelcome to ArtiFrame! / ArtiFrame'e Hoş Geldiniz!\033[0m" . PHP_EOL;
|
|
54
|
+
echo "Please select your preferred language / Lütfen dilinizi seçin:" . PHP_EOL;
|
|
55
|
+
echo " [1] 🇹🇷 Türkçe (TR)" . PHP_EOL;
|
|
56
|
+
echo " [2] 🇬🇧 English (EN)" . PHP_EOL;
|
|
57
|
+
echo " [3] 🇩🇪 Deutsch (DE)" . PHP_EOL;
|
|
58
|
+
echo " [4] 🇫🇷 Français (FR)" . PHP_EOL;
|
|
59
|
+
echo " [5] 🇪🇸 Español (ES)" . PHP_EOL;
|
|
60
|
+
echo PHP_EOL;
|
|
61
|
+
|
|
62
|
+
while (true) {
|
|
63
|
+
echo "Select [1-5]: ";
|
|
64
|
+
$choice = trim(fgets(STDIN));
|
|
65
|
+
$map = [
|
|
66
|
+
'1' => 'tr',
|
|
67
|
+
'2' => 'en',
|
|
68
|
+
'3' => 'de',
|
|
69
|
+
'4' => 'fr',
|
|
70
|
+
'5' => 'es'
|
|
71
|
+
];
|
|
72
|
+
|
|
73
|
+
if (isset($map[$choice])) {
|
|
74
|
+
$lang = $map[$choice];
|
|
75
|
+
if ($configFile) file_put_contents($configFile, $lang);
|
|
76
|
+
echo PHP_EOL . "Language set to: " . strtoupper($lang) . PHP_EOL;
|
|
77
|
+
return $lang;
|
|
78
|
+
}
|
|
79
|
+
echo "Invalid choice. Please try again." . PHP_EOL;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public function run(): void
|
|
84
|
+
{
|
|
85
|
+
$script = array_shift($this->args);
|
|
86
|
+
|
|
87
|
+
// Strip --lang flag globally for args
|
|
88
|
+
$this->args = array_filter($this->args, function($arg) {
|
|
89
|
+
return strpos($arg, '--lang=') !== 0;
|
|
90
|
+
});
|
|
91
|
+
$this->args = array_values($this->args);
|
|
92
|
+
|
|
93
|
+
// If no arguments provided, enter Interactive Mode (REPL)
|
|
94
|
+
if (empty($this->args)) {
|
|
95
|
+
$this->runInteractiveShell();
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// One-shot mode
|
|
100
|
+
$commandName = array_shift($this->args);
|
|
101
|
+
$this->routeCommand($commandName, $this->args);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private function runInteractiveShell(): void
|
|
105
|
+
{
|
|
106
|
+
$this->showBanner();
|
|
107
|
+
|
|
108
|
+
while (true) {
|
|
109
|
+
echo "\033[1;32martiframe\033[0m\033[38;5;240m>\033[0m ";
|
|
110
|
+
$input = trim(fgets(STDIN));
|
|
111
|
+
|
|
112
|
+
if ($input === '') {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (in_array(strtolower($input), ['exit', 'quit'])) {
|
|
117
|
+
echo PHP_EOL . "\033[38;5;240m Goodbye. Build something great.\033[0m" . PHP_EOL . PHP_EOL;
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
$parts = explode(' ', $input);
|
|
122
|
+
$parts = array_filter($parts, function($v) { return trim($v) !== ''; });
|
|
123
|
+
$parts = array_values($parts);
|
|
124
|
+
|
|
125
|
+
$commandName = array_shift($parts);
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
$this->routeCommand($commandName, $parts);
|
|
129
|
+
} catch (\Exception $e) {
|
|
130
|
+
echo "\033[1;31m ✖ Error:\033[0m " . $e->getMessage() . PHP_EOL;
|
|
131
|
+
}
|
|
132
|
+
echo PHP_EOL;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private function showBanner(): void
|
|
137
|
+
{
|
|
138
|
+
$g = "\033[38;2;0;157;108m"; // #009d6c green
|
|
139
|
+
$lg = "\033[38;2;0;200;140m"; // lighter green for accent
|
|
140
|
+
$d = "\033[38;2;80;80;80m"; // dim gray for decorators
|
|
141
|
+
$w = "\033[1;37m"; // white bold
|
|
142
|
+
$r = "\033[0m"; // reset
|
|
143
|
+
|
|
144
|
+
echo PHP_EOL;
|
|
145
|
+
echo $g . " ┌─────────────────────────────────────────────────────────────┐" . $r . PHP_EOL;
|
|
146
|
+
echo $g . " │" . $r . PHP_EOL;
|
|
147
|
+
echo $g . " │" . $r . " " . $g . " █████╗ ██████╗ ████████╗██╗███████╗██████╗ █████╗ ███╗ ███╗███████╗" . $r . PHP_EOL;
|
|
148
|
+
echo $g . " │" . $r . " " . $g . " ██╔══██╗██╔══██╗╚══██╔══╝██║██╔════╝██╔══██╗██╔══██╗████╗ ████║██╔════╝" . $r . PHP_EOL;
|
|
149
|
+
echo $g . " │" . $r . " " . $lg . " ███████║██████╔╝ ██║ ██║█████╗ ██████╔╝███████║██╔████╔██║█████╗ " . $r . PHP_EOL;
|
|
150
|
+
echo $g . " │" . $r . " " . $g . " ██╔══██║██╔══██╗ ██║ ██║██╔══╝ ██╔══██╗██╔══██║██║╚██╔╝██║██╔══╝ " . $r . PHP_EOL;
|
|
151
|
+
echo $g . " │" . $r . " " . $g . " ██║ ██║██║ ██║ ██║ ██║██║ ██║ ██║██║ ██║██║ ╚═╝ ██║███████╗" . $r . PHP_EOL;
|
|
152
|
+
echo $g . " │" . $r . " " . $g . " ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝" . $r . PHP_EOL;
|
|
153
|
+
echo $g . " │" . $r . PHP_EOL;
|
|
154
|
+
echo $g . " │" . $r . " " . $d . " ─────────────────────────────────────────────────────────" . $r . PHP_EOL;
|
|
155
|
+
echo $g . " │" . $r . " " . $w . " [A] Agile Circuit Core v" . ARTIFRAME_VERSION . $r . $d . " │ Lightweight Native PHP Framework" . $r . PHP_EOL;
|
|
156
|
+
echo $g . " │" . $r . " " . $d . " ─────────────────────────────────────────────────────────" . $r . PHP_EOL;
|
|
157
|
+
echo $g . " │" . $r . PHP_EOL;
|
|
158
|
+
echo $g . " └─────────────────────────────────────────────────────────────┘" . $r . PHP_EOL;
|
|
159
|
+
echo PHP_EOL;
|
|
160
|
+
echo " " . $d . "Type " . $r . $g . "help" . $r . $d . " for available commands, or " . $r . $g . "exit" . $r . $d . " to quit." . $r . PHP_EOL;
|
|
161
|
+
echo PHP_EOL;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
private function routeCommand(string $commandName, array $commandArgs): void
|
|
167
|
+
{
|
|
168
|
+
switch ($commandName) {
|
|
169
|
+
case 'new':
|
|
170
|
+
(new \ArtiFrame\Cli\Commands\NewProjectCommand($this->translator))->execute($commandArgs);
|
|
171
|
+
break;
|
|
172
|
+
|
|
173
|
+
case 'make:view':
|
|
174
|
+
(new \ArtiFrame\Cli\Commands\MakeViewCommand($this->translator))->execute($commandArgs);
|
|
175
|
+
break;
|
|
176
|
+
|
|
177
|
+
case 'make:api':
|
|
178
|
+
(new \ArtiFrame\Cli\Commands\MakeApiCommand($this->translator))->execute($commandArgs);
|
|
179
|
+
break;
|
|
180
|
+
|
|
181
|
+
case 'make:class':
|
|
182
|
+
(new \ArtiFrame\Cli\Commands\MakeClassCommand($this->translator))->execute($commandArgs);
|
|
183
|
+
break;
|
|
184
|
+
|
|
185
|
+
case 'version':
|
|
186
|
+
(new \ArtiFrame\Cli\Commands\VersionCommand($this->translator))->execute($commandArgs);
|
|
187
|
+
break;
|
|
188
|
+
|
|
189
|
+
case 'help':
|
|
190
|
+
default:
|
|
191
|
+
$this->showHelp();
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private function showHelp(): void
|
|
197
|
+
{
|
|
198
|
+
$g = "\033[38;2;0;157;108m"; // #009d6c green
|
|
199
|
+
$lg = "\033[38;2;0;200;140m"; // light green
|
|
200
|
+
$y = "\033[38;5;220m"; // yellow for args
|
|
201
|
+
$d = "\033[38;2;100;100;100m"; // dim
|
|
202
|
+
$w = "\033[1;37m"; // white bold
|
|
203
|
+
$c = "\033[38;5;81m"; // cyan for sub-options
|
|
204
|
+
$r = "\033[0m"; // reset
|
|
205
|
+
|
|
206
|
+
echo PHP_EOL;
|
|
207
|
+
echo " " . $w . "COMMANDS" . $r . PHP_EOL;
|
|
208
|
+
echo " " . $d . "─────────────────────────────────────────────────────────────" . $r . PHP_EOL;
|
|
209
|
+
echo PHP_EOL;
|
|
210
|
+
|
|
211
|
+
// new
|
|
212
|
+
echo " " . $g . "new" . $r . " " . $y . "<project-path>" . $r . PHP_EOL;
|
|
213
|
+
echo " " . $d . "│" . $r . " Create a new ArtiFrame project from scratch." . PHP_EOL;
|
|
214
|
+
echo " " . $d . "└── " . $r . "Example: " . $lg . "new my-app" . $r . PHP_EOL;
|
|
215
|
+
echo PHP_EOL;
|
|
216
|
+
|
|
217
|
+
// make:view
|
|
218
|
+
echo " " . $g . "make:view" . $r . " " . $y . "<path>" . $r . PHP_EOL;
|
|
219
|
+
echo " " . $d . "│" . $r . " Generate a new view file with its paired CSS and JS assets." . PHP_EOL;
|
|
220
|
+
echo " " . $d . "│" . $r . " The path can use subdirectories (auto-created)." . PHP_EOL;
|
|
221
|
+
echo " " . $d . "└── " . $r . "Example: " . $lg . "make:view pages/about.php" . $r . PHP_EOL;
|
|
222
|
+
echo PHP_EOL;
|
|
223
|
+
|
|
224
|
+
// make:api
|
|
225
|
+
echo " " . $g . "make:api" . $r . " " . $y . "<template>" . $r . " " . $y . "<path>" . $r . PHP_EOL;
|
|
226
|
+
echo " " . $d . "│" . $r . " Generate a new API endpoint file." . PHP_EOL;
|
|
227
|
+
echo " " . $d . "│" . $r . PHP_EOL;
|
|
228
|
+
echo " " . $d . "├── " . $c . "standart" . $r . " Single-action endpoint (one request, one response)." . PHP_EOL;
|
|
229
|
+
echo " " . $d . "│ " . $r . "Example: " . $lg . "make:api standart api/user/get.php" . $r . PHP_EOL;
|
|
230
|
+
echo " " . $d . "│" . $r . PHP_EOL;
|
|
231
|
+
echo " " . $d . "└── " . $c . "switch-case" . $r . " Multi-action endpoint with action routing." . PHP_EOL;
|
|
232
|
+
echo " " . $d . " " . $r . "Example: " . $lg . "make:api switch-case api/user/crud.php" . $r . PHP_EOL;
|
|
233
|
+
echo PHP_EOL;
|
|
234
|
+
|
|
235
|
+
// make:class
|
|
236
|
+
echo " " . $g . "make:class" . $r . " " . $y . "<path>" . $r . PHP_EOL;
|
|
237
|
+
echo " " . $d . "│" . $r . " Generate a new PHP class file with namespace boilerplate." . PHP_EOL;
|
|
238
|
+
echo " " . $d . "└── " . $r . "Example: " . $lg . "make:class classes/UserManager.php" . $r . PHP_EOL;
|
|
239
|
+
echo PHP_EOL;
|
|
240
|
+
|
|
241
|
+
// version
|
|
242
|
+
echo " " . $g . "version" . $r . " " . $y . "<action>" . $r . " " . $y . "<level>" . $r . PHP_EOL;
|
|
243
|
+
echo " " . $d . "│" . $r . " Manage the semantic version number stored in your project config." . PHP_EOL;
|
|
244
|
+
echo " " . $d . "│" . $r . " Version format: " . $w . "MAJOR.MINOR.PATCH" . $r . " (e.g. 2.4.1)" . PHP_EOL;
|
|
245
|
+
echo " " . $d . "│" . $r . PHP_EOL;
|
|
246
|
+
echo " " . $d . "├── " . $c . "upgrade" . $r . PHP_EOL;
|
|
247
|
+
echo " " . $d . "│ ├── " . $c . "patch" . $r . " Bug fixes, small tweaks. " . $d . "1.0.0 → 1.0.1" . $r . PHP_EOL;
|
|
248
|
+
echo " " . $d . "│ ├── " . $c . "minor" . $r . " New backwards-compat feature. " . $d . "1.0.0 → 1.1.0" . $r . PHP_EOL;
|
|
249
|
+
echo " " . $d . "│ └── " . $c . "major" . $r . " Breaking changes. " . $d . "1.0.0 → 2.0.0" . $r . PHP_EOL;
|
|
250
|
+
echo " " . $d . "│" . $r . PHP_EOL;
|
|
251
|
+
echo " " . $d . "└── " . $c . "downgrade" . $r . PHP_EOL;
|
|
252
|
+
echo " " . $d . " ├── " . $c . "patch" . $r . " Roll back last patch. " . $d . "1.0.3 → 1.0.2" . $r . PHP_EOL;
|
|
253
|
+
echo " " . $d . " ├── " . $c . "minor" . $r . " Roll back last minor release. " . $d . "1.3.0 → 1.2.0" . $r . PHP_EOL;
|
|
254
|
+
echo " " . $d . " └── " . $c . "major" . $r . " Roll back last major release. " . $d . "3.0.0 → 2.0.0" . $r . PHP_EOL;
|
|
255
|
+
echo PHP_EOL;
|
|
256
|
+
echo " " . $d . " Example: " . $lg . "version upgrade minor" . $r . PHP_EOL;
|
|
257
|
+
echo " " . $d . " Example: " . $lg . "version downgrade patch" . $r . PHP_EOL;
|
|
258
|
+
echo PHP_EOL;
|
|
259
|
+
|
|
260
|
+
// help / exit
|
|
261
|
+
echo " " . $d . "─────────────────────────────────────────────────────────────" . $r . PHP_EOL;
|
|
262
|
+
echo " " . $g . "help" . $r . " Show this help message." . PHP_EOL;
|
|
263
|
+
echo " " . $g . "exit" . $r . " / " . $g . "quit" . $r . " Exit the interactive shell." . PHP_EOL;
|
|
264
|
+
echo PHP_EOL;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
use ArtiFrame\Cli\Services\Safeguard;
|
|
6
|
+
|
|
7
|
+
class MakeApiCommand
|
|
8
|
+
{
|
|
9
|
+
private Translator $translator;
|
|
10
|
+
private Safeguard $safeguard;
|
|
11
|
+
|
|
12
|
+
public function __construct(Translator $translator)
|
|
13
|
+
{
|
|
14
|
+
$this->translator = $translator;
|
|
15
|
+
$this->safeguard = new Safeguard($translator);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public function execute(array $args): void
|
|
19
|
+
{
|
|
20
|
+
$type = $args[0] ?? null;
|
|
21
|
+
$target = $args[1] ?? null;
|
|
22
|
+
|
|
23
|
+
if (!$type || !in_array($type, ['standart', 'switch-case'])) {
|
|
24
|
+
echo "❌ " . $this->translator->get('ERROR_API_TYPE') . PHP_EOL;
|
|
25
|
+
exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!$target) {
|
|
29
|
+
echo "❌ " . $this->translator->get('ERROR_API_PATH_REQUIRED') . PHP_EOL;
|
|
30
|
+
exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Normalize path
|
|
34
|
+
$target = ltrim(str_replace('\\', '/', $target), '/');
|
|
35
|
+
|
|
36
|
+
// Ensure .php extension
|
|
37
|
+
if (!str_ends_with($target, '.php')) {
|
|
38
|
+
$target .= '.php';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
$projectRoot = getcwd();
|
|
42
|
+
$apiPath = $projectRoot . '/public/api/' . $type . '/' . $target;
|
|
43
|
+
|
|
44
|
+
if (!$this->safeguard->checkTarget($apiPath)) {
|
|
45
|
+
exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
$stubName = 'api-' . $type . '.stub';
|
|
49
|
+
$stubPath = $projectRoot . '/bin/stubs/' . $stubName;
|
|
50
|
+
|
|
51
|
+
if (!file_exists($stubPath)) {
|
|
52
|
+
echo "❌ " . $this->translator->get('ERROR_STUB_NOT_FOUND', ['path' => $stubPath]) . PHP_EOL;
|
|
53
|
+
exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Generate File
|
|
57
|
+
$this->ensureDirectoryExists(dirname($apiPath));
|
|
58
|
+
|
|
59
|
+
$content = file_get_contents($stubPath);
|
|
60
|
+
file_put_contents($apiPath, $content);
|
|
61
|
+
|
|
62
|
+
echo $this->translator->get('SUCCESS_API', ['type' => $type, 'path' => $target]) . PHP_EOL;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private function ensureDirectoryExists(string $path): void
|
|
66
|
+
{
|
|
67
|
+
if (!is_dir($path)) {
|
|
68
|
+
mkdir($path, 0755, true);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
use ArtiFrame\Cli\Services\Safeguard;
|
|
6
|
+
|
|
7
|
+
class MakeClassCommand
|
|
8
|
+
{
|
|
9
|
+
private Translator $translator;
|
|
10
|
+
private Safeguard $safeguard;
|
|
11
|
+
|
|
12
|
+
public function __construct(Translator $translator)
|
|
13
|
+
{
|
|
14
|
+
$this->translator = $translator;
|
|
15
|
+
$this->safeguard = new Safeguard($translator);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public function execute(array $args): void
|
|
19
|
+
{
|
|
20
|
+
$target = $args[0] ?? null;
|
|
21
|
+
|
|
22
|
+
if (!$target || strpos($target, '/') === false && strpos($target, '\\') === false) {
|
|
23
|
+
echo "❌ " . $this->translator->get('DIR_REQUIRED_ERROR') . PHP_EOL;
|
|
24
|
+
echo "Example: /src/Service/PaymentService" . PHP_EOL;
|
|
25
|
+
exit(1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Normalize path
|
|
29
|
+
$target = ltrim(str_replace('\\', '/', $target), '/');
|
|
30
|
+
|
|
31
|
+
// Allowed roots
|
|
32
|
+
if (!str_starts_with($target, 'app/') && !str_starts_with($target, 'src/')) {
|
|
33
|
+
echo "❌ " . $this->translator->get('ERROR_CLASS_ROOT') . PHP_EOL;
|
|
34
|
+
exit(1);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Ensure .php extension
|
|
38
|
+
if (!str_ends_with($target, '.php')) {
|
|
39
|
+
$target .= '.php';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$projectRoot = getcwd();
|
|
43
|
+
$classPath = $projectRoot . '/' . $target;
|
|
44
|
+
|
|
45
|
+
if (!$this->safeguard->checkTarget($classPath)) {
|
|
46
|
+
exit(1);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
$stubPath = $projectRoot . '/bin/stubs/class.stub';
|
|
50
|
+
if (!file_exists($stubPath)) {
|
|
51
|
+
echo "❌ " . $this->translator->get('ERROR_STUB_NOT_FOUND', ['path' => $stubPath]) . PHP_EOL;
|
|
52
|
+
exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Determine Namespace and Class Name
|
|
56
|
+
$pathParts = explode('/', str_replace('.php', '', $target));
|
|
57
|
+
$className = array_pop($pathParts);
|
|
58
|
+
|
|
59
|
+
// Create Namespace array with proper casing
|
|
60
|
+
$namespaceParts = [];
|
|
61
|
+
foreach ($pathParts as $part) {
|
|
62
|
+
$namespaceParts[] = ucfirst($part);
|
|
63
|
+
}
|
|
64
|
+
$namespace = implode('\\', $namespaceParts);
|
|
65
|
+
|
|
66
|
+
// Generate File
|
|
67
|
+
$this->ensureDirectoryExists(dirname($classPath));
|
|
68
|
+
|
|
69
|
+
$content = file_get_contents($stubPath);
|
|
70
|
+
$content = str_replace(
|
|
71
|
+
['{{NAMESPACE}}', '{{CLASS_NAME}}'],
|
|
72
|
+
[$namespace, $className],
|
|
73
|
+
$content
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
file_put_contents($classPath, $content);
|
|
77
|
+
|
|
78
|
+
echo $this->translator->get('SUCCESS_CLASS', ['path' => $target]) . PHP_EOL;
|
|
79
|
+
echo $this->translator->get('NAMESPACE_LABEL') . ' ' . $namespace . PHP_EOL;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private function ensureDirectoryExists(string $path): void
|
|
83
|
+
{
|
|
84
|
+
if (!is_dir($path)) {
|
|
85
|
+
mkdir($path, 0755, true);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
use ArtiFrame\Cli\Services\Safeguard;
|
|
6
|
+
|
|
7
|
+
class MakeViewCommand
|
|
8
|
+
{
|
|
9
|
+
private Translator $translator;
|
|
10
|
+
private Safeguard $safeguard;
|
|
11
|
+
|
|
12
|
+
public function __construct(Translator $translator)
|
|
13
|
+
{
|
|
14
|
+
$this->translator = $translator;
|
|
15
|
+
$this->safeguard = new Safeguard($translator);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public function execute(array $args): void
|
|
19
|
+
{
|
|
20
|
+
$target = $args[0] ?? null;
|
|
21
|
+
|
|
22
|
+
if (!$target) {
|
|
23
|
+
echo "❌ " . $this->translator->get('ERROR_VIEW_PATH_REQUIRED') . PHP_EOL;
|
|
24
|
+
exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Normalize path
|
|
28
|
+
$target = ltrim(str_replace('\\', '/', $target), '/');
|
|
29
|
+
|
|
30
|
+
// Ensure .php extension
|
|
31
|
+
if (!str_ends_with($target, '.php')) {
|
|
32
|
+
$target .= '.php';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$projectRoot = getcwd();
|
|
36
|
+
$viewPath = $projectRoot . '/public/' . $target;
|
|
37
|
+
|
|
38
|
+
if (!$this->safeguard->checkTarget($viewPath)) {
|
|
39
|
+
exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Determine hierarchy for assets
|
|
43
|
+
$pathParts = explode('/', $target);
|
|
44
|
+
$fileNameWithExt = array_pop($pathParts);
|
|
45
|
+
$fileName = pathinfo($fileNameWithExt, PATHINFO_FILENAME);
|
|
46
|
+
|
|
47
|
+
$subDir = count($pathParts) > 0 ? implode('/', $pathParts) : 'root';
|
|
48
|
+
|
|
49
|
+
$cssRelative = '/assets/css/' . $subDir . '/' . $fileName . '.css';
|
|
50
|
+
$jsRelative = '/assets/js/' . $subDir . '/' . $fileName . '.js';
|
|
51
|
+
|
|
52
|
+
$cssPath = $projectRoot . '/public' . $cssRelative;
|
|
53
|
+
$jsPath = $projectRoot . '/public' . $jsRelative;
|
|
54
|
+
|
|
55
|
+
// Stub path
|
|
56
|
+
$stubPath = $projectRoot . '/bin/stubs/view.stub';
|
|
57
|
+
if (!file_exists($stubPath)) {
|
|
58
|
+
echo "❌ " . $this->translator->get('ERROR_STUB_NOT_FOUND', ['path' => $stubPath]) . PHP_EOL;
|
|
59
|
+
echo $this->translator->get('ERROR_RUN_FROM_ROOT') . PHP_EOL;
|
|
60
|
+
exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Generate Files
|
|
64
|
+
$this->ensureDirectoryExists(dirname($viewPath));
|
|
65
|
+
$this->ensureDirectoryExists(dirname($cssPath));
|
|
66
|
+
$this->ensureDirectoryExists(dirname($jsPath));
|
|
67
|
+
|
|
68
|
+
// Format Title
|
|
69
|
+
$title = ucfirst(str_replace(['-', '_'], ' ', $fileName));
|
|
70
|
+
|
|
71
|
+
// Read and parse stub
|
|
72
|
+
$lang = $this->translator->getLang();
|
|
73
|
+
$content = file_get_contents($stubPath);
|
|
74
|
+
$content = str_replace(
|
|
75
|
+
['{{LANG}}', '{{VIEW_TITLE}}', '{{CSS_PATH}}', '{{JS_PATH}}'],
|
|
76
|
+
[$lang, $title, $cssRelative, $jsRelative],
|
|
77
|
+
$content
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
file_put_contents($viewPath, $content);
|
|
81
|
+
file_put_contents($cssPath, "/* CSS for {$title} */\n");
|
|
82
|
+
file_put_contents($jsPath, "/* JS for {$title} */\n");
|
|
83
|
+
|
|
84
|
+
echo $this->translator->get('SUCCESS_VIEW', ['path' => $target]) . PHP_EOL;
|
|
85
|
+
echo $this->translator->get('SUCCESS_CSS', ['path' => $cssRelative]) . PHP_EOL;
|
|
86
|
+
echo $this->translator->get('SUCCESS_JS', ['path' => $jsRelative]) . PHP_EOL;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private function ensureDirectoryExists(string $path): void
|
|
90
|
+
{
|
|
91
|
+
if (!is_dir($path)) {
|
|
92
|
+
mkdir($path, 0755, true);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|