@artilingo/artiframe-cli 2.0.4 → 3.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/LICENSE +660 -660
- package/README.md +64 -118
- package/bin/artiframe.js +0 -0
- package/bin/artiframe.php +0 -0
- package/core-stubs/app/ApiAuthControl.php +76 -0
- package/core-stubs/app/ApiControl.php +81 -35
- package/core-stubs/app/AuthControl.php +39 -0
- package/core-stubs/app/Database.php +36 -35
- package/core-stubs/app/DotEnv.php +19 -1
- package/core-stubs/app/ViewControl.php +47 -1
- package/core-stubs/bin/SQLMethod.php +261 -0
- package/core-stubs/bin/SystemMethod.php +115 -74
- package/core-stubs/bin/ViewMethod.php +19 -5
- package/core-stubs/docs/de.html +4325 -4347
- package/core-stubs/docs/en.html +4325 -4347
- package/core-stubs/docs/es.html +4325 -4347
- package/core-stubs/docs/fr.html +4325 -4347
- package/core-stubs/docs/tr.html +117 -46
- package/core-stubs/public/403.php +52 -0
- package/core-stubs/public/assets/css/components/header.css +174 -0
- package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
- package/core-stubs/public/assets/css/components/sidebar.css +184 -0
- package/core-stubs/public/assets/css/root/app.css +975 -38
- package/core-stubs/public/assets/css/root/root.css +64 -0
- package/core-stubs/public/assets/js/components/header.js +380 -0
- package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
- package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
- package/core-stubs/public/assets/js/root/app.js +1870 -0
- package/core-stubs/public/includes/footer.php +4 -5
- package/core-stubs/public/includes/head-auth.php +65 -0
- package/core-stubs/public/includes/head.php +56 -17
- package/core-stubs/public/includes/header.php +135 -1
- package/core-stubs/public/includes/mobilenav.php +75 -3
- package/core-stubs/public/includes/sidebar.php +186 -1
- package/core-stubs/public/includes/theme-modal.php +1 -0
- package/db-studio/debug.log +3 -0
- package/db-studio/index.html +1755 -0
- package/db-studio/launcher.html +102 -0
- package/db-studio/launcher.js +180 -0
- package/db-studio/logo.svg +22 -0
- package/db-studio/main.js +568 -0
- package/db-studio/package-lock.json +1034 -0
- package/db-studio/package.json +16 -0
- package/db-studio/preload.js +29 -0
- package/devops-studio/api-inspector.js +222 -0
- package/devops-studio/index.html +1892 -0
- package/devops-studio/logo.svg +22 -0
- package/devops-studio/main.js +67 -0
- package/devops-studio/make-wizard.js +635 -0
- package/devops-studio/package-lock.json +871 -0
- package/devops-studio/package.json +12 -0
- package/package.json +5 -2
- package/scripts/postinstall.js +44 -8
- package/server-studio/.json-404-guard +1 -0
- package/server-studio/index.html +283 -0
- package/server-studio/logo.svg +22 -0
- package/server-studio/main.js +133 -0
- package/server-studio/package-lock.json +1179 -0
- package/server-studio/package.json +15 -0
- package/server-studio/router.php +99 -0
- package/src/App.php +29 -0
- package/src/Commands/AddCommand.php +26 -9
- package/src/Commands/DbExportCommand.php +131 -0
- package/src/Commands/DbStartCommand.php +46 -0
- package/src/Commands/DevopsCommand.php +35 -0
- package/src/Commands/GoCommand.php +48 -48
- package/src/Commands/ListCommand.php +68 -68
- package/src/Commands/MakeApiCommand.php +6 -1
- package/src/Commands/MakeViewCommand.php +25 -2
- package/src/Commands/NewProjectCommand.php +16 -11
- package/src/Commands/OptimizeCommand.php +61 -0
- package/src/Commands/RemoveCommand.php +35 -7
- package/src/Commands/ServeCommand.php +46 -91
- package/src/Commands/ShowCommand.php +24 -24
- package/src/Commands/UpgradeCommand.php +39 -10
- package/stubs/make/api-switch-case.stub +1 -1
- package/stubs/make/auth-api-standart.stub +20 -0
- package/stubs/make/auth-api-switch-case.stub +38 -0
- package/stubs/make/auth-view.stub +26 -0
- package/stubs/make/class.stub +10 -2
- package/stubs/make/view.stub +3 -0
- package/stubs/service/image.stub +334 -334
- package/stubs/service/iyzico.stub +637 -637
- package/stubs/service/jwt.stub +312 -312
- package/stubs/service/phpmailer.stub +143 -143
- package/stubs/service/pusher.stub +232 -232
- package/stubs/service/qrcode.stub +169 -169
- package/stubs/service/redis.stub +361 -361
- package/stubs/service/s3.stub +377 -377
- package/stubs/service/stripe.stub +526 -526
- package/stubs/service/twilio.stub +361 -361
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "artiframe-server-studio",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "ArtiFrame Real-time Server Dashboard",
|
|
5
|
+
"main": "main.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "electron ."
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"qrcode": "^1.5.3"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"electron": "^28.2.0"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
$uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
|
|
3
|
+
$projectRoot = getenv('ARTIFRAME_PROJECT_ROOT');
|
|
4
|
+
$publicDir = $projectRoot . '/public';
|
|
5
|
+
$requestedFile = $publicDir . $uri;
|
|
6
|
+
|
|
7
|
+
$resolvedFile = 'public/index.php';
|
|
8
|
+
$isStatic = false;
|
|
9
|
+
|
|
10
|
+
if ($uri !== '/' && file_exists($requestedFile) && !is_dir($requestedFile)) {
|
|
11
|
+
$resolvedFile = 'public' . $uri;
|
|
12
|
+
$isStatic = true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
$globalErrorMessage = null;
|
|
16
|
+
|
|
17
|
+
// Function to send log to Electron
|
|
18
|
+
function sendLogToElectron($statusCode = null) {
|
|
19
|
+
$loggerPort = getenv('ARTIFRAME_STUDIO_LOGGER_PORT');
|
|
20
|
+
if (!$loggerPort) return;
|
|
21
|
+
|
|
22
|
+
global $uri, $resolvedFile, $globalErrorMessage, $startTime;
|
|
23
|
+
|
|
24
|
+
if ($statusCode === null) {
|
|
25
|
+
$statusCode = http_response_code() ?: 200;
|
|
26
|
+
$error = error_get_last();
|
|
27
|
+
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR])) {
|
|
28
|
+
$statusCode = 500;
|
|
29
|
+
if (!$globalErrorMessage) {
|
|
30
|
+
$globalErrorMessage = $error['message'] . ' in ' . $error['file'] . ':' . $error['line'];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
$parsedParams = [];
|
|
36
|
+
foreach ($_GET as $k => $v) {
|
|
37
|
+
$val = is_array($v) ? 'Array' : $v;
|
|
38
|
+
$parsedParams[] = '$_GET[\'' . $k . '\'] = ' . $val;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
$log = [
|
|
42
|
+
'time' => date('H:i:s'),
|
|
43
|
+
'method' => strtoupper($_SERVER['REQUEST_METHOD']),
|
|
44
|
+
'url' => $_SERVER['REQUEST_URI'],
|
|
45
|
+
'resolvedFile' => $resolvedFile,
|
|
46
|
+
'params' => implode(', ', $parsedParams),
|
|
47
|
+
'statusCode' => $statusCode,
|
|
48
|
+
'errorMessage' => $globalErrorMessage,
|
|
49
|
+
'duration' => isset($startTime) ? round((microtime(true) - $startTime) * 1000) . 'ms' : '0ms',
|
|
50
|
+
'memory' => round(memory_get_peak_usage(true) / 1024 / 1024, 2) . ' MB'
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
$payload = json_encode($log);
|
|
54
|
+
$options = [
|
|
55
|
+
'http' => [
|
|
56
|
+
'method' => 'POST',
|
|
57
|
+
'header' => "Content-Type: application/json\r\n",
|
|
58
|
+
'content' => $payload,
|
|
59
|
+
'timeout' => 0.5
|
|
60
|
+
]
|
|
61
|
+
];
|
|
62
|
+
$context = stream_context_create($options);
|
|
63
|
+
@file_get_contents("http://127.0.0.1:{$loggerPort}", false, $context);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Register shutdown to guarantee logging even on fatals
|
|
67
|
+
register_shutdown_function('sendLogToElectron');
|
|
68
|
+
|
|
69
|
+
if ($isStatic) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Intercept output to capture status code for index.php execution
|
|
74
|
+
ob_start();
|
|
75
|
+
|
|
76
|
+
$_SERVER['SCRIPT_NAME'] = '/index.php';
|
|
77
|
+
$_SERVER['SCRIPT_FILENAME'] = $publicDir . '/index.php';
|
|
78
|
+
chdir($publicDir);
|
|
79
|
+
|
|
80
|
+
try {
|
|
81
|
+
require $publicDir . '/index.php';
|
|
82
|
+
} catch (\Throwable $e) {
|
|
83
|
+
$globalErrorMessage = $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine();
|
|
84
|
+
echo "<h1>500 Internal Server Error</h1>";
|
|
85
|
+
echo "<pre>" . $globalErrorMessage . "\n" . $e->getTraceAsString() . "</pre>";
|
|
86
|
+
http_response_code(500);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
$output = ob_get_clean();
|
|
90
|
+
$statusCode = http_response_code() ?: 200;
|
|
91
|
+
|
|
92
|
+
// Apply JSON 404 Guard if needed
|
|
93
|
+
$isJson404GuardActive = file_exists(__DIR__ . '/.json-404-guard');
|
|
94
|
+
if ($statusCode === 404 && $isJson404GuardActive) {
|
|
95
|
+
header('Content-Type: application/json');
|
|
96
|
+
$output = json_encode(['error' => 'Not Found', 'message' => 'JSON 404 Guard is active.', 'code' => 404]);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
echo $output;
|
package/src/App.php
CHANGED
|
@@ -230,6 +230,28 @@ class App
|
|
|
230
230
|
break;
|
|
231
231
|
|
|
232
232
|
|
|
233
|
+
case 'optimize':
|
|
234
|
+
(new \ArtiFrame\Cli\Commands\OptimizeCommand($this->translator))->execute($commandArgs);
|
|
235
|
+
break;
|
|
236
|
+
|
|
237
|
+
case 'db:start':
|
|
238
|
+
(new \ArtiFrame\Cli\Commands\DbStartCommand($this->translator))->execute(array_merge($commandArgs, ['--mode=offline']));
|
|
239
|
+
break;
|
|
240
|
+
|
|
241
|
+
case 'db:onproject':
|
|
242
|
+
(new \ArtiFrame\Cli\Commands\DbStartCommand($this->translator))->execute(array_merge($commandArgs, ['--mode=live']));
|
|
243
|
+
break;
|
|
244
|
+
|
|
245
|
+
case 'db:export':
|
|
246
|
+
(new \ArtiFrame\Cli\Commands\DbExportCommand($this->translator))->execute($commandArgs);
|
|
247
|
+
break;
|
|
248
|
+
|
|
249
|
+
case 'devops':
|
|
250
|
+
(new \ArtiFrame\Cli\Commands\DevopsCommand($this->translator))->execute($commandArgs);
|
|
251
|
+
break;
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
233
255
|
case 'serve':
|
|
234
256
|
(new \ArtiFrame\Cli\Commands\ServeCommand($this->translator))->execute($commandArgs);
|
|
235
257
|
break;
|
|
@@ -421,6 +443,13 @@ class App
|
|
|
421
443
|
echo " " . $d . "└── " . $r . "Example: " . $lg . "issues" . $r . " or " . $lg . "issues 4" . $r . PHP_EOL;
|
|
422
444
|
echo PHP_EOL;
|
|
423
445
|
|
|
446
|
+
// db:export
|
|
447
|
+
echo " " . $g . "db:export" . $r . " " . $y . "<within|without>" . $r . PHP_EOL;
|
|
448
|
+
echo " " . $d . "│" . $r . " Veritabanını SQL dosyası olarak dışa aktarır." . PHP_EOL;
|
|
449
|
+
echo " " . $d . "├── " . $r . "Example: " . $lg . "db:export within" . $r . $d . " (Yapı ve Veriler)" . $r . PHP_EOL;
|
|
450
|
+
echo " " . $d . "└── " . $r . "Example: " . $lg . "db:export without" . $r . $d . " (Sadece Yapı)" . $r . PHP_EOL;
|
|
451
|
+
echo PHP_EOL;
|
|
452
|
+
|
|
424
453
|
// help / exit
|
|
425
454
|
echo " " . $d . "─────────────────────────────────────────────────────────────" . $r . PHP_EOL;
|
|
426
455
|
echo " " . $g . "help" . $r . " " . $t->get('HELP_HELP_DESC') . PHP_EOL;
|
|
@@ -136,11 +136,11 @@ class AddCommand
|
|
|
136
136
|
'stub' => 'phpmailer.stub',
|
|
137
137
|
'env' => [
|
|
138
138
|
'# ── mail (phpmailer) ──────────────────────',
|
|
139
|
-
'MAIL_HOST=
|
|
140
|
-
'MAIL_PORT=
|
|
139
|
+
'MAIL_HOST=127.0.0.1',
|
|
140
|
+
'MAIL_PORT=1025',
|
|
141
141
|
'MAIL_USERNAME=',
|
|
142
142
|
'MAIL_PASSWORD=',
|
|
143
|
-
'MAIL_ENCRYPTION=
|
|
143
|
+
'MAIL_ENCRYPTION=',
|
|
144
144
|
'MAIL_FROM_ADDRESS=hello@example.com',
|
|
145
145
|
'MAIL_FROM_NAME=ArtiFrame',
|
|
146
146
|
],
|
|
@@ -317,29 +317,46 @@ class AddCommand
|
|
|
317
317
|
return;
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
+
|
|
320
321
|
$envBlock = PHP_EOL . implode(PHP_EOL, $package['env']) . PHP_EOL;
|
|
321
322
|
|
|
322
323
|
// .env dosyasına ekle
|
|
323
324
|
$envFile = $projectRoot . '/.env';
|
|
324
325
|
if (file_exists($envFile)) {
|
|
325
|
-
// Zaten eklenmişse tekrar ekleme
|
|
326
326
|
$currentContent = file_get_contents($envFile);
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
// Zaten eklenmiş anahtarlardan herhangi biri var mı kontrol et
|
|
328
|
+
$alreadyExists = false;
|
|
329
|
+
foreach ($package['env'] as $line) {
|
|
330
|
+
if (str_starts_with(trim($line), '#') || empty(trim($line))) continue;
|
|
331
|
+
$key = explode('=', $line)[0];
|
|
332
|
+
if (str_contains($currentContent, $key . '=')) {
|
|
333
|
+
$alreadyExists = true;
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (!$alreadyExists) {
|
|
338
|
+
file_put_contents($envFile, $envBlock, FILE_APPEND);
|
|
329
339
|
}
|
|
330
|
-
file_put_contents($envFile, $envBlock, FILE_APPEND);
|
|
331
340
|
}
|
|
332
341
|
|
|
333
342
|
// .env.example dosyasına ekle
|
|
334
343
|
$envExample = $projectRoot . '/.env.example';
|
|
335
344
|
if (file_exists($envExample)) {
|
|
336
345
|
$currentContent = file_get_contents($envExample);
|
|
337
|
-
|
|
346
|
+
$alreadyExists = false;
|
|
347
|
+
foreach ($package['env'] as $line) {
|
|
348
|
+
if (str_starts_with(trim($line), '#') || empty(trim($line))) continue;
|
|
349
|
+
$key = explode('=', $line)[0];
|
|
350
|
+
if (str_contains($currentContent, $key . '=')) {
|
|
351
|
+
$alreadyExists = true;
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (!$alreadyExists) {
|
|
338
356
|
file_put_contents($envExample, $envBlock, FILE_APPEND);
|
|
339
357
|
}
|
|
340
358
|
}
|
|
341
359
|
}
|
|
342
|
-
|
|
343
360
|
// ─── Yardımcı Metodlar ───────────────────────────────────────
|
|
344
361
|
|
|
345
362
|
/**
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
use ArtiFrame\Cli\Services\Safeguard;
|
|
6
|
+
|
|
7
|
+
class DbExportCommand
|
|
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
|
+
private function parseEnvFile(string $path): array
|
|
19
|
+
{
|
|
20
|
+
$env = [];
|
|
21
|
+
$lines = file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
22
|
+
foreach ($lines as $line) {
|
|
23
|
+
$line = trim($line);
|
|
24
|
+
if (strpos($line, '#') === 0) continue;
|
|
25
|
+
if (strpos($line, '=') !== false) {
|
|
26
|
+
list($key, $val) = explode('=', $line, 2);
|
|
27
|
+
$env[trim($key)] = trim($val, " \t\n\r\0\x0B\"'");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return $env;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public function execute(array $args): void
|
|
34
|
+
{
|
|
35
|
+
$projectRoot = $this->safeguard->getProjectRoot();
|
|
36
|
+
|
|
37
|
+
if (!file_exists($projectRoot . '/.env')) {
|
|
38
|
+
echo "❌ .env dosyasi bulunamadi. Bu komut sadece projelerin icinde calisir.\n";
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$mode = $args[0] ?? null;
|
|
43
|
+
if (!in_array($mode, ['within', 'without'])) {
|
|
44
|
+
echo "❌ Gecersiz parametre. Kullanim:\n";
|
|
45
|
+
echo " artiframe db:export within (Yapi ve Verileri disari aktarir)\n";
|
|
46
|
+
echo " artiframe db:export without (Sadece tablo yapisini disari aktarir)\n";
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Read .env securely
|
|
51
|
+
$env = $this->parseEnvFile($projectRoot . '/.env');
|
|
52
|
+
$dbHost = $env['DB_HOST'] ?? 'localhost';
|
|
53
|
+
$dbUser = $env['DB_USER'] ?? ($env['DB_USERNAME'] ?? 'root');
|
|
54
|
+
$dbPass = $env['DB_PASS'] ?? ($env['DB_PASSWORD'] ?? '');
|
|
55
|
+
$dbName = $env['DB_NAME'] ?? ($env['DB_DATABASE'] ?? '');
|
|
56
|
+
|
|
57
|
+
if (!$dbName) {
|
|
58
|
+
echo "❌ .env dosyasinda DB_NAME ayarlanmamis.\n";
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
echo "🔄 Veritabani disari aktariliyor: {$dbName} (" . ($mode === 'within' ? 'Yapi + Veri' : 'Sadece Yapi') . ")...\n";
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
$pdo = new \PDO("mysql:host={$dbHost};dbname={$dbName};charset=utf8mb4", $dbUser, $dbPass, [
|
|
66
|
+
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
$sql = "-- ArtiFrame Veritabani Yedegi\n";
|
|
70
|
+
$sql .= "-- Tarih: " . date('Y-m-d H:i:s') . "\n";
|
|
71
|
+
$sql .= "-- Veritabani: {$dbName}\n";
|
|
72
|
+
$sql .= "-- Mod: {$mode}\n\n";
|
|
73
|
+
$sql .= "SET FOREIGN_KEY_CHECKS=0;\n\n";
|
|
74
|
+
|
|
75
|
+
$tablesQuery = $pdo->query("SHOW TABLES");
|
|
76
|
+
$tables = $tablesQuery->fetchAll(\PDO::FETCH_COLUMN);
|
|
77
|
+
|
|
78
|
+
foreach ($tables as $table) {
|
|
79
|
+
// Table structure
|
|
80
|
+
$sql .= "-- --------------------------------------------------------\n";
|
|
81
|
+
$sql .= "-- Tablo Yapisi: `{$table}`\n";
|
|
82
|
+
$sql .= "-- --------------------------------------------------------\n";
|
|
83
|
+
$sql .= "DROP TABLE IF EXISTS `{$table}`;\n";
|
|
84
|
+
|
|
85
|
+
$createRow = $pdo->query("SHOW CREATE TABLE `{$table}`")->fetch(\PDO::FETCH_ASSOC);
|
|
86
|
+
$sql .= $createRow['Create Table'] . ";\n\n";
|
|
87
|
+
|
|
88
|
+
// Table data (if within)
|
|
89
|
+
if ($mode === 'within') {
|
|
90
|
+
$rows = $pdo->query("SELECT * FROM `{$table}`")->fetchAll(\PDO::FETCH_ASSOC);
|
|
91
|
+
if (count($rows) > 0) {
|
|
92
|
+
$sql .= "-- Tablo Verisi: `{$table}`\n";
|
|
93
|
+
|
|
94
|
+
$chunks = array_chunk($rows, 100); // 100 rows per INSERT
|
|
95
|
+
foreach ($chunks as $chunk) {
|
|
96
|
+
$keys = array_keys($chunk[0]);
|
|
97
|
+
$keysList = implode("\`, \`", $keys);
|
|
98
|
+
$sql .= "INSERT INTO `{$table}` (`{$keysList}`) VALUES \n";
|
|
99
|
+
|
|
100
|
+
$valuesLines = [];
|
|
101
|
+
foreach ($chunk as $row) {
|
|
102
|
+
$vals = array_map(function($val) use ($pdo) {
|
|
103
|
+
if ($val === null) return 'NULL';
|
|
104
|
+
return $pdo->quote($val);
|
|
105
|
+
}, array_values($row));
|
|
106
|
+
$valuesLines[] = "(" . implode(", ", $vals) . ")";
|
|
107
|
+
}
|
|
108
|
+
$sql .= implode(",\n", $valuesLines) . ";\n";
|
|
109
|
+
}
|
|
110
|
+
$sql .= "\n";
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
$sql .= "SET FOREIGN_KEY_CHECKS=1;\n";
|
|
116
|
+
|
|
117
|
+
$filename = "export_{$mode}_{$dbName}_" . date('Ymd_His') . ".sql";
|
|
118
|
+
$exportPath = $projectRoot . '/' . $filename;
|
|
119
|
+
|
|
120
|
+
file_put_contents($exportPath, $sql);
|
|
121
|
+
|
|
122
|
+
echo "✅ Basarili! Veritabani disa aktarildi.\n";
|
|
123
|
+
echo "📂 Dosya: {$exportPath}\n";
|
|
124
|
+
|
|
125
|
+
} catch (\PDOException $e) {
|
|
126
|
+
echo "❌ Veritabani hatasi: " . $e->getMessage() . "\n";
|
|
127
|
+
} catch (\Exception $e) {
|
|
128
|
+
echo "❌ Hata: " . $e->getMessage() . "\n";
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
use ArtiFrame\Cli\Services\Safeguard;
|
|
6
|
+
|
|
7
|
+
class DbStartCommand
|
|
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
|
+
$projectRoot = $this->safeguard->getProjectRoot();
|
|
21
|
+
$dbStudioPath = dirname(__DIR__, 2) . '/db-studio';
|
|
22
|
+
|
|
23
|
+
$mode = 'offline';
|
|
24
|
+
if (in_array('--mode=live', $args)) {
|
|
25
|
+
$mode = 'live';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if ($mode === 'live' && !file_exists($projectRoot . '/.env')) {
|
|
29
|
+
echo "❌ .env dosyasi bulunamadi. Lutfen veritabani ayarlarini yapin veya bagimsiz mod icin 'artiframe db:start' kullanin.\n";
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
echo "🚀 ArtiFrame DB Studio baslatiliyor...\n";
|
|
34
|
+
|
|
35
|
+
$os = PHP_OS_FAMILY;
|
|
36
|
+
$cmd = sprintf('npm run start --prefix %s -- %s --mode=%s', escapeshellarg($dbStudioPath), escapeshellarg($projectRoot), $mode);
|
|
37
|
+
|
|
38
|
+
if ($os === 'Windows') {
|
|
39
|
+
pclose(popen("start \"ArtiFrame DB Studio\" cmd /c \"{$cmd}\"", "r"));
|
|
40
|
+
} else {
|
|
41
|
+
exec("{$cmd} > /dev/null 2>&1 &");
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
echo "✅ DB Studio arka planda acildi.\n";
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
|
|
6
|
+
class DevopsCommand
|
|
7
|
+
{
|
|
8
|
+
private Translator $translator;
|
|
9
|
+
|
|
10
|
+
public function __construct(Translator $translator)
|
|
11
|
+
{
|
|
12
|
+
$this->translator = $translator;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public function execute(array $args): void
|
|
16
|
+
{
|
|
17
|
+
$tab = isset($args[0]) ? $args[0] : 'launcher';
|
|
18
|
+
$cwd = getcwd();
|
|
19
|
+
|
|
20
|
+
echo "\n 🚀 ArtiFrame DevOps Studio başlatılıyor...\n";
|
|
21
|
+
|
|
22
|
+
$devopsStudioPath = dirname(__DIR__, 2) . '/devops-studio';
|
|
23
|
+
$os = PHP_OS_FAMILY;
|
|
24
|
+
|
|
25
|
+
$cmd = sprintf('npm run start --prefix %s -- %s %s', escapeshellarg($devopsStudioPath), escapeshellarg($tab), escapeshellarg($cwd));
|
|
26
|
+
|
|
27
|
+
if ($os === 'Windows') {
|
|
28
|
+
pclose(popen("start \"ArtiFrame DevOps Studio\" cmd /c \"{$cmd}\"", "r"));
|
|
29
|
+
} else {
|
|
30
|
+
exec("{$cmd} > /dev/null 2>&1 &");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
echo " ✅ DevOps Studio arka planda açıldı.\n\n";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -1,48 +1,48 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
namespace ArtiFrame\Cli\Commands;
|
|
3
|
-
|
|
4
|
-
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
-
|
|
6
|
-
class GoCommand
|
|
7
|
-
{
|
|
8
|
-
private Translator $translator;
|
|
9
|
-
|
|
10
|
-
public function __construct(Translator $translator)
|
|
11
|
-
{
|
|
12
|
-
$this->translator = $translator;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public function execute(array $args): void
|
|
16
|
-
{
|
|
17
|
-
$target = $args[0] ?? null;
|
|
18
|
-
|
|
19
|
-
if (!$target) {
|
|
20
|
-
echo "
|
|
21
|
-
❌ " . $this->translator->get('GO_MISSING_DIR') . "
|
|
22
|
-
|
|
23
|
-
";
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if ($target === 'back') {
|
|
28
|
-
$target = '..';
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (!is_dir($target)) {
|
|
32
|
-
$notFound = str_replace(':dir', $target, $this->translator->get('GO_NOT_FOUND'));
|
|
33
|
-
echo "
|
|
34
|
-
❌ " . $notFound . "
|
|
35
|
-
|
|
36
|
-
";
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
chdir($target);
|
|
41
|
-
echo "
|
|
42
|
-
✅ " . $this->translator->get('GO_SUCCESS') . "
|
|
43
|
-
";
|
|
44
|
-
echo " " . getcwd() . "
|
|
45
|
-
|
|
46
|
-
";
|
|
47
|
-
}
|
|
48
|
-
}
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
|
|
6
|
+
class GoCommand
|
|
7
|
+
{
|
|
8
|
+
private Translator $translator;
|
|
9
|
+
|
|
10
|
+
public function __construct(Translator $translator)
|
|
11
|
+
{
|
|
12
|
+
$this->translator = $translator;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public function execute(array $args): void
|
|
16
|
+
{
|
|
17
|
+
$target = $args[0] ?? null;
|
|
18
|
+
|
|
19
|
+
if (!$target) {
|
|
20
|
+
echo "
|
|
21
|
+
❌ " . $this->translator->get('GO_MISSING_DIR') . "
|
|
22
|
+
|
|
23
|
+
";
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if ($target === 'back') {
|
|
28
|
+
$target = '..';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!is_dir($target)) {
|
|
32
|
+
$notFound = str_replace(':dir', $target, $this->translator->get('GO_NOT_FOUND'));
|
|
33
|
+
echo "
|
|
34
|
+
❌ " . $notFound . "
|
|
35
|
+
|
|
36
|
+
";
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
chdir($target);
|
|
41
|
+
echo "
|
|
42
|
+
✅ " . $this->translator->get('GO_SUCCESS') . "
|
|
43
|
+
";
|
|
44
|
+
echo " " . getcwd() . "
|
|
45
|
+
|
|
46
|
+
";
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
<?php
|
|
2
|
-
namespace ArtiFrame\Cli\Commands;
|
|
3
|
-
|
|
4
|
-
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
-
|
|
6
|
-
class ListCommand
|
|
7
|
-
{
|
|
8
|
-
private Translator $translator;
|
|
9
|
-
|
|
10
|
-
public function __construct(Translator $translator)
|
|
11
|
-
{
|
|
12
|
-
$this->translator = $translator;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
public function execute(array $args): void
|
|
16
|
-
{
|
|
17
|
-
$safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
|
|
18
|
-
$dir = $safeguard->getProjectRoot();
|
|
19
|
-
$projectName = basename($dir);
|
|
20
|
-
|
|
21
|
-
echo "
|
|
22
|
-
📂 " . $projectName . "/
|
|
23
|
-
";
|
|
24
|
-
|
|
25
|
-
$priorityOrder = [
|
|
26
|
-
'bin', 'config', 'src', 'app', 'public', '.agents',
|
|
27
|
-
'vendor', '.env', '.env.example', '.gitignore',
|
|
28
|
-
'composer.json', 'composer.lock', 'schema.sql',
|
|
29
|
-
'README.md', 'OKUBENI.md', 'LESEMICH.md', 'LISEZMOI.md', 'LEAME.md',
|
|
30
|
-
'kilavuz.html', 'guide.html', 'handbuch.html', 'guide_fr.html', 'guia.html', 'LICENSE',
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
$entries = array_filter(scandir($dir), fn($e) => $e !== '.' && $e !== '..');
|
|
34
|
-
|
|
35
|
-
usort($entries, function ($a, $b) use ($priorityOrder) {
|
|
36
|
-
$ia = array_search($a, $priorityOrder);
|
|
37
|
-
$ib = array_search($b, $priorityOrder);
|
|
38
|
-
$ia = ($ia === false) ? 99 : $ia;
|
|
39
|
-
$ib = ($ib === false) ? 99 : $ib;
|
|
40
|
-
return $ia <=> $ib;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
$entries = array_values($entries);
|
|
44
|
-
$total = count($entries);
|
|
45
|
-
|
|
46
|
-
foreach ($entries as $i => $entry) {
|
|
47
|
-
$isLast = ($i === $total - 1);
|
|
48
|
-
$connector = $isLast ? '└──' : '├──';
|
|
49
|
-
$fullPath = $dir . DIRECTORY_SEPARATOR . $entry;
|
|
50
|
-
|
|
51
|
-
if (is_dir($fullPath)) {
|
|
52
|
-
$subItems = array_filter(scandir($fullPath), fn($e) => $e !== '.' && $e !== '..');
|
|
53
|
-
$subCount = count($subItems);
|
|
54
|
-
$countStr = $subCount > 0 ? ' ' . $this->translator->get('DIR_ITEM_COUNT', ['count' => $subCount]) : '';
|
|
55
|
-
echo " │ {$connector} 📂 {$entry}/{$countStr}
|
|
56
|
-
";
|
|
57
|
-
} else {
|
|
58
|
-
$size = filesize($fullPath);
|
|
59
|
-
$sizeStr = $size > 1024 ? round($size / 1024, 1) . ' KB' : $size . ' B';
|
|
60
|
-
echo " │ {$connector} 📄 {$entry} [{$sizeStr}]
|
|
61
|
-
";
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
echo " │
|
|
65
|
-
|
|
66
|
-
";
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
|
|
6
|
+
class ListCommand
|
|
7
|
+
{
|
|
8
|
+
private Translator $translator;
|
|
9
|
+
|
|
10
|
+
public function __construct(Translator $translator)
|
|
11
|
+
{
|
|
12
|
+
$this->translator = $translator;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public function execute(array $args): void
|
|
16
|
+
{
|
|
17
|
+
$safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
|
|
18
|
+
$dir = $safeguard->getProjectRoot();
|
|
19
|
+
$projectName = basename($dir);
|
|
20
|
+
|
|
21
|
+
echo "
|
|
22
|
+
📂 " . $projectName . "/
|
|
23
|
+
";
|
|
24
|
+
|
|
25
|
+
$priorityOrder = [
|
|
26
|
+
'bin', 'config', 'src', 'app', 'public', '.agents',
|
|
27
|
+
'vendor', '.env', '.env.example', '.gitignore',
|
|
28
|
+
'composer.json', 'composer.lock', 'schema.sql',
|
|
29
|
+
'README.md', 'OKUBENI.md', 'LESEMICH.md', 'LISEZMOI.md', 'LEAME.md',
|
|
30
|
+
'kilavuz.html', 'guide.html', 'handbuch.html', 'guide_fr.html', 'guia.html', 'LICENSE',
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
$entries = array_filter(scandir($dir), fn($e) => $e !== '.' && $e !== '..');
|
|
34
|
+
|
|
35
|
+
usort($entries, function ($a, $b) use ($priorityOrder) {
|
|
36
|
+
$ia = array_search($a, $priorityOrder);
|
|
37
|
+
$ib = array_search($b, $priorityOrder);
|
|
38
|
+
$ia = ($ia === false) ? 99 : $ia;
|
|
39
|
+
$ib = ($ib === false) ? 99 : $ib;
|
|
40
|
+
return $ia <=> $ib;
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
$entries = array_values($entries);
|
|
44
|
+
$total = count($entries);
|
|
45
|
+
|
|
46
|
+
foreach ($entries as $i => $entry) {
|
|
47
|
+
$isLast = ($i === $total - 1);
|
|
48
|
+
$connector = $isLast ? '└──' : '├──';
|
|
49
|
+
$fullPath = $dir . DIRECTORY_SEPARATOR . $entry;
|
|
50
|
+
|
|
51
|
+
if (is_dir($fullPath)) {
|
|
52
|
+
$subItems = array_filter(scandir($fullPath), fn($e) => $e !== '.' && $e !== '..');
|
|
53
|
+
$subCount = count($subItems);
|
|
54
|
+
$countStr = $subCount > 0 ? ' ' . $this->translator->get('DIR_ITEM_COUNT', ['count' => $subCount]) : '';
|
|
55
|
+
echo " │ {$connector} 📂 {$entry}/{$countStr}
|
|
56
|
+
";
|
|
57
|
+
} else {
|
|
58
|
+
$size = filesize($fullPath);
|
|
59
|
+
$sizeStr = $size > 1024 ? round($size / 1024, 1) . ' KB' : $size . ' B';
|
|
60
|
+
echo " │ {$connector} 📄 {$entry} [{$sizeStr}]
|
|
61
|
+
";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
echo " │
|
|
65
|
+
|
|
66
|
+
";
|
|
67
|
+
}
|
|
68
|
+
}
|