@artilingo/artiframe-cli 2.0.4 → 2.0.5

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.
Files changed (90) hide show
  1. package/LICENSE +660 -660
  2. package/bin/artiframe.js +0 -0
  3. package/bin/artiframe.php +0 -0
  4. package/core-stubs/app/ApiAuthControl.php +76 -0
  5. package/core-stubs/app/ApiControl.php +81 -35
  6. package/core-stubs/app/AuthControl.php +39 -0
  7. package/core-stubs/app/Database.php +36 -35
  8. package/core-stubs/app/DotEnv.php +19 -1
  9. package/core-stubs/app/ViewControl.php +47 -1
  10. package/core-stubs/bin/SQLMethod.php +261 -0
  11. package/core-stubs/bin/SystemMethod.php +115 -74
  12. package/core-stubs/bin/ViewMethod.php +19 -5
  13. package/core-stubs/docs/de.html +4325 -4347
  14. package/core-stubs/docs/en.html +4325 -4347
  15. package/core-stubs/docs/es.html +4325 -4347
  16. package/core-stubs/docs/fr.html +4325 -4347
  17. package/core-stubs/docs/tr.html +117 -46
  18. package/core-stubs/public/403.php +52 -0
  19. package/core-stubs/public/assets/css/components/header.css +174 -0
  20. package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
  21. package/core-stubs/public/assets/css/components/sidebar.css +184 -0
  22. package/core-stubs/public/assets/css/root/app.css +975 -38
  23. package/core-stubs/public/assets/css/root/root.css +64 -0
  24. package/core-stubs/public/assets/js/components/header.js +380 -0
  25. package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
  26. package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
  27. package/core-stubs/public/assets/js/root/app.js +1870 -0
  28. package/core-stubs/public/includes/footer.php +4 -5
  29. package/core-stubs/public/includes/head-auth.php +65 -0
  30. package/core-stubs/public/includes/head.php +56 -17
  31. package/core-stubs/public/includes/header.php +135 -1
  32. package/core-stubs/public/includes/mobilenav.php +75 -3
  33. package/core-stubs/public/includes/sidebar.php +186 -1
  34. package/core-stubs/public/includes/theme-modal.php +1 -0
  35. package/db-studio/debug.log +3 -0
  36. package/db-studio/index.html +1755 -0
  37. package/db-studio/launcher.html +102 -0
  38. package/db-studio/launcher.js +180 -0
  39. package/db-studio/logo.svg +22 -0
  40. package/db-studio/main.js +568 -0
  41. package/db-studio/package-lock.json +1034 -0
  42. package/db-studio/package.json +16 -0
  43. package/db-studio/preload.js +29 -0
  44. package/devops-studio/api-inspector.js +222 -0
  45. package/devops-studio/index.html +1892 -0
  46. package/devops-studio/logo.svg +22 -0
  47. package/devops-studio/main.js +67 -0
  48. package/devops-studio/make-wizard.js +635 -0
  49. package/devops-studio/package-lock.json +871 -0
  50. package/devops-studio/package.json +12 -0
  51. package/package.json +5 -2
  52. package/scripts/postinstall.js +44 -8
  53. package/server-studio/.json-404-guard +1 -0
  54. package/server-studio/index.html +283 -0
  55. package/server-studio/logo.svg +22 -0
  56. package/server-studio/main.js +133 -0
  57. package/server-studio/package-lock.json +1179 -0
  58. package/server-studio/package.json +15 -0
  59. package/server-studio/router.php +99 -0
  60. package/src/App.php +29 -0
  61. package/src/Commands/AddCommand.php +26 -9
  62. package/src/Commands/DbExportCommand.php +131 -0
  63. package/src/Commands/DbStartCommand.php +46 -0
  64. package/src/Commands/DevopsCommand.php +35 -0
  65. package/src/Commands/GoCommand.php +48 -48
  66. package/src/Commands/ListCommand.php +68 -68
  67. package/src/Commands/MakeApiCommand.php +6 -1
  68. package/src/Commands/MakeViewCommand.php +25 -2
  69. package/src/Commands/NewProjectCommand.php +16 -11
  70. package/src/Commands/OptimizeCommand.php +61 -0
  71. package/src/Commands/RemoveCommand.php +35 -7
  72. package/src/Commands/ServeCommand.php +46 -91
  73. package/src/Commands/ShowCommand.php +24 -24
  74. package/src/Commands/UpgradeCommand.php +39 -10
  75. package/stubs/make/api-switch-case.stub +1 -1
  76. package/stubs/make/auth-api-standart.stub +20 -0
  77. package/stubs/make/auth-api-switch-case.stub +38 -0
  78. package/stubs/make/auth-view.stub +26 -0
  79. package/stubs/make/class.stub +10 -2
  80. package/stubs/make/view.stub +3 -0
  81. package/stubs/service/image.stub +334 -334
  82. package/stubs/service/iyzico.stub +637 -637
  83. package/stubs/service/jwt.stub +312 -312
  84. package/stubs/service/phpmailer.stub +143 -143
  85. package/stubs/service/pusher.stub +232 -232
  86. package/stubs/service/qrcode.stub +169 -169
  87. package/stubs/service/redis.stub +361 -361
  88. package/stubs/service/s3.stub +377 -377
  89. package/stubs/service/stripe.stub +526 -526
  90. package/stubs/service/twilio.stub +361 -361
