@artilingo/artiframe-cli 2.0.3 → 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 +36 -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
@@ -0,0 +1,261 @@
1
+ <?php
2
+ /**
3
+ * ArtiFrame Database Mini-ORM & SQL Helpers
4
+ *
5
+ * @package ArtiFrame
6
+ * @author Artilingo
7
+ * @license AGPLv3
8
+ */
9
+
10
+ namespace Bin {
11
+
12
+ class SQLMethod
13
+ {
14
+ /**
15
+ * Güvenli ve hızlı bir PDO Prepare & Execute sarmalayıcısı.
16
+ */
17
+ public static function executeStmt(string $sql, array $params = []): \PDOStatement
18
+ {
19
+ // App\Database PSR-4 ile otomatik yüklenir. Sadece kullanıldığı yerde devreye girer.
20
+ $db = \App\Database::getInstance();
21
+ \App\Database::ping();
22
+
23
+ $stmt = $db->prepare($sql);
24
+ $stmt->execute($params);
25
+
26
+ return $stmt;
27
+ }
28
+
29
+ public static function dbInsert(string $table, array $data): string
30
+ {
31
+ if (empty($data)) {
32
+ throw new \InvalidArgumentException("Eklenecek veri (data) boş olamaz.");
33
+ }
34
+
35
+ // Tablo adını güvenlik için ters tırnak (backtick) ile saralım
36
+ $table = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $table) . "`";
37
+
38
+ $columns = [];
39
+ $placeholders = [];
40
+ $params = [];
41
+
42
+ foreach ($data as $key => $value) {
43
+ $columns[] = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $key) . "`";
44
+ $placeholders[] = "?";
45
+ $params[] = $value;
46
+ }
47
+
48
+ $sql = "INSERT INTO {$table} (" . implode(', ', $columns) . ") VALUES (" . implode(', ', $placeholders) . ")";
49
+ self::executeStmt($sql, $params);
50
+
51
+ return \App\Database::getInstance()->lastInsertId();
52
+ }
53
+
54
+ public static function dbUpdate(string $table, array $data, array $where): int
55
+ {
56
+ if (empty($data)) {
57
+ throw new \InvalidArgumentException("Güncellenecek veri (data) boş olamaz.");
58
+ }
59
+ if (empty($where)) {
60
+ throw new \InvalidArgumentException("BOMBA RİSKİ: Neye göre güncelleneceği (where) boş olamaz! Tüm tabloyu güncelleyemezsiniz.");
61
+ }
62
+
63
+ $table = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $table) . "`";
64
+
65
+ $setParts = [];
66
+ $params = [];
67
+ foreach ($data as $key => $value) {
68
+ $setParts[] = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $key) . "` = ?";
69
+ $params[] = $value;
70
+ }
71
+
72
+ [$whereParts, $whereParams] = self::parseWhere($where);
73
+ $params = array_merge($params, $whereParams);
74
+
75
+ $sql = "UPDATE {$table} SET " . implode(', ', $setParts) . " WHERE " . implode(' AND ', $whereParts);
76
+ $stmt = self::executeStmt($sql, $params);
77
+
78
+ return $stmt->rowCount();
79
+ }
80
+
81
+ public static function dbDelete(string $table, array $where): int
82
+ {
83
+ if (empty($where)) {
84
+ throw new \InvalidArgumentException("BOMBA RİSKİ: Neye göre silineceği (where) boş olamaz! Tüm tabloyu silemezsiniz.");
85
+ }
86
+
87
+ $table = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $table) . "`";
88
+
89
+ [$whereParts, $params] = self::parseWhere($where);
90
+
91
+ $sql = "DELETE FROM {$table} WHERE " . implode(' AND ', $whereParts);
92
+ $stmt = self::executeStmt($sql, $params);
93
+
94
+ return $stmt->rowCount();
95
+ }
96
+
97
+
98
+ /**
99
+ * WHERE dizisini güvenli SQL ve Parametrelere çevirir.
100
+ */
101
+ private static function parseWhere(array $where): array
102
+ {
103
+ $whereParts = [];
104
+ $params = [];
105
+
106
+ foreach ($where as $key => $value) {
107
+ $key = trim($key);
108
+ // İçinde operatör varsa (Örn: "yas >" veya "isim LIKE")
109
+ if (preg_match('/^([a-zA-Z0-9_\.]+)\s*(>=|<=|!=|<>|>|<|LIKE|NOT LIKE)$/i', $key, $matches)) {
110
+ $column = $matches[1];
111
+ $operator = strtoupper($matches[2]);
112
+ } else {
113
+ $column = preg_replace('/[^a-zA-Z0-9_\.]/', '', $key);
114
+ $operator = '=';
115
+ }
116
+
117
+ // Tabloadi.Sutun formatını güvenli backtick içine al: `tabloadi`.`sutun`
118
+ $colParts = explode('.', $column);
119
+ $safeCol = implode('.', array_map(fn($p) => "`$p`", $colParts));
120
+
121
+ $whereParts[] = "{$safeCol} {$operator} ?";
122
+ $params[] = $value;
123
+ }
124
+
125
+ return [$whereParts, $params];
126
+ }
127
+
128
+ public static function dbGet(string $table, array $where = [], string $orderBy = ''): mixed
129
+ {
130
+ $table = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $table) . "`";
131
+
132
+ $sql = "SELECT * FROM {$table}";
133
+ $params = [];
134
+
135
+ if (!empty($where)) {
136
+ [$whereParts, $params] = self::parseWhere($where);
137
+ $sql .= " WHERE " . implode(' AND ', $whereParts);
138
+ }
139
+
140
+ if (!empty($orderBy)) {
141
+ // Sadece a-z, boşluk ve virgüle izin ver (Injection koruması)
142
+ $orderBy = preg_replace('/[^a-zA-Z0-9_ \.,]/', '', $orderBy);
143
+ $sql .= " ORDER BY {$orderBy}";
144
+ }
145
+
146
+ $sql .= " LIMIT 1";
147
+
148
+ return self::executeStmt($sql, $params)->fetch(\PDO::FETCH_ASSOC);
149
+ }
150
+
151
+ public static function dbList(string $table, array $where = [], string $orderBy = '', string|int $limit = ''): array
152
+ {
153
+ $table = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $table) . "`";
154
+
155
+ $sql = "SELECT * FROM {$table}";
156
+ $params = [];
157
+
158
+ if (!empty($where)) {
159
+ [$whereParts, $params] = self::parseWhere($where);
160
+ $sql .= " WHERE " . implode(' AND ', $whereParts);
161
+ }
162
+
163
+ if (!empty($orderBy)) {
164
+ $orderBy = preg_replace('/[^a-zA-Z0-9_ \.,]/', '', $orderBy);
165
+ $sql .= " ORDER BY {$orderBy}";
166
+ }
167
+
168
+ if (!empty($limit)) {
169
+ // Sadece rakam ve virgüle izin ver (Örn: "0, 20" veya "20")
170
+ $limit = preg_replace('/[^0-9, ]/', '', (string)$limit);
171
+ $sql .= " LIMIT {$limit}";
172
+ }
173
+
174
+ return self::executeStmt($sql, $params)->fetchAll(\PDO::FETCH_ASSOC);
175
+ }
176
+
177
+ public static function dbCount(string $table, array $where = []): int
178
+ {
179
+ $table = "`" . preg_replace('/[^a-zA-Z0-9_]/', '', $table) . "`";
180
+
181
+ $sql = "SELECT COUNT(*) FROM {$table}";
182
+ $params = [];
183
+
184
+ if (!empty($where)) {
185
+ [$whereParts, $params] = self::parseWhere($where);
186
+ $sql .= " WHERE " . implode(' AND ', $whereParts);
187
+ }
188
+
189
+ return (int) self::executeStmt($sql, $params)->fetchColumn(0);
190
+ }
191
+
192
+ public static function dbRow(string $sql, array $params = [], int $fetchStyle = \PDO::FETCH_ASSOC): mixed
193
+ {
194
+ return self::executeStmt($sql, $params)->fetch($fetchStyle);
195
+ }
196
+
197
+ public static function dbRows(string $sql, array $params = [], int $fetchStyle = \PDO::FETCH_ASSOC): array
198
+ {
199
+ return self::executeStmt($sql, $params)->fetchAll($fetchStyle);
200
+ }
201
+
202
+ public static function dbValue(string $sql, array $params = [], int $column = 0): mixed
203
+ {
204
+ return self::executeStmt($sql, $params)->fetchColumn($column);
205
+ }
206
+ }
207
+ }
208
+
209
+
210
+ namespace {
211
+ if (!function_exists('dbExecute')) {
212
+ function dbExecute(string $sql, array $params = []): \PDOStatement {
213
+ return \Bin\SQLMethod::executeStmt($sql, $params);
214
+ }
215
+ }
216
+ if (!function_exists('dbInsert')) {
217
+ function dbInsert(string $table, array $data): string {
218
+ return \Bin\SQLMethod::dbInsert($table, $data);
219
+ }
220
+ }
221
+ if (!function_exists('dbUpdate')) {
222
+ function dbUpdate(string $table, array $data, array $where): int {
223
+ return \Bin\SQLMethod::dbUpdate($table, $data, $where);
224
+ }
225
+ }
226
+ if (!function_exists('dbDelete')) {
227
+ function dbDelete(string $table, array $where): int {
228
+ return \Bin\SQLMethod::dbDelete($table, $where);
229
+ }
230
+ }
231
+ if (!function_exists('dbGet')) {
232
+ function dbGet(string $table, array $where = [], string $orderBy = ''): mixed {
233
+ return \Bin\SQLMethod::dbGet($table, $where, $orderBy);
234
+ }
235
+ }
236
+ if (!function_exists('dbList')) {
237
+ function dbList(string $table, array $where = [], string $orderBy = '', string|int $limit = ''): array {
238
+ return \Bin\SQLMethod::dbList($table, $where, $orderBy, $limit);
239
+ }
240
+ }
241
+ if (!function_exists('dbCount')) {
242
+ function dbCount(string $table, array $where = []): int {
243
+ return \Bin\SQLMethod::dbCount($table, $where);
244
+ }
245
+ }
246
+ if (!function_exists('dbRow')) {
247
+ function dbRow(string $sql, array $params = [], int $fetchStyle = \PDO::FETCH_ASSOC): mixed {
248
+ return \Bin\SQLMethod::dbRow($sql, $params, $fetchStyle);
249
+ }
250
+ }
251
+ if (!function_exists('dbRows')) {
252
+ function dbRows(string $sql, array $params = [], int $fetchStyle = \PDO::FETCH_ASSOC): array {
253
+ return \Bin\SQLMethod::dbRows($sql, $params, $fetchStyle);
254
+ }
255
+ }
256
+ if (!function_exists('dbValue')) {
257
+ function dbValue(string $sql, array $params = [], int $column = 0): mixed {
258
+ return \Bin\SQLMethod::dbValue($sql, $params, $column);
259
+ }
260
+ }
261
+ }
@@ -47,7 +47,7 @@ namespace Bin {
47
47
  * @param string $value
48
48
  * @return string
49
49
  */
50
- public static function sanitizeString(string $value): string
50
+ public static function stripHtml(string $value): string
51
51
  {
52
52
  return strip_tags(trim($value));
53
53
  }
@@ -98,6 +98,65 @@ namespace Bin {
98
98
  return !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest';
99
99
  }
100
100
 
101
+ /**
102
+ * Beni Hatırla: Güvenli Cookie Oluşturur (14 Gün)
103
+ */
104
+ public static function setRememberMeCookie(string $kullaniciIdHex): void
105
+ {
106
+ $expires = time() + (14 * 24 * 60 * 60); // 14 gün
107
+ $secret = $_ENV['DB_PASSWORD'] ?? 'SinavOrtagim2026';
108
+ $data = $kullaniciIdHex . '|' . $expires;
109
+ $hash = hash_hmac('sha256', $data, $secret);
110
+ $cookieValue = base64_encode($data . '|' . $hash);
111
+
112
+ // HTTPOnly, Secure
113
+ setcookie('remember_me', $cookieValue, $expires, '/', '', true, true);
114
+ }
115
+
116
+ /**
117
+ * Beni Hatırla: Cookie'yi doğrular ve kullaniciId (hex) döner
118
+ */
119
+ public static function validateRememberMeCookie(): ?string
120
+ {
121
+ if (empty($_COOKIE['remember_me'])) {
122
+ return null;
123
+ }
124
+
125
+ $cookieValue = base64_decode($_COOKIE['remember_me']);
126
+ if (!$cookieValue) return null;
127
+
128
+ $parts = explode('|', $cookieValue);
129
+ if (count($parts) !== 3) {
130
+ return null;
131
+ }
132
+
133
+ [$kullaniciIdHex, $expires, $hash] = $parts;
134
+
135
+ if (time() > (int)$expires) {
136
+ self::clearRememberMeCookie();
137
+ return null;
138
+ }
139
+
140
+ $secret = $_ENV['DB_PASSWORD'] ?? 'SinavOrtagim2026';
141
+ $data = $kullaniciIdHex . '|' . $expires;
142
+ $expectedHash = hash_hmac('sha256', $data, $secret);
143
+
144
+ if (!hash_equals($expectedHash, $hash)) {
145
+ return null; // Kurcalanmış
146
+ }
147
+
148
+ return $kullaniciIdHex;
149
+ }
150
+
151
+ /**
152
+ * Beni Hatırla: Cookie'yi siler (Çıkış yaparken kullanılır)
153
+ */
154
+ public static function clearRememberMeCookie(): void
155
+ {
156
+ setcookie('remember_me', '', time() - 3600, '/', '', true, true);
157
+ }
158
+
159
+
101
160
  /**
102
161
  * API'ler için hızlı ve standart JSON yanıt (response) oluşturur.
103
162
  * Kullanıldığı anda işlemi sonlandırır (exit).
@@ -336,7 +395,7 @@ namespace Bin {
336
395
  *
337
396
  * @return string 16-byte raw binary string
338
397
  */
339
- public static function byteId(): string
398
+ public static function generateBinaryId(): string
340
399
  {
341
400
  // Get current timestamp in milliseconds (48-bit)
342
401
  $ts = (int)(microtime(true) * 1000);
@@ -398,9 +457,9 @@ namespace Bin {
398
457
  *
399
458
  * @return string 36-character hyphenated UUID string
400
459
  */
401
- public static function makeId(): string
460
+ public static function generateStringId(): string
402
461
  {
403
- return self::formatId(self::byteId());
462
+ return self::formatId(self::generateBinaryId());
404
463
  }
405
464
 
406
465
  /**
@@ -435,61 +494,54 @@ namespace Bin {
435
494
  return $asString ? (string) $result : $result;
436
495
  }
437
496
 
438
- /**
439
- * Sadece sayılardan oluşan rastgele bir OTP (One-Time Password) kodu üretir.
440
- * @param int $length Hanelerin sayısı (Varsayılan 6)
441
- */
442
- public static function otpInt(int $length = 6): int
443
- {
444
- if ($length < 1) $length = 1;
445
- if ($length > 18) $length = 18; // PHP 64-bit safe max length
497
+
446
498
 
447
- $min = (int) str_pad('1', $length, '0');
448
- $max = (int) str_pad('9', $length, '9');
499
+
449
500
 
450
- return random_int($min, $max);
451
- }
501
+
502
+
503
+
452
504
 
453
505
  /**
454
- * Sadece harflerden oluşan rastgele bir OTP kodu üretir.
455
- * @param int $length Hanelerin sayısı (Varsayılan 6)
456
- * @param string $case 'c': Sadece küçük, 'C': Sadece büyük, 'cC'/'Cc': Karışık
506
+ * Hexadecimal string'i binary formata çevirir. Zaten binary ise dokunmaz.
507
+ * ID dönüşümlerinde kod tekrarını (DRY) engellemek için kullanılır.
457
508
  */
458
- public static function otpStr(int $length = 6, string $case = 'C'): string
509
+ public static function convertToBinaryId(?string $id): ?string
459
510
  {
460
- $lower = 'abcdefghijklmnopqrstuvwxyz';
461
- $upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
462
-
463
- $chars = match (strtolower($case)) {
464
- 'c' => $lower,
465
- 'cc' => $lower . $upper,
466
- default => $upper,
467
- };
468
-
469
- $otp = '';
470
- $maxIndex = strlen($chars) - 1;
471
- for ($i = 0; $i < $length; $i++) {
472
- $otp .= $chars[random_int(0, $maxIndex)];
511
+ if (empty($id)) return $id;
512
+ if (strlen($id) === 32 && ctype_xdigit($id)) {
513
+ return hex2bin($id);
473
514
  }
474
-
475
- return $otp;
515
+ return $id;
476
516
  }
477
-
478
517
  /**
479
- * Harf ve sayılardan (Alphanumeric) oluşan rastgele bir OTP kodu üretir.
518
+ * Güvenli ve rastgele bir OTP (One Time Password) kodu üretir.
519
+ *
480
520
  * @param int $length Hanelerin sayısı (Varsayılan 6)
481
- * @param string $case 'c': Küçük+Sayı, 'C': Büyük+Sayı, 'cC'/'Cc': Karışık+Sayı
521
+ * @param string $type 'numeric', 'alpha' veya 'alphanumeric'
522
+ * @param string $case 'lower', 'upper' veya 'mixed' (Sadece harf içeren durumlarda geçerli)
482
523
  */
483
- public static function otpMix(int $length = 6, string $case = 'C'): string
524
+ public static function generateOTP(int $length = 6, string $type = 'numeric', string $case = 'upper'): string
484
525
  {
485
526
  $numbers = '0123456789';
486
527
  $lower = 'abcdefghijklmnopqrstuvwxyz';
487
528
  $upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
488
529
 
489
- $chars = match (strtolower($case)) {
490
- 'c' => $numbers . $lower,
491
- 'cc' => $numbers . $lower . $upper,
492
- default => $numbers . $upper,
530
+ $chars = match ($type) {
531
+ 'numeric' => $numbers,
532
+ 'alpha' => match ($case) {
533
+ 'lower' => $lower,
534
+ 'upper' => $upper,
535
+ 'mixed' => $lower . $upper,
536
+ default => $upper
537
+ },
538
+ 'alphanumeric' => match ($case) {
539
+ 'lower' => $numbers . $lower,
540
+ 'upper' => $numbers . $upper,
541
+ 'mixed' => $numbers . $lower . $upper,
542
+ default => $numbers . $upper
543
+ },
544
+ default => $numbers
493
545
  };
494
546
 
495
547
  $otp = '';
@@ -500,16 +552,6 @@ namespace Bin {
500
552
 
501
553
  return $otp;
502
554
  }
503
-
504
- /**
505
- * Gelen veriyi (özellikle BigInt ID'leri) güvenli bir şekilde string'e çevirir.
506
- * Javascript'te 15 haneyi aşan sayılardaki veri kaybını engellemek için
507
- * View dosyalarında data-id=<?= stringer($id) ?> şeklinde kullanılır.
508
- */
509
- public static function stringer($value): string
510
- {
511
- return (string) $value;
512
- }
513
555
  } // end class SystemMethod
514
556
 
515
557
  } // end namespace Bin
@@ -532,9 +574,9 @@ namespace {
532
574
  }
533
575
 
534
576
  if (!function_exists('sanitizeString')) {
535
- function sanitizeString(string $value): string
577
+ function stripHtml(string $value): string
536
578
  {
537
- return \Bin\SystemMethod::sanitizeString($value);
579
+ return \Bin\SystemMethod::stripHtml($value);
538
580
  }
539
581
  }
540
582
 
@@ -658,9 +700,9 @@ namespace {
658
700
  }
659
701
 
660
702
  if (!function_exists('byteId')) {
661
- function byteId(): string
703
+ function generateBinaryId(): string
662
704
  {
663
- return \Bin\SystemMethod::byteId();
705
+ return \Bin\SystemMethod::generateBinaryId();
664
706
  }
665
707
  }
666
708
 
@@ -672,9 +714,9 @@ namespace {
672
714
  }
673
715
 
674
716
  if (!function_exists('makeId')) {
675
- function makeId(): string
717
+ function generateStringId(): string
676
718
  {
677
- return \Bin\SystemMethod::makeId();
719
+ return \Bin\SystemMethod::generateStringId();
678
720
  }
679
721
  }
680
722
 
@@ -692,31 +734,30 @@ namespace {
692
734
  }
693
735
  }
694
736
 
695
- if (!function_exists('stringer')) {
696
- function stringer($value): string
697
- {
698
- return \Bin\SystemMethod::stringer($value);
699
- }
700
- }
737
+
738
+
739
+
740
+
741
+
701
742
 
702
- if (!function_exists('otpInt')) {
703
- function otpInt(int $length = 6): int
743
+ if (!function_exists('generateOTP')) {
744
+ function generateOTP(int $length = 6, string $type = 'numeric', string $case = 'upper'): string
704
745
  {
705
- return \Bin\SystemMethod::otpInt($length);
746
+ return \Bin\SystemMethod::generateOTP($length, $type, $case);
706
747
  }
707
748
  }
708
749
 
709
- if (!function_exists('otpStr')) {
710
- function otpStr(int $length = 6, string $case = 'C'): string
750
+ if (!function_exists('toBin')) {
751
+ function convertToBinaryId(?string $id): ?string
711
752
  {
712
- return \Bin\SystemMethod::otpStr($length, $case);
753
+ return \Bin\SystemMethod::convertToBinaryId($id);
713
754
  }
714
755
  }
715
756
 
716
- if (!function_exists('otpMix')) {
717
- function otpMix(int $length = 6, string $case = 'C'): string
757
+ if (!function_exists('generateOTP')) {
758
+ function generateOTP(int $length = 6, string $type = 'numeric', string $case = 'upper'): string
718
759
  {
719
- return \Bin\SystemMethod::otpMix($length, $case);
760
+ return \Bin\SystemMethod::generateOTP($length, $type, $case);
720
761
  }
721
762
  }
722
763
  }
@@ -35,6 +35,16 @@ namespace Bin {
35
35
  return htmlspecialchars((string)$data, ENT_QUOTES | ENT_HTML5, 'UTF-8');
36
36
  }
37
37
 
38
+ /**
39
+ * Metin içindeki @kullaniciadi formatındaki etiketleri linklere dönüştürür.
40
+ * XSS koruması için metnin önce display() fonksiyonundan geçmiş olması önerilir.
41
+ */
42
+ public static function parseMentions(string $text): string
43
+ {
44
+ $text = self::display($text);
45
+ return preg_replace('/@([A-Za-z0-9_]{3,30})/', '<a href="/user/profil/" class="cm-mention-link">@</a>', $text);
46
+ }
47
+
38
48
  /**
39
49
  * URL'leri güvenli hale getirir, zararlı karakterleri temizler.
40
50
  */
@@ -156,7 +166,9 @@ namespace Bin {
156
166
  if (empty($date)) return '-';
157
167
  $time = is_numeric($date) ? $date : strtotime($date);
158
168
  $diff = time() - $time;
169
+
159
170
  if ($diff < 1) return self::display(($lang === 'tr') ? 'şimdi' : 'just now');
171
+ if ($diff >= 604800) return self::display(date('d.m.Y', $time));
160
172
 
161
173
  $tokens = [
162
174
  31536000 => 'year',
@@ -420,12 +432,7 @@ namespace Bin {
420
432
  public static function routeLink(?string $requestUri = null): void
421
433
  {
422
434
 
423
- if (!defined('APP_MAINTENANCE')) {
424
- $rawVal = $_ENV['APP_MAINTENANCE'] ?? false;
425
435
 
426
- // filter_var("true", FILTER_VALIDATE_BOOLEAN) -> bool(true) üretir
427
- define('APP_MAINTENANCE', filter_var($rawVal, FILTER_VALIDATE_BOOLEAN));
428
- }
429
436
 
430
437
  // ------------------------------------------------------------------
431
438
  // 1. BAKIM MODU (MAINTENANCE GUARD)
@@ -640,6 +647,13 @@ namespace {
640
647
  }
641
648
  }
642
649
 
650
+ if (!function_exists('parseMentions')) {
651
+ function parseMentions(string $text): string
652
+ {
653
+ return \Bin\ViewMethod::parseMentions($text);
654
+ }
655
+ }
656
+
643
657
  if (!function_exists('formatSize')) {
644
658
  function formatSize(int $bytes): string
645
659
  {