@artilingo/artiframe-cli 1.3.0 → 2.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/core-stubs/bin/SystemMethod.php +600 -521
- package/core-stubs/bin/ViewMethod.php +591 -393
- package/core-stubs/docs/de.html +853 -1172
- package/core-stubs/docs/en.html +585 -904
- package/core-stubs/docs/es.html +934 -1253
- package/core-stubs/docs/fr.html +913 -1232
- package/core-stubs/docs/tr.html +4212 -5021
- package/package.json +1 -1
- package/src/App.php +38 -0
- package/src/Commands/AddCommand.php +1 -1
- package/src/Commands/AuthCommand.php +219 -0
- package/src/Commands/IssuesCommand.php +174 -0
- package/src/Commands/ListCommand.php +2 -1
- package/src/Commands/MakeApiCommand.php +1 -1
- package/src/Commands/MakeClassCommand.php +1 -1
- package/src/Commands/MakeViewCommand.php +1 -1
- package/src/Commands/NewProjectCommand.php +37 -25
- package/src/Commands/RemoveCommand.php +21 -10
- package/src/Commands/ServeCommand.php +29 -9
- package/src/Commands/SuggestCommand.php +143 -0
- package/src/Commands/TableCommand.php +2 -1
- package/src/Commands/UpgradeCommand.php +209 -0
- package/src/Commands/VersionCommand.php +2 -1
- package/src/Lang/de.php +9 -1
- package/src/Lang/en.php +8 -0
- package/src/Lang/es.php +9 -1
- package/src/Lang/fr.php +8 -0
- package/src/Lang/tr.php +10 -2
- package/src/Services/Safeguard.php +25 -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/sentry.stub +76 -106
- package/stubs/service/stripe.stub +526 -526
- package/stubs/service/twilio.stub +361 -361
- package/core-stubs/app/R2Manager.php +0 -130
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
<?php
|
|
2
2
|
namespace ArtiFrame\Cli\Commands;
|
|
3
3
|
|
|
4
4
|
use ArtiFrame\Cli\Services\Translator;
|
|
@@ -24,7 +24,7 @@ class RemoveCommand
|
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
$projectRoot =
|
|
27
|
+
$projectRoot = $this->safeguard->getProjectRoot();
|
|
28
28
|
|
|
29
29
|
$targetPath = $target;
|
|
30
30
|
if (!file_exists($targetPath)) {
|
|
@@ -52,15 +52,26 @@ class RemoveCommand
|
|
|
52
52
|
$isClass = strpos($normalizedPath, '/src/') !== false || strpos($normalizedPath, '/app/') !== false;
|
|
53
53
|
|
|
54
54
|
if ($isView) {
|
|
55
|
-
$relPath = str_replace(str_replace('\\', '/', $projectRoot) . '/public/', '', $normalizedPath);
|
|
56
|
-
$relPath = preg_replace('/\.php$/', '', $relPath);
|
|
57
|
-
|
|
58
|
-
$cssPath = $projectRoot . '/public/assets/css/' . $relPath . '.css';
|
|
59
|
-
$jsPath = $projectRoot . '/public/assets/js/' . $relPath . '.js';
|
|
60
|
-
|
|
61
55
|
$assetsFound = [];
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
$content = file_get_contents($targetPath);
|
|
57
|
+
|
|
58
|
+
// Extract CSS path from href="/assets/css/...css"
|
|
59
|
+
if (preg_match('/href="(\/assets\/css\/[^"]+\.css)(?:\?[^"]*)?"/i', $content, $matches)) {
|
|
60
|
+
$cssRelative = ltrim($matches[1], '/');
|
|
61
|
+
$cssPath = rtrim($projectRoot, '/') . '/public/' . $cssRelative;
|
|
62
|
+
if (file_exists($cssPath)) {
|
|
63
|
+
$assetsFound[] = $cssPath;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Extract JS path from src="/assets/js/...js"
|
|
68
|
+
if (preg_match('/src="(\/assets\/js\/[^"]+\.js)(?:\?[^"]*)?"/i', $content, $matches)) {
|
|
69
|
+
$jsRelative = ltrim($matches[1], '/');
|
|
70
|
+
$jsPath = rtrim($projectRoot, '/') . '/public/' . $jsRelative;
|
|
71
|
+
if (file_exists($jsPath)) {
|
|
72
|
+
$assetsFound[] = $jsPath;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
64
75
|
|
|
65
76
|
if (!empty($assetsFound)) {
|
|
66
77
|
echo "\n⚠️ " . $this->translator->get('REMOVE_CONFIRM_ASSETS') . " [y/N]: ";
|
|
@@ -14,7 +14,8 @@ class ServeCommand
|
|
|
14
14
|
|
|
15
15
|
public function execute(array $args): void
|
|
16
16
|
{
|
|
17
|
-
$
|
|
17
|
+
$safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
|
|
18
|
+
$projectRoot = $safeguard->getProjectRoot();
|
|
18
19
|
$publicDir = $projectRoot . '/public';
|
|
19
20
|
|
|
20
21
|
if (!is_dir($publicDir) || !file_exists($publicDir . '/index.php')) {
|
|
@@ -32,34 +33,53 @@ class ServeCommand
|
|
|
32
33
|
$port = $args[0];
|
|
33
34
|
}
|
|
34
35
|
|
|
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}";
|
|
36
50
|
|
|
37
51
|
echo "
|
|
38
|
-
🚀 " . $this->translator->get('SERVE_STARTING', ['url' => $
|
|
52
|
+
🚀 " . $this->translator->get('SERVE_STARTING', ['url' => "0.0.0.0:{$port}"]) . "
|
|
39
53
|
";
|
|
40
54
|
echo " " . $this->translator->get('SERVE_STOP_INFO') . "
|
|
41
55
|
|
|
42
|
-
";
|
|
56
|
+
Local: {$localUrl}";
|
|
57
|
+
|
|
58
|
+
if ($localIp && $localIp !== '127.0.0.1' && $localIp !== 'Unknown') {
|
|
59
|
+
echo "
|
|
60
|
+
Network: {$networkUrl}";
|
|
61
|
+
}
|
|
62
|
+
echo "\n\n";
|
|
43
63
|
|
|
44
64
|
$os = PHP_OS_FAMILY;
|
|
45
65
|
|
|
46
|
-
// Command to start PHP built-in server
|
|
47
|
-
$phpCmd = sprintf('php -S
|
|
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));
|
|
48
68
|
|
|
49
69
|
if ($os === 'Windows') {
|
|
50
70
|
// Open Browser
|
|
51
|
-
pclose(popen("start {$
|
|
71
|
+
pclose(popen("start {$localUrl}", "r"));
|
|
52
72
|
// Start Server in new visible CMD window
|
|
53
73
|
pclose(popen("start \"ArtiFrame Server\" cmd /k \"{$phpCmd}\"", "r"));
|
|
54
74
|
} elseif ($os === 'Darwin') {
|
|
55
75
|
// Open Browser
|
|
56
|
-
exec("open {$
|
|
76
|
+
exec("open {$localUrl} > /dev/null 2>&1 &");
|
|
57
77
|
// Start Server in new Terminal window
|
|
58
78
|
$appleScript = 'tell app "Terminal" to do script "' . escapeshellcmd($phpCmd) . '"';
|
|
59
79
|
exec("osascript -e " . escapeshellarg($appleScript));
|
|
60
80
|
} else {
|
|
61
81
|
// Open Browser
|
|
62
|
-
exec("xdg-open {$
|
|
82
|
+
exec("xdg-open {$localUrl} > /dev/null 2>&1 &");
|
|
63
83
|
// Linux: Try common terminals, fallback to background process
|
|
64
84
|
$linuxCmd = sprintf(
|
|
65
85
|
'gnome-terminal -- bash -c "%s" || xterm -e "%s" || konsole -e "%s" || %s > /dev/null 2>&1 &',
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
|
|
6
|
+
class SuggestCommand
|
|
7
|
+
{
|
|
8
|
+
private Translator $translator;
|
|
9
|
+
const API_ENDPOINT = 'https://api.artilingo.com/artiframe/v1/suggest.php';
|
|
10
|
+
|
|
11
|
+
public function __construct(Translator $translator)
|
|
12
|
+
{
|
|
13
|
+
$this->translator = $translator;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public function execute(array $args): void
|
|
17
|
+
{
|
|
18
|
+
$home = getenv('HOME') ?: getenv('USERPROFILE');
|
|
19
|
+
$configFile = $home . \DIRECTORY_SEPARATOR . '.artiframe' . \DIRECTORY_SEPARATOR . 'config.json';
|
|
20
|
+
|
|
21
|
+
if (!file_exists($configFile)) {
|
|
22
|
+
echo "\033[1;31m[-] Not authenticated. Please run 'artiframe auth' first.\033[0m" . PHP_EOL;
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
$config = json_decode(file_get_contents($configFile), true);
|
|
27
|
+
if (!$config || !isset($config['github_token'])) {
|
|
28
|
+
echo "\033[1;31m[-] Not authenticated. Please run 'artiframe auth' first.\033[0m" . PHP_EOL;
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
$token = $config['github_token'];
|
|
33
|
+
$username = $config['github_user'] ?? 'User';
|
|
34
|
+
|
|
35
|
+
echo "\033[1;36mHello @{$username}, welcome to ArtiFrame Issue Submitter!\033[0m" . PHP_EOL;
|
|
36
|
+
echo PHP_EOL;
|
|
37
|
+
|
|
38
|
+
// 1. Ask for Category
|
|
39
|
+
$categories = [
|
|
40
|
+
'1' => 'Feature Request',
|
|
41
|
+
'2' => 'Bug Report',
|
|
42
|
+
'3' => 'Helper Suggestion'
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
echo "Please select a Category:" . PHP_EOL;
|
|
46
|
+
echo " [1] Feature Request" . PHP_EOL;
|
|
47
|
+
echo " [2] Bug Report" . PHP_EOL;
|
|
48
|
+
echo " [3] Helper Suggestion" . PHP_EOL;
|
|
49
|
+
|
|
50
|
+
$categoryId = null;
|
|
51
|
+
while (true) {
|
|
52
|
+
echo "Select [1-3]: ";
|
|
53
|
+
$input = trim(fgets(STDIN));
|
|
54
|
+
if (isset($categories[$input])) {
|
|
55
|
+
$categoryId = $input;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
echo "\033[1;31mInvalid selection.\033[0m" . PHP_EOL;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
$category = $categories[$categoryId];
|
|
62
|
+
|
|
63
|
+
// 2. Ask for Title
|
|
64
|
+
echo PHP_EOL;
|
|
65
|
+
$title = '';
|
|
66
|
+
while (true) {
|
|
67
|
+
echo "Title (Short summary, max 120 chars): ";
|
|
68
|
+
$title = trim(fgets(STDIN));
|
|
69
|
+
if (strlen($title) === 0) {
|
|
70
|
+
echo "\033[1;31mTitle cannot be empty.\033[0m" . PHP_EOL;
|
|
71
|
+
} elseif (strlen($title) > 120) {
|
|
72
|
+
echo "\033[1;31mTitle is too long. Max 120 chars.\033[0m" . PHP_EOL;
|
|
73
|
+
} else {
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 3. Ask for Description
|
|
79
|
+
echo PHP_EOL;
|
|
80
|
+
echo "Description (Detailed explanation or code sample):" . PHP_EOL;
|
|
81
|
+
echo "\033[1;33m(Type 'END' on a new line and press Enter to finish)\033[0m" . PHP_EOL;
|
|
82
|
+
|
|
83
|
+
$bodyLines = [];
|
|
84
|
+
while (true) {
|
|
85
|
+
$line = fgets(STDIN);
|
|
86
|
+
if ($line === false || trim(strtoupper($line)) === 'END') {
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
$bodyLines[] = rtrim($line, "\r\n");
|
|
90
|
+
}
|
|
91
|
+
$body = implode(PHP_EOL, $bodyLines);
|
|
92
|
+
|
|
93
|
+
if (empty(trim($body))) {
|
|
94
|
+
echo "\033[1;31m[-] Description cannot be empty. Aborting.\033[0m" . PHP_EOL;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// 4. Send Payload
|
|
99
|
+
echo PHP_EOL . "\033[1;36mSubmitting to ArtiFrame...\033[0m" . PHP_EOL;
|
|
100
|
+
|
|
101
|
+
$payload = json_encode([
|
|
102
|
+
'token' => $token,
|
|
103
|
+
'category' => $category,
|
|
104
|
+
'title' => $title,
|
|
105
|
+
'body' => $body
|
|
106
|
+
]);
|
|
107
|
+
|
|
108
|
+
$ch = curl_init(self::API_ENDPOINT);
|
|
109
|
+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
110
|
+
curl_setopt($ch, CURLOPT_POST, true);
|
|
111
|
+
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
|
|
112
|
+
curl_setopt($ch, CURLOPT_HTTPHEADER, [
|
|
113
|
+
'Content-Type: application/json',
|
|
114
|
+
'Accept: application/json'
|
|
115
|
+
]);
|
|
116
|
+
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
117
|
+
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
118
|
+
curl_setopt($ch, CURLOPT_USERAGENT, 'ArtiFrame-CLI');
|
|
119
|
+
|
|
120
|
+
$response = curl_exec($ch);
|
|
121
|
+
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
122
|
+
curl_close($ch);
|
|
123
|
+
|
|
124
|
+
if ($response) {
|
|
125
|
+
$data = json_decode($response, true);
|
|
126
|
+
if ($httpCode === 200 && isset($data['status']) && $data['status'] === 'success') {
|
|
127
|
+
echo "\033[1;32m🎉 Issue successfully created!\033[0m" . PHP_EOL;
|
|
128
|
+
echo "URL: " . ($data['issue_url'] ?? 'N/A') . PHP_EOL;
|
|
129
|
+
} else {
|
|
130
|
+
if ($data && isset($data['message'])) {
|
|
131
|
+
echo "\033[1;31m[-] Server Error: " . $data['message'] . "\033[0m" . PHP_EOL;
|
|
132
|
+
} else {
|
|
133
|
+
echo "\033[1;31m[-] Server Error: Unknown response format.\033[0m" . PHP_EOL;
|
|
134
|
+
echo "HTTP Code: " . $httpCode . PHP_EOL;
|
|
135
|
+
echo "Raw Response: " . substr($response, 0, 300) . PHP_EOL;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
} else {
|
|
139
|
+
echo "\033[1;31m[-] Failed to communicate with the server.\033[0m" . PHP_EOL;
|
|
140
|
+
echo "cURL Error: " . curl_error($ch) . PHP_EOL;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -69,7 +69,8 @@ class TableCommand
|
|
|
69
69
|
return;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
$
|
|
72
|
+
$safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
|
|
73
|
+
$schemaPath = $safeguard->getProjectRoot() . '/schema.sql';
|
|
73
74
|
|
|
74
75
|
if (!file_exists($schemaPath)) {
|
|
75
76
|
file_put_contents($schemaPath, "-- ArtiFrame DB Schema\n-- Created: " . date('Y-m-d') . "\n");
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
namespace ArtiFrame\Cli\Commands;
|
|
3
|
+
|
|
4
|
+
use ArtiFrame\Cli\Services\Translator;
|
|
5
|
+
|
|
6
|
+
class UpgradeCommand
|
|
7
|
+
{
|
|
8
|
+
private Translator $translator;
|
|
9
|
+
private array $changes = [
|
|
10
|
+
'added' => [],
|
|
11
|
+
'modified' => []
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
public function __construct(Translator $translator)
|
|
15
|
+
{
|
|
16
|
+
$this->translator = $translator;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public function execute(array $args): void
|
|
20
|
+
{
|
|
21
|
+
$targetDir = getcwd();
|
|
22
|
+
|
|
23
|
+
if (!file_exists($targetDir . '/composer.json') || !is_dir($targetDir . '/app') || !is_dir($targetDir . '/bin')) {
|
|
24
|
+
echo "❌ " . $this->translator->get('ERROR_RUN_FROM_ROOT') . PHP_EOL;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ── KURAL 1: INDEX.PHP KORUMASI ────────────────────────────────
|
|
29
|
+
$indexFile = $targetDir . '/public/index.php';
|
|
30
|
+
if (file_exists($indexFile)) {
|
|
31
|
+
$indexContent = file_get_contents($indexFile);
|
|
32
|
+
if (strpos($indexContent, 'routeLink(') === false) {
|
|
33
|
+
echo PHP_EOL . "❌ " . $this->translator->get('UPGRADE_INDEX_ABORT') . PHP_EOL;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ── KURAL 2: ÇEKİRDEK (BIN) DEĞİŞİKLİK KONTROLÜ ────────────────
|
|
39
|
+
$coreStubsBinDir = \ARTIFRAME_CLI_ROOT . '/core-stubs/bin';
|
|
40
|
+
$projectBinDir = $targetDir . '/bin';
|
|
41
|
+
|
|
42
|
+
$isCoreModified = false;
|
|
43
|
+
$filesToCheck = ['SystemMethod.php', 'ViewMethod.php'];
|
|
44
|
+
|
|
45
|
+
foreach ($filesToCheck as $file) {
|
|
46
|
+
$stubPath = $coreStubsBinDir . '/' . $file;
|
|
47
|
+
$projPath = $projectBinDir . '/' . $file;
|
|
48
|
+
|
|
49
|
+
if (file_exists($stubPath) && file_exists($projPath)) {
|
|
50
|
+
if (md5_file($stubPath) !== md5_file($projPath)) {
|
|
51
|
+
$isCoreModified = true;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if ($isCoreModified) {
|
|
58
|
+
echo PHP_EOL . "⚠️ " . $this->translator->get('UPGRADE_CORE_WARNING') . PHP_EOL;
|
|
59
|
+
// The prompt asks to press Enter to continue.
|
|
60
|
+
$choice = trim(fgets(STDIN));
|
|
61
|
+
if (strtolower($choice) === 'n' || strtolower($choice) === 'h') {
|
|
62
|
+
echo $this->translator->get('ABORTED') . PHP_EOL;
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
echo PHP_EOL . "🚀 " . $this->translator->get('PHASE_COPYING') . PHP_EOL;
|
|
68
|
+
|
|
69
|
+
// ── KURAL 3 & ANA İŞLEM: KOPYALAMA ──────────────────────────────
|
|
70
|
+
$this->copyDirectory(\ARTIFRAME_CLI_ROOT . '/core-stubs/app', $targetDir . '/app');
|
|
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);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ── KURAL 4: SERVICE STUB EZİLMESİ ──────────────────────────────
|
|
84
|
+
$servicesDir = $targetDir . '/src/Service';
|
|
85
|
+
$stubsServicesDir = \ARTIFRAME_CLI_ROOT . '/stubs/services';
|
|
86
|
+
|
|
87
|
+
if (is_dir($servicesDir) && is_dir($stubsServicesDir)) {
|
|
88
|
+
$iterator = new \DirectoryIterator($servicesDir);
|
|
89
|
+
foreach ($iterator as $fileinfo) {
|
|
90
|
+
if ($fileinfo->isFile() && $fileinfo->getExtension() === 'php') {
|
|
91
|
+
$filename = $fileinfo->getFilename();
|
|
92
|
+
|
|
93
|
+
$stubIterator = new \DirectoryIterator($stubsServicesDir);
|
|
94
|
+
foreach ($stubIterator as $stubInfo) {
|
|
95
|
+
if ($stubInfo->isFile() && $stubInfo->getExtension() === 'stub') {
|
|
96
|
+
$stubName = $stubInfo->getBasename('.stub');
|
|
97
|
+
$expectedServiceName = ucfirst($stubName) . 'Service.php';
|
|
98
|
+
|
|
99
|
+
if ($filename === $expectedServiceName) {
|
|
100
|
+
$oldContent = file_get_contents($fileinfo->getPathname());
|
|
101
|
+
$content = file_get_contents($stubInfo->getPathname());
|
|
102
|
+
if (md5($oldContent) !== md5($content)) {
|
|
103
|
+
$oldFunctions = $this->getFunctionsFromFile($fileinfo->getPathname());
|
|
104
|
+
$newFunctions = $this->getFunctionsFromFile($stubInfo->getPathname());
|
|
105
|
+
$addedFunctions = array_values(array_diff($newFunctions, $oldFunctions));
|
|
106
|
+
|
|
107
|
+
file_put_contents($fileinfo->getPathname(), $content);
|
|
108
|
+
$this->changes['modified']['src/Service/' . $filename] = [
|
|
109
|
+
'added_functions' => $addedFunctions
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (empty($this->changes['added']) && empty($this->changes['modified'])) {
|
|
120
|
+
echo PHP_EOL . "✅ " . $this->translator->get('UPGRADE_SUCCESS') . " (Sistem zaten güncel)" . PHP_EOL . PHP_EOL;
|
|
121
|
+
} else {
|
|
122
|
+
echo PHP_EOL . "✅ " . $this->translator->get('UPGRADE_SUCCESS') . PHP_EOL . PHP_EOL;
|
|
123
|
+
|
|
124
|
+
echo "📊 Değişiklik Raporu:" . PHP_EOL;
|
|
125
|
+
echo str_repeat('-', 40) . PHP_EOL;
|
|
126
|
+
|
|
127
|
+
if (!empty($this->changes['added'])) {
|
|
128
|
+
echo "\e[32m[EKLENDİ]\e[0m" . PHP_EOL;
|
|
129
|
+
foreach ($this->changes['added'] as $add) {
|
|
130
|
+
echo " + $add" . PHP_EOL;
|
|
131
|
+
}
|
|
132
|
+
echo PHP_EOL;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!empty($this->changes['modified'])) {
|
|
136
|
+
echo "\e[33m[GÜNCELLENDİ]\e[0m" . PHP_EOL;
|
|
137
|
+
foreach ($this->changes['modified'] as $mod => $details) {
|
|
138
|
+
echo " ~ $mod" . PHP_EOL;
|
|
139
|
+
if (!empty($details['added_functions'])) {
|
|
140
|
+
foreach ($details['added_functions'] as $func) {
|
|
141
|
+
echo " \e[36m[YENİ FONKSİYON]\e[0m $func() - Lütfen dokümantasyonu inceleyin." . PHP_EOL;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
echo PHP_EOL;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private function copyDirectory(string $source, string $target): void
|
|
151
|
+
{
|
|
152
|
+
if (!is_dir($target)) {
|
|
153
|
+
mkdir($target, 0755, true);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
$dir = opendir($source);
|
|
157
|
+
while (($file = readdir($dir)) !== false) {
|
|
158
|
+
if ($file === '.' || $file === '..') {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
$srcFile = $source . '/' . $file;
|
|
162
|
+
$tgtFile = $target . '/' . $file;
|
|
163
|
+
|
|
164
|
+
if (is_dir($srcFile)) {
|
|
165
|
+
$this->copyDirectory($srcFile, $tgtFile);
|
|
166
|
+
} else {
|
|
167
|
+
$isNew = !file_exists($tgtFile);
|
|
168
|
+
$isModified = !$isNew && (md5_file($srcFile) !== md5_file($tgtFile));
|
|
169
|
+
|
|
170
|
+
if ($isNew || $isModified) {
|
|
171
|
+
$addedFunctions = [];
|
|
172
|
+
if ($isModified && pathinfo($srcFile, PATHINFO_EXTENSION) === 'php') {
|
|
173
|
+
$oldFunctions = $this->getFunctionsFromFile($tgtFile);
|
|
174
|
+
$newFunctions = $this->getFunctionsFromFile($srcFile);
|
|
175
|
+
$addedFunctions = array_values(array_diff($newFunctions, $oldFunctions));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
copy($srcFile, $tgtFile);
|
|
179
|
+
|
|
180
|
+
$normalizedTarget = str_replace('\\', '/', $tgtFile);
|
|
181
|
+
$normalizedCwd = str_replace('\\', '/', getcwd()) . '/';
|
|
182
|
+
$relativePath = str_replace($normalizedCwd, '', $normalizedTarget);
|
|
183
|
+
|
|
184
|
+
if ($isNew) {
|
|
185
|
+
$this->changes['added'][] = $relativePath;
|
|
186
|
+
} else {
|
|
187
|
+
$this->changes['modified'][$relativePath] = [
|
|
188
|
+
'added_functions' => $addedFunctions
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
closedir($dir);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
private function getFunctionsFromFile(string $filepath): array
|
|
198
|
+
{
|
|
199
|
+
if (!file_exists($filepath)) {
|
|
200
|
+
return [];
|
|
201
|
+
}
|
|
202
|
+
$content = file_get_contents($filepath);
|
|
203
|
+
$functions = [];
|
|
204
|
+
if (preg_match_all('/function\s+([a-zA-Z0-9_]+)\s*\(/i', $content, $matches)) {
|
|
205
|
+
$functions = $matches[1];
|
|
206
|
+
}
|
|
207
|
+
return $functions;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -27,7 +27,8 @@ class VersionCommand
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
$
|
|
30
|
+
$safeguard = new \ArtiFrame\Cli\Services\Safeguard($this->translator);
|
|
31
|
+
$projectRoot = $safeguard->getProjectRoot();
|
|
31
32
|
$versionFile = $projectRoot . '/config/app-version.php';
|
|
32
33
|
|
|
33
34
|
if (!file_exists($versionFile)) {
|
package/src/Lang/de.php
CHANGED
|
@@ -59,6 +59,7 @@ return [
|
|
|
59
59
|
// Help screen
|
|
60
60
|
'HELP_COMMANDS' => 'BEFEHLE',
|
|
61
61
|
'HELP_NEW_DESC' => 'Erstellt ein neues ArtiFrame-Projekt von Grund auf.',
|
|
62
|
+
'HELP_UPGRADE_DESC' => 'Wendet aktualisierte CLI-Kernfunktionen (app, bin) von NPM auf Ihr Projekt an.',
|
|
62
63
|
'HELP_MAKEVIEW_DESC1' => 'Erstellt eine neue View-Datei mit CSS- und JS-Assets.',
|
|
63
64
|
'HELP_MAKEVIEW_DESC2' => 'Der Pfad kann Unterverzeichnisse enthalten (automatisch erstellt).',
|
|
64
65
|
'HELP_MAKEAPI_DESC' => 'Erstellt eine neue API-Endpunkt-Datei.',
|
|
@@ -75,6 +76,8 @@ return [
|
|
|
75
76
|
'HELP_MAJOR_DOWN' => 'Letzte Major-Version zurücksetzen.',
|
|
76
77
|
'HELP_HELP_DESC' => 'Diese Hilfemeldung anzeigen.',
|
|
77
78
|
'HELP_EXIT_DESC' => 'Die interaktive Shell beenden.',
|
|
79
|
+
'HELP_AUTH_DESC' => 'Authentifizieren Sie sich bei GitHub, um Vorschläge einzureichen.',
|
|
80
|
+
'HELP_SUGGEST_DESC' => 'Reichen Sie einen Funktionswunsch, Fehlerbericht oder Vorschlag direkt bei GitHub ein.',
|
|
78
81
|
|
|
79
82
|
// LangCommand
|
|
80
83
|
'LANG_CURRENT' => 'Aktuelle Sprache:',
|
|
@@ -176,6 +179,11 @@ return [
|
|
|
176
179
|
'TABLE_LIST_HEADER' => 'Unterstützte Tabellen:',
|
|
177
180
|
'TABLE_DESC_USERS' => 'Basis-Benutzer- und Autorisierungstabelle (UUID).',
|
|
178
181
|
'TABLE_DESC_USER_SESSIONS' => 'Benutzersitzungen (IP, Gerät, Token) verfolgen.',
|
|
179
|
-
'TABLE_DESC_USER_PREFERENCES' => 'Benutzereinstellungen (Sprache,
|
|
182
|
+
'TABLE_DESC_USER_PREFERENCES' => 'Benutzereinstellungen (Sprache, Design, Benachrichtigungen).',
|
|
183
|
+
|
|
184
|
+
// Upgrade
|
|
185
|
+
'UPGRADE_INDEX_ABORT' => 'public/index.php Datei erkannt! In der neuen Version fungiert diese Datei als Router. Um das Upgrade fortzusetzen, benennen Sie bitte Ihre bestehende index.php in landing.php (oder einen anderen Namen) um und führen Sie den Befehl erneut aus.',
|
|
186
|
+
'UPGRADE_CORE_WARNING' => 'Ihr Projektkern unterscheidet sich von der Originalversion. Wenn Sie manuell Funktionen hinzugefügt haben, sichern Sie diese bitte vor dem Upgrade, um Datenverlust zu vermeiden. Drücken Sie die Eingabetaste, um nach der Sicherung fortzufahren.',
|
|
187
|
+
'UPGRADE_SUCCESS' => 'Kern (app/ und bin/) und Service-Stubs erfolgreich aktualisiert!',
|
|
180
188
|
|
|
181
189
|
];
|
package/src/Lang/en.php
CHANGED
|
@@ -59,6 +59,7 @@ return [
|
|
|
59
59
|
// Help screen
|
|
60
60
|
'HELP_COMMANDS' => 'COMMANDS',
|
|
61
61
|
'HELP_NEW_DESC' => 'Create a new ArtiFrame project from scratch.',
|
|
62
|
+
'HELP_UPGRADE_DESC' => 'Applies updated core features (app, bin) from NPM to the current project.',
|
|
62
63
|
'HELP_MAKEVIEW_DESC1' => 'Generate a new view file with its paired CSS and JS assets.',
|
|
63
64
|
'HELP_MAKEVIEW_DESC2' => 'The path can use subdirectories (auto-created).',
|
|
64
65
|
'HELP_MAKEAPI_DESC' => 'Generate a new API endpoint file.',
|
|
@@ -75,6 +76,8 @@ return [
|
|
|
75
76
|
'HELP_MAJOR_DOWN' => 'Roll back last major release.',
|
|
76
77
|
'HELP_HELP_DESC' => 'Show this help message.',
|
|
77
78
|
'HELP_EXIT_DESC' => 'Exit the interactive shell.',
|
|
79
|
+
'HELP_AUTH_DESC' => 'Authenticate with GitHub to enable issue suggestions.',
|
|
80
|
+
'HELP_SUGGEST_DESC' => 'Submit a feature request, bug report, or helper suggestion directly to GitHub.',
|
|
78
81
|
|
|
79
82
|
// LangCommand
|
|
80
83
|
'LANG_CURRENT' => 'Current language:',
|
|
@@ -178,4 +181,9 @@ return [
|
|
|
178
181
|
'TABLE_DESC_USER_SESSIONS' => 'User sessions (IP, device, token) tracking.',
|
|
179
182
|
'TABLE_DESC_USER_PREFERENCES' => 'User preferences (language, theme, notifications).',
|
|
180
183
|
|
|
184
|
+
// Upgrade
|
|
185
|
+
'UPGRADE_INDEX_ABORT' => 'public/index.php file detected! In the new version, this file acts as a router. To continue the upgrade, please rename your existing index.php to landing.php (or any other name) and run the command again.',
|
|
186
|
+
'UPGRADE_CORE_WARNING' => 'Your project core is different from the original version. If you have manually added functions, please back them up before upgrading to prevent data loss. Press Enter to continue after backing up.',
|
|
187
|
+
'UPGRADE_SUCCESS' => 'Core (app/ and bin/) and service stubs updated successfully!',
|
|
188
|
+
|
|
181
189
|
];
|
package/src/Lang/es.php
CHANGED
|
@@ -59,6 +59,7 @@ return [
|
|
|
59
59
|
// Help screen
|
|
60
60
|
'HELP_COMMANDS' => 'COMANDOS',
|
|
61
61
|
'HELP_NEW_DESC' => 'Crea un nuevo proyecto ArtiFrame desde cero.',
|
|
62
|
+
'HELP_UPGRADE_DESC' => 'Aplica las características actualizadas del núcleo CLI (app, bin) desde NPM al proyecto.',
|
|
62
63
|
'HELP_MAKEVIEW_DESC1' => 'Genera un nuevo archivo de vista con sus recursos CSS y JS.',
|
|
63
64
|
'HELP_MAKEVIEW_DESC2' => 'La ruta puede usar subdirectorios (creados automáticamente).',
|
|
64
65
|
'HELP_MAKEAPI_DESC' => 'Genera un nuevo archivo de punto de conexión API.',
|
|
@@ -75,6 +76,8 @@ return [
|
|
|
75
76
|
'HELP_MAJOR_DOWN' => 'Revertir la última versión mayor.',
|
|
76
77
|
'HELP_HELP_DESC' => 'Mostrar este mensaje de ayuda.',
|
|
77
78
|
'HELP_EXIT_DESC' => 'Salir del shell interactivo.',
|
|
79
|
+
'HELP_AUTH_DESC' => 'Autentifícate con GitHub para habilitar las sugerencias de issues.',
|
|
80
|
+
'HELP_SUGGEST_DESC' => 'Envía una solicitud de función, un informe de error o una sugerencia de ayuda directamente a GitHub.',
|
|
78
81
|
|
|
79
82
|
// LangCommand
|
|
80
83
|
'LANG_CURRENT' => 'Idioma actual:',
|
|
@@ -176,6 +179,11 @@ return [
|
|
|
176
179
|
'TABLE_LIST_HEADER' => 'Tablas compatibles:',
|
|
177
180
|
'TABLE_DESC_USERS' => 'Tabla básica de usuarios y autorización (UUID).',
|
|
178
181
|
'TABLE_DESC_USER_SESSIONS' => 'Seguimiento de sesiones de usuario (IP, dispositivo, token).',
|
|
179
|
-
'TABLE_DESC_USER_PREFERENCES' => 'Preferencias
|
|
182
|
+
'TABLE_DESC_USER_PREFERENCES' => 'Preferencias del usuario (idioma, tema, notificaciones).',
|
|
183
|
+
|
|
184
|
+
// Upgrade
|
|
185
|
+
'UPGRADE_INDEX_ABORT' => '¡Archivo public/index.php detectado! En la nueva versión, este archivo actúa como un enrutador. Para continuar con la actualización, cambie el nombre de su index.php existente a landing.php (o cualquier otro nombre) y vuelva a ejecutar el comando.',
|
|
186
|
+
'UPGRADE_CORE_WARNING' => 'El núcleo de su proyecto es diferente de la versión original. Si ha agregado funciones manualmente, haga una copia de seguridad antes de actualizar para evitar la pérdida de datos. Presione Entrar para continuar después de hacer la copia de seguridad.',
|
|
187
|
+
'UPGRADE_SUCCESS' => '¡Núcleo (app/ y bin/) y stubs de servicio actualizados con éxito!',
|
|
180
188
|
|
|
181
189
|
];
|
package/src/Lang/fr.php
CHANGED
|
@@ -59,6 +59,7 @@ return [
|
|
|
59
59
|
// Help screen
|
|
60
60
|
'HELP_COMMANDS' => 'COMMANDES',
|
|
61
61
|
'HELP_NEW_DESC' => 'Crée un nouveau projet ArtiFrame de zéro.',
|
|
62
|
+
'HELP_UPGRADE_DESC' => 'Applique les fonctionnalités principales mises à jour du CLI (app, bin) depuis NPM au projet.',
|
|
62
63
|
'HELP_MAKEVIEW_DESC1' => 'Génère un nouveau fichier vue avec ses assets CSS et JS.',
|
|
63
64
|
'HELP_MAKEVIEW_DESC2' => 'Le chemin peut utiliser des sous-répertoires (créés automatiquement).',
|
|
64
65
|
'HELP_MAKEAPI_DESC' => 'Génère un nouveau fichier de point de terminaison API.',
|
|
@@ -75,6 +76,8 @@ return [
|
|
|
75
76
|
'HELP_MAJOR_DOWN' => 'Annuler la dernière version majeure.',
|
|
76
77
|
'HELP_HELP_DESC' => 'Afficher ce message d\'aide.',
|
|
77
78
|
'HELP_EXIT_DESC' => 'Quitter le shell interactif.',
|
|
79
|
+
'HELP_AUTH_DESC' => 'Authentifiez-vous avec GitHub pour permettre les suggestions.',
|
|
80
|
+
'HELP_SUGGEST_DESC' => 'Soumettez une demande de fonctionnalité, un rapport de bogue ou une suggestion d\'aide directement sur GitHub.',
|
|
78
81
|
|
|
79
82
|
// LangCommand
|
|
80
83
|
'LANG_CURRENT' => 'Langue actuelle :',
|
|
@@ -178,4 +181,9 @@ return [
|
|
|
178
181
|
'TABLE_DESC_USER_SESSIONS' => 'Suivi des sessions utilisateur (IP, appareil, token).',
|
|
179
182
|
'TABLE_DESC_USER_PREFERENCES' => 'Préférences de l\'utilisateur (langue, thème, notifications).',
|
|
180
183
|
|
|
184
|
+
// Upgrade
|
|
185
|
+
'UPGRADE_INDEX_ABORT' => 'Fichier public/index.php détecté ! Dans la nouvelle version, ce fichier agit comme un routeur. Pour continuer la mise à jour, veuillez renommer votre index.php existant en landing.php (ou tout autre nom) et relancez la commande.',
|
|
186
|
+
'UPGRADE_CORE_WARNING' => 'Le cœur de votre projet diffère de la version originale. Si vous avez ajouté manuellement des fonctions, veuillez les sauvegarder avant la mise à jour pour éviter toute perte de données. Appuyez sur Entrée pour continuer après la sauvegarde.',
|
|
187
|
+
'UPGRADE_SUCCESS' => 'Cœur (app/ et bin/) et stubs de services mis à jour avec succès !',
|
|
188
|
+
|
|
181
189
|
];
|
package/src/Lang/tr.php
CHANGED
|
@@ -59,6 +59,7 @@ return [
|
|
|
59
59
|
// Help screen
|
|
60
60
|
'HELP_COMMANDS' => 'KOMUTLAR',
|
|
61
61
|
'HELP_NEW_DESC' => 'Sıfırdan yeni bir ArtiFrame projesi oluşturur.',
|
|
62
|
+
'HELP_UPGRADE_DESC' => 'NPM üzerinden güncellenen çekirdek özellikleri (app, bin) mevcut projeye uygular.',
|
|
62
63
|
'HELP_MAKEVIEW_DESC1' => 'CSS ve JS varlıklarıyla birlikte yeni bir view dosyası oluşturur.',
|
|
63
64
|
'HELP_MAKEVIEW_DESC2' => 'Yol alt dizinleri içerebilir (otomatik oluşturulur).',
|
|
64
65
|
'HELP_MAKEAPI_DESC' => 'Yeni bir API endpoint dosyası oluşturur.',
|
|
@@ -74,7 +75,9 @@ return [
|
|
|
74
75
|
'HELP_MINOR_DOWN' => 'Son minör sürümün geri alınması.',
|
|
75
76
|
'HELP_MAJOR_DOWN' => 'Son majör sürümün geri alınması.',
|
|
76
77
|
'HELP_HELP_DESC' => 'Bu yardım mesajını gösterir.',
|
|
77
|
-
'HELP_EXIT_DESC' => '
|
|
78
|
+
'HELP_EXIT_DESC' => 'Etkileşimli kabuktan çık.',
|
|
79
|
+
'HELP_AUTH_DESC' => 'Issue önerileri için GitHub ile kimlik doğrulaması yapın.',
|
|
80
|
+
'HELP_SUGGEST_DESC' => 'GitHub\'a doğrudan özellik isteği, hata bildirimi veya öneri gönderin.',
|
|
78
81
|
|
|
79
82
|
// LangCommand
|
|
80
83
|
'LANG_CURRENT' => 'Mevcut dil:',
|
|
@@ -156,7 +159,7 @@ return [
|
|
|
156
159
|
'SERVE_NOT_PROJECT' => 'Bu dizin geçerli bir ArtiFrame projesi değil (public/index.php bulunamadı).',
|
|
157
160
|
'SERVE_STARTING' => 'Geliştirme sunucusu başlatılıyor: :url',
|
|
158
161
|
'SERVE_STOP_INFO' => 'Durdurmak için CTRL+C tuşlarına basın.',
|
|
159
|
-
'HELP_SERVE_DESC' => '
|
|
162
|
+
'HELP_SERVE_DESC' => 'Geliştirme sunucusunu başlatır ve yerel ağa açar.',
|
|
160
163
|
|
|
161
164
|
'INVALID_PACKAGE_NAME' => 'Geçersiz paket adı. Format şuna benzemeli: vendor/project',
|
|
162
165
|
|
|
@@ -178,4 +181,9 @@ return [
|
|
|
178
181
|
'TABLE_DESC_USER_SESSIONS' => 'Kullanıcı oturumları (IP, cihaz, token) takibi.',
|
|
179
182
|
'TABLE_DESC_USER_PREFERENCES' => 'Kullanıcı tercihleri (dil, tema, bildirimler).',
|
|
180
183
|
|
|
184
|
+
// Upgrade
|
|
185
|
+
'UPGRADE_INDEX_ABORT' => 'public/index.php dosyası tespit edildi! Yeni sürümde bu dosya artık bir router\'dır. Güncellemeye devam edebilmek için lütfen mevcut index.php\'nizin adını landing.php (veya istediğiniz başka bir isim) olarak değiştirin ve komutu tekrar çalıştırın.',
|
|
186
|
+
'UPGRADE_CORE_WARNING' => 'Proje çekirdeğiniz orijinal sürümden farklı. Manuel olarak eklediğiniz fonksiyonlar varsa kayba uğramamak için güncellemeden önce lütfen kopyalarını alın. Kopyalarını aldıktan sonra Enter tuşuna basarak devam edebilirsiniz.',
|
|
187
|
+
'UPGRADE_SUCCESS' => 'Çekirdek (app/ ve bin/) ile servis şablonları başarıyla güncellendi!',
|
|
188
|
+
|
|
181
189
|
];
|