@@ -45,7 +45,12 @@ class MakeApiCommand
45
45
  return;
46
46
  }
47
47
 
48
- $stubName = 'api-' . $type . '.stub';
48
+ $stubName = 'api-' . $type . '.stub';
49
+
50
+ if (str_starts_with($target, 'auth') || str_starts_with($target, 'auth/')) {
51
+ $stubName = 'auth-' . $stubName;
52
+ }
53
+
49
54
  $stubPath = \ARTIFRAME_CLI_ROOT . '/stubs/make/' . $stubName;
50
55
 
51
56
  if (!file_exists($stubPath)) {
@@ -53,7 +53,11 @@ class MakeViewCommand
53
53
  $jsPath = $projectRoot . '/public' . $jsRelative;
54
54
 
55
55
  // Stub path
56
- $stubPath = \ARTIFRAME_CLI_ROOT . '/stubs/make/view.stub';
56
+ if (str_starts_with($subDir, 'auth') || str_starts_with($subDir, 'auth/')) {
57
+ $stubPath = \ARTIFRAME_CLI_ROOT . '/stubs/make/auth-view.stub';
58
+ } else {
59
+ $stubPath = \ARTIFRAME_CLI_ROOT . '/stubs/make/view.stub';
60
+ }
57
61
  if (!file_exists($stubPath)) {
58
62
  echo "❌ " . $this->translator->get('ERROR_STUB_NOT_FOUND', ['path' => $stubPath]) . PHP_EOL;
59
63
  echo $this->translator->get('ERROR_RUN_FROM_ROOT') . PHP_EOL;
@@ -79,7 +83,26 @@ class MakeViewCommand
79
83
 
80
84
  file_put_contents($viewPath, $content);
81
85
  file_put_contents($cssPath, "/* CSS for {$title} */\n");
82
- file_put_contents($jsPath, "/* JS for {$title} */\n");
86
+ $jsContent = <<<EOT
87
+ /* JS for {$title} */
88
+
89
+ // CSRF Token (API istekleri için zorunludur)
90
+ const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content');
91
+
92
+ /*
93
+ * Fetch API Örnek Kullanımı:
94
+ *
95
+ * fetch('/api/standart/endpoint', {
96
+ * method: 'POST',
97
+ * headers: {
98
+ * 'Content-Type': 'application/json',
99
+ * 'X-CSRF-TOKEN': csrfToken
100
+ * },
101
+ * body: JSON.stringify({ key: 'value' })
102
+ * });
103
+ */
104
+ EOT;
105
+ file_put_contents($jsPath, $jsContent . "\n");
83
106
 
84
107
  echo $this->translator->get('SUCCESS_VIEW', ['path' => $target]) . PHP_EOL;
85
108
  echo $this->translator->get('SUCCESS_CSS', ['path' => $cssRelative]) . PHP_EOL;
@@ -88,7 +88,7 @@ class NewProjectCommand
88
88
  // Toplam adım sayısını hesapla
89
89
  $coreStubs = \ARTIFRAME_CLI_ROOT . '/core-stubs';
90
90
  $stubCount = $this->countFiles($coreStubs);
91
- $dynamicCount = 14; // createDynamicFiles içindeki dosya sayısı
91
+ $dynamicCount = 12; // createDynamicFiles içindeki dosya sayısı
92
92
  $dirCount = 10; // oluşturulacak dinamik dizin sayısı
93
93
  $this->totalSteps = $stubCount + $dynamicCount + $dirCount;
94
94
 
@@ -428,7 +428,8 @@ class NewProjectCommand
428
428
  },
429
429
  "files": [
430
430
  "bin/ViewMethod.php",
431
- "bin/SystemMethod.php"
431
+ "bin/SystemMethod.php",
432
+ "bin/SQLMethod.php"
432
433
  ]
433
434
  },
434
435
  "authors": [
@@ -450,17 +451,11 @@ JSON;
450
451
  // config/app-version.php
451
452
  file_put_contents(
452
453
  $targetDir . '/config/app-version.php',
453
- $licenseHeader . "\n// APP_ENV: 0 = Canlı (Prod), 1 = Geliştirici (Debug)\ndefine('APP_ENV', 1);\ndefine('APP_VERSION', '1.0.0');\n"
454
+ $licenseHeader . "\n// APP_ENV: 0 = Canlı (Prod), 1 = Geliştirici (Debug)\ndefine('APP_ENV', 1);\ndefine('APP_VERSION', '1.0.0');\ndefine('APP_MAINTENANCE', false); // true yaparsanız sistem 503 Bakım Moduna geçer\n"
454
455
  );
455
456
  $this->tick('config/app-version.php');
456
457
 
457
- // config/central-control.php
458
- file_put_contents($targetDir . '/config/central-control.php', $licenseHeader . "\n// Central Control Configurations\n");
459
- $this->tick('config/central-control.php');
460
458
 
461
- // config/api-security.php
462
- file_put_contents($targetDir . '/config/api-security.php', $licenseHeader . "\n// API Security Rules\n");
463
- $this->tick('config/api-security.php');
464
459
 
465
460
  // .env & .env.example
466
461
  $envStub = implode("\n", [
@@ -473,8 +468,7 @@ JSON;
473
468
  "# Uygulama",
474
469
  "APP_NAME=ArtiFrame",
475
470
  "APP_URL=http://localhost",
476
- "APP_MAINTENANCE=false",
477
- "",
471
+ "",
478
472
  "# Veritabanı (MySQL / MariaDB)",
479
473
  "DB_HOST=localhost",
480
474
  "DB_USER=root",
@@ -487,6 +481,17 @@ JSON;
487
481
  "REDIS_PORT=6379",
488
482
  "REDIS_PASSWORD=",
489
483
  "REDIS_DB=0",
484
+ "",
485
+ "# ── mail (phpmailer) ──────────────────────",
486
+ "# Mailpit varsayilan ayarlari: SMTP 1025, Web UI 8025",
487
+ "MAIL_MAILER=smtp",
488
+ "MAIL_HOST=127.0.0.1",
489
+ "MAIL_PORT=1025",
490
+ "MAIL_USERNAME=",
491
+ "MAIL_PASSWORD=",
492
+ "MAIL_ENCRYPTION=",
493
+ "MAIL_FROM_ADDRESS=\"hello@example.com\"",
494
+ "MAIL_FROM_NAME=\"ArtiFrame\"",
490
495
  ]) . "\n";
491
496
  file_put_contents($targetDir . '/.env', $envStub);
492
497
  $this->tick('.env');
@@ -0,0 +1,61 @@
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+ use ArtiFrame\Cli\Services\Safeguard;
6
+
7
+ class OptimizeCommand
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
+ $envPath = $projectRoot . '/.env';
22
+ $cacheDir = $projectRoot . '/config';
23
+ $cachePath = $cacheDir . '/env-cache.php';
24
+
25
+ if (!file_exists($envPath)) {
26
+ echo "❌ .env file not found at: {$envPath}\n";
27
+ return;
28
+ }
29
+
30
+ if (!is_dir($cacheDir)) {
31
+ mkdir($cacheDir, 0755, true);
32
+ }
33
+
34
+ $lines = file($envPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
35
+ $config = [];
36
+
37
+ foreach ($lines as $line) {
38
+ $line = trim($line);
39
+ if (str_starts_with($line, '#')) continue;
40
+ if (!str_contains($line, '=')) continue;
41
+
42
+ list($name, $value) = explode('=', $line, 2);
43
+ $name = trim($name);
44
+ $value = trim(trim($value), '"\'');
45
+
46
+ // Handle booleans
47
+ if (strtolower($value) === 'true') $value = true;
48
+ elseif (strtolower($value) === 'false') $value = false;
49
+
50
+ $config[$name] = $value;
51
+ }
52
+
53
+ $export = var_export($config, true);
54
+ $phpCode = "<?php\n// Auto-generated by artiframe optimize\n// DO NOT EDIT MANUALLY\nreturn {$export};\n";
55
+
56
+ file_put_contents($cachePath, $phpCode);
57
+
58
+ echo "✅ Environment variables cached successfully at config/env-cache.php\n";
59
+ echo "⚠️ IMPORTANT: Add env-cache.php to your .gitignore if running locally.\n";
60
+ }
61
+ }
@@ -40,13 +40,24 @@ class RemoveCommand
40
40
  return;
41
41
  }
42
42
 
43
- echo "\n⚠️ " . $this->translator->get('REMOVE_CONFIRM_FILE', ['path' => $targetPath]) . " [y/N]: ";
44
- $ans = trim(fgets(STDIN));
45
- if (strtolower($ans) !== 'y') {
46
- echo "Abort.\n";
43
+ // ─── Path Traversal Ön Kontrolü ──────────────────────────
44
+ $resolvedEarly = realpath($targetPath);
45
+ $realProjectRoot = realpath($projectRoot);
46
+ if ($resolvedEarly && $realProjectRoot && !str_starts_with($resolvedEarly, $realProjectRoot . '/')) {
47
+ echo "❌ Güvenlik ihlali: Hedef dosya proje dizini dışında!\n";
47
48
  return;
48
49
  }
49
50
 
51
+ $force = in_array('--force', $args) || in_array('-y', $args);
52
+ if (!$force) {
53
+ echo "\n⚠️ " . $this->translator->get('REMOVE_CONFIRM_FILE', ['path' => $targetPath]) . " [y/N]: ";
54
+ $ans = trim(fgets(STDIN));
55
+ if (strtolower($ans) !== 'y') {
56
+ echo "Abort.\n";
57
+ return;
58
+ }
59
+ }
60
+
50
61
  $targetPath = realpath($targetPath);
51
62
  $normalizedPath = str_replace('\\', '/', $targetPath);
52
63
  $isView = strpos($normalizedPath, '/public/') !== false && strpos($normalizedPath, '/public/api/') === false && strpos($normalizedPath, '/public/assets/') === false;
@@ -75,8 +86,15 @@ class RemoveCommand
75
86
  }
76
87
 
77
88
  if (!empty($assetsFound)) {
78
- echo "\n⚠️ " . $this->translator->get('REMOVE_CONFIRM_ASSETS') . " [y/N]: ";
79
- $ansAssets = trim(fgets(STDIN));
89
+ if (in_array('--no-assets', $args)) {
90
+ $ansAssets = 'n';
91
+ } elseif (!$force) {
92
+ echo "\n⚠️ " . $this->translator->get('REMOVE_CONFIRM_ASSETS') . " [y/N]: ";
93
+ $ansAssets = trim(fgets(STDIN));
94
+ } else {
95
+ $ansAssets = 'y';
96
+ }
97
+
80
98
  if (strtolower($ansAssets) === 'y') {
81
99
  foreach ($assetsFound as $a) {
82
100
  unlink($a);
@@ -97,6 +115,16 @@ class RemoveCommand
97
115
  echo " -> " . $usage['file'] . " (Lines: " . implode(', ', $usage['lines']) . ")\n";
98
116
  }
99
117
  echo "\n📌 " . $this->translator->get('REMOVE_API_WARNING') . "\n";
118
+
119
+ // --force olsa bile kullanım tespit edilirse --force-class olmadan iptal et
120
+ if (!in_array('--force-class', $args)) {
121
+ echo "\n❓ Yine de silmek istiyor musunuz? [y/N]: ";
122
+ $ansClass = trim(fgets(STDIN));
123
+ if (strtolower($ansClass) !== 'y') {
124
+ echo "Abort.\n";
125
+ return;
126
+ }
127
+ }
100
128
  }
101
129
  }
102
130
  }
@@ -130,4 +158,4 @@ class RemoveCommand
130
158
  }
131
159
  return $usages;
132
160
  }
133
- }
161
+ }
@@ -1,91 +1,46 @@
1
- <?php
2
- namespace ArtiFrame\Cli\Commands;
3
-
4
- use ArtiFrame\Cli\Services\Translator;
5
-
6
- class ServeCommand
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
- $projectRoot = $safeguard->getProjectRoot();
19
- $publicDir = $projectRoot . '/public';
20
-
21
- if (!is_dir($publicDir) || !file_exists($publicDir . '/index.php')) {
22
- echo "
23
- ❌ " . $this->translator->get('SERVE_NOT_PROJECT') . "
24
-
25
- ";
26
- return;
27
- }
28
-
29
- $host = 'localhost';
30
- $port = '8000';
31
-
32
- if (isset($args[0]) && is_numeric($args[0])) {
33
- $port = $args[0];
34
- }
35
-
36
- // Detect Local IP
37
- $localIp = 'Unknown';
38
- $sock = @socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
39
- if ($sock) {
40
- @socket_connect($sock, "8.8.8.8", 53);
41
- @socket_getsockname($sock, $localIp);
42
- @socket_close($sock);
43
- }
44
- if ($localIp === 'Unknown' || $localIp === '127.0.0.1' || $localIp === '::1' || empty($localIp)) {
45
- $localIp = getHostByName(getHostName());
46
- }
47
-
48
- $localUrl = "http://localhost:{$port}";
49
- $networkUrl = "http://{$localIp}:{$port}";
50
-
51
- echo "
52
- 🚀 " . $this->translator->get('SERVE_STARTING', ['url' => "0.0.0.0:{$port}"]) . "
53
- ";
54
- echo " " . $this->translator->get('SERVE_STOP_INFO') . "
55
-
56
- Local: {$localUrl}";
57
-
58
- if ($localIp && $localIp !== '127.0.0.1' && $localIp !== 'Unknown') {
59
- echo "
60
- Network: {$networkUrl}";
61
- }
62
- echo "\n\n";
63
-
64
- $os = PHP_OS_FAMILY;
65
-
66
- // Command to start PHP built-in server on all interfaces (0.0.0.0)
67
- $phpCmd = sprintf('php -S 0.0.0.0:%s -t %s', $port, escapeshellarg($publicDir));
68
-
69
- if ($os === 'Windows') {
70
- // Open Browser
71
- pclose(popen("start {$localUrl}", "r"));
72
- // Start Server in new visible CMD window
73
- pclose(popen("start \"ArtiFrame Server\" cmd /k \"{$phpCmd}\"", "r"));
74
- } elseif ($os === 'Darwin') {
75
- // Open Browser
76
- exec("open {$localUrl} > /dev/null 2>&1 &");
77
- // Start Server in new Terminal window
78
- $appleScript = 'tell app "Terminal" to do script "' . escapeshellcmd($phpCmd) . '"';
79
- exec("osascript -e " . escapeshellarg($appleScript));
80
- } else {
81
- // Open Browser
82
- exec("xdg-open {$localUrl} > /dev/null 2>&1 &");
83
- // Linux: Try common terminals, fallback to background process
84
- $linuxCmd = sprintf(
85
- 'gnome-terminal -- bash -c "%s" || xterm -e "%s" || konsole -e "%s" || %s > /dev/null 2>&1 &',
86
- $phpCmd, $phpCmd, $phpCmd, $phpCmd
87
- );
88
- exec($linuxCmd);
89
- }
90
- }
91
- }
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+
6
+ class ServeCommand
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
+ $projectRoot = $safeguard->getProjectRoot();
19
+ $publicDir = $projectRoot . '/public';
20
+
21
+ if (!is_dir($publicDir) || !file_exists($publicDir . '/index.php')) {
22
+ echo "\n ❌ " . $this->translator->get('SERVE_NOT_PROJECT') . "\n\n";
23
+ return;
24
+ }
25
+
26
+ $port = '9002';
27
+ if (isset($args[0]) && is_numeric($args[0])) {
28
+ $port = $args[0];
29
+ }
30
+
31
+ echo "\n 🚀 ArtiFrame Server Studio başlatılıyor...\n";
32
+
33
+ $serverStudioPath = dirname(__DIR__, 2) . '/server-studio';
34
+ $os = PHP_OS_FAMILY;
35
+
36
+ $cmd = sprintf('npm run start --prefix %s -- %s %s', escapeshellarg($serverStudioPath), escapeshellarg($projectRoot), escapeshellarg($port));
37
+
38
+ if ($os === 'Windows') {
39
+ pclose(popen("start \"ArtiFrame Server Studio\" cmd /c \"{$cmd}\"", "r"));
40
+ } else {
41
+ exec("{$cmd} > /dev/null 2>&1 &");
42
+ }
43
+
44
+ echo " ✅ Server Studio arka planda açıldı. Gelişmiş arayüzü kontrol edin.\n\n";
45
+ }
46
+ }
@@ -1,24 +1,24 @@
1
- <?php
2
- namespace ArtiFrame\Cli\Commands;
3
-
4
- use ArtiFrame\Cli\Services\Translator;
5
-
6
- class ShowCommand
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
- echo "
18
- 📍 " . $this->translator->get('SHOW_CURRENT_DIR') . "
19
- ";
20
- echo " " . getcwd() . "
21
-
22
- ";
23
- }
24
- }
1
+ <?php
2
+ namespace ArtiFrame\Cli\Commands;
3
+
4
+ use ArtiFrame\Cli\Services\Translator;
5
+
6
+ class ShowCommand
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
+ echo "
18
+ 📍 " . $this->translator->get('SHOW_CURRENT_DIR') . "
19
+ ";
20
+ echo " " . getcwd() . "
21
+
22
+ ";
23
+ }
24
+ }
@@ -69,17 +69,14 @@ class UpgradeCommand
69
69
  // ── KURAL 3 & ANA İŞLEM: KOPYALAMA ──────────────────────────────
70
70
  $this->copyDirectory(\ARTIFRAME_CLI_ROOT . '/core-stubs/app', $targetDir . '/app');
71
71
  $this->copyDirectory(\ARTIFRAME_CLI_ROOT . '/core-stubs/bin', $targetDir . '/bin');
72
-
73
- // Docs
74
- $docsSource = \ARTIFRAME_CLI_ROOT . '/core-stubs/docs';
75
- $docsTarget = $targetDir . '/public/docs';
76
- if (is_dir($docsSource)) {
77
- if (!is_dir($docsTarget)) {
78
- mkdir($docsTarget, 0755, true);
79
- }
80
- $this->copyDirectory($docsSource, $docsTarget);
72
+
73
+ // Public (Eksik layout/UI dosyalarini tamamla ama var olanlari ezme)
74
+ if (is_dir(\ARTIFRAME_CLI_ROOT . '/core-stubs/public')) {
75
+ $this->copyDirectorySafe(\ARTIFRAME_CLI_ROOT . '/core-stubs/public', $targetDir . '/public');
81
76
  }
82
77
 
78
+
79
+
83
80
  // ── KURAL 4: SERVICE STUB EZİLMESİ ──────────────────────────────
84
81
  $servicesDir = $targetDir . '/src/Service';
85
82
  $stubsServicesDir = \ARTIFRAME_CLI_ROOT . '/stubs/services';
@@ -206,4 +203,36 @@ class UpgradeCommand
206
203
  }
207
204
  return $functions;
208
205
  }
209
- }
206
+
207
+ private function copyDirectorySafe(string $source, string $target): void
208
+ {
209
+ if (!is_dir($target)) {
210
+ mkdir($target, 0755, true);
211
+ }
212
+
213
+ $dir = opendir($source);
214
+ while (($file = readdir($dir)) !== false) {
215
+ if ($file === '.' || $file === '..') {
216
+ continue;
217
+ }
218
+ $srcFile = $source . '/' . $file;
219
+ $tgtFile = $target . '/' . $file;
220
+
221
+ if (is_dir($srcFile)) {
222
+ $this->copyDirectorySafe($srcFile, $tgtFile);
223
+ } else {
224
+ if (!file_exists($tgtFile)) {
225
+ copy($srcFile, $tgtFile);
226
+
227
+ $normalizedTarget = str_replace('\\', '/', $tgtFile);
228
+ $normalizedCwd = str_replace('\\', '/', getcwd()) . '/';
229
+ $relativePath = str_replace($normalizedCwd, '', $normalizedTarget);
230
+
231
+ $this->changes['added'][] = $relativePath;
232
+ }
233
+ }
234
+ }
235
+ closedir($dir);
236
+ }
237
+
238
+ }
@@ -14,7 +14,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/ApiControl.php';
14
14
 
15
15
  use Bin\SystemMethod;
16
16
 
17
- $action = sanitizeString($_POST['action'] ?? '');
17
+ $action = stripHtml($_POST['action'] ?? '');
18
18
 
19
19
  switch ($action) {
20
20
  case 'create':
@@ -0,0 +1,20 @@
1
+ <?php
2
+ /**
3
+ * ArtiFrame Core Engine
4
+ *
5
+ * @package ArtiFrame
6
+ * @author Artilingo
7
+ * @license AGPLv3 (Attribution-ShareAlike Required)
8
+ */
9
+
10
+ // İzin verilen HTTP metodları (Örn: GET, POST, PUT, DELETE)
11
+ $allowedMethods = ['POST'];
12
+
13
+ require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/ApiAuthControl.php';
14
+
15
+ use Bin\SystemMethod;
16
+
17
+ // API İş Mantığı (Business Logic) Başlangıcı
18
+ // ...
19
+
20
+ jsonResponse(['status' => 'success', 'message' => 'İşlem başarılı.'], 200);
@@ -0,0 +1,38 @@
1
+ <?php
2
+ /**
3
+ * ArtiFrame Core Engine
4
+ *
5
+ * @package ArtiFrame
6
+ * @author Artilingo
7
+ * @license AGPLv3 (Attribution-ShareAlike Required)
8
+ */
9
+
10
+ // İzin verilen HTTP metodları (Örn: GET, POST, PUT, DELETE)
11
+ $allowedMethods = ['POST'];
12
+
13
+ require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/ApiAuthControl.php';
14
+
15
+ use Bin\SystemMethod;
16
+
17
+ $action = stripHtml($_POST['action'] ?? '');
18
+
19
+ switch ($action) {
20
+ case 'create':
21
+ // TODO: Oluşturma işlemleri
22
+ jsonResponse(['status' => 'success', 'message' => 'Başarıyla oluşturuldu.'], 200);
23
+ break;
24
+
25
+ case 'update':
26
+ // TODO: Güncelleme işlemleri
27
+ jsonResponse(['status' => 'success', 'message' => 'Başarıyla güncellendi.'], 200);
28
+ break;
29
+
30
+ case 'delete':
31
+ // TODO: Silme işlemleri
32
+ jsonResponse(['status' => 'success', 'message' => 'Başarıyla silindi.'], 200);
33
+ break;
34
+
35
+ default:
36
+ jsonResponse(['status' => 'error', 'message' => 'Geçersiz veya eksik action parametresi.'], 400);
37
+ break;
38
+ }
@@ -0,0 +1,26 @@
1
+ <?php
2
+ // Auth kalkanı (Sadece giriş yapmamış kullanıcılar görebilir)
3
+ require_once $_SERVER['DOCUMENT_ROOT'] . '/../app/AuthControl.php';
4
+ use Bin\ViewMethod;
5
+ ?>
6
+ <!DOCTYPE html>
7
+ <html lang="{{LANG}}" data-theme="default" data-mode="light">
8
+ <head>
9
+ <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/head-auth.php'; ?>
10
+
11
+ <title>{{VIEW_TITLE}}</title>
12
+
13
+ <!-- View-Specific Assets with Cache-Busting -->
14
+ <link rel="stylesheet" href="{{CSS_PATH}}?v=<?= APP_VERSION ?>">
15
+ <script src="{{JS_PATH}}?v=<?= APP_VERSION ?>" defer></script>
16
+ </head>
17
+ <body>
18
+ <main class="auth-wrapper">
19
+ <div class="auth-container">
20
+ <h1>{{VIEW_TITLE}}</h1>
21
+ <!-- Auth form content starts here -->
22
+
23
+ </div>
24
+ </main>
25
+ </body>
26
+ </html>
@@ -15,11 +15,19 @@
15
15
  namespace {{NAMESPACE}};
16
16
 
17
17
  use Bin\SystemMethod;
18
+ use App\Database;
19
+ use PDO;
18
20
 
19
21
  class {{CLASS_NAME}}
20
22
  {
23
+ /**
24
+ * @var PDO $db Veritabanı bağlantısı (Singleton)
25
+ */
26
+ private PDO $db;
27
+
21
28
  public function __construct()
22
29
  {
23
- // Constructor logic
30
+ // Singleton üzerinden hazır PDO bağlantısını değişkene ata
31
+ $this->db = Database::getInstance();
24
32
  }
25
- }
33
+ }
@@ -24,6 +24,9 @@ use Bin\ViewMethod;
24
24
 
25
25
  </main>
26
26
 
27
+ <!-- Mobile Navigation -->
28
+ <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/mobilenav.php'; ?>
29
+
27
30
  <!-- Footer -->
28
31
  <?php require_once $_SERVER['DOCUMENT_ROOT'] . '/includes/footer.php'; ?>
29
32
  </body>