@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.
Files changed (41) hide show
  1. package/core-stubs/bin/SystemMethod.php +600 -521
  2. package/core-stubs/bin/ViewMethod.php +591 -393
  3. package/core-stubs/docs/de.html +853 -1172
  4. package/core-stubs/docs/en.html +585 -904
  5. package/core-stubs/docs/es.html +934 -1253
  6. package/core-stubs/docs/fr.html +913 -1232
  7. package/core-stubs/docs/tr.html +4212 -5021
  8. package/package.json +1 -1
  9. package/src/App.php +38 -0
  10. package/src/Commands/AddCommand.php +1 -1
  11. package/src/Commands/AuthCommand.php +219 -0
  12. package/src/Commands/IssuesCommand.php +174 -0
  13. package/src/Commands/ListCommand.php +2 -1
  14. package/src/Commands/MakeApiCommand.php +1 -1
  15. package/src/Commands/MakeClassCommand.php +1 -1
  16. package/src/Commands/MakeViewCommand.php +1 -1
  17. package/src/Commands/NewProjectCommand.php +37 -25
  18. package/src/Commands/RemoveCommand.php +21 -10
  19. package/src/Commands/ServeCommand.php +29 -9
  20. package/src/Commands/SuggestCommand.php +143 -0
  21. package/src/Commands/TableCommand.php +2 -1
  22. package/src/Commands/UpgradeCommand.php +209 -0
  23. package/src/Commands/VersionCommand.php +2 -1
  24. package/src/Lang/de.php +9 -1
  25. package/src/Lang/en.php +8 -0
  26. package/src/Lang/es.php +9 -1
  27. package/src/Lang/fr.php +8 -0
  28. package/src/Lang/tr.php +10 -2
  29. package/src/Services/Safeguard.php +25 -0
  30. package/stubs/service/image.stub +334 -334
  31. package/stubs/service/iyzico.stub +637 -637
  32. package/stubs/service/jwt.stub +312 -312
  33. package/stubs/service/phpmailer.stub +143 -143
  34. package/stubs/service/pusher.stub +232 -232
  35. package/stubs/service/qrcode.stub +169 -169
  36. package/stubs/service/redis.stub +361 -361
  37. package/stubs/service/s3.stub +377 -377
  38. package/stubs/service/sentry.stub +76 -106
  39. package/stubs/service/stripe.stub +526 -526
  40. package/stubs/service/twilio.stub +361 -361
  41. package/core-stubs/app/R2Manager.php +0 -130
@@ -1,18 +1,23 @@
1
- <!DOCTYPE html>
2
- <!DOCTYPE html>
3
-
1
+ html
4
2
  <html lang="de">
5
3
  <head>
6
4
  <meta charset="utf-8"/>
7
5
  <meta content="width=device-width, initial-scale=1.0" name="viewport"/>
8
- <title>ArtiFrame | Offizielle Entwicklerdokumentation</title>
9
-
10
- <link rel="icon" type="image/png" href="../../public/assets/images/favicon-96x96.png" sizes="96x96" />
11
- <link rel="icon" type="image/svg+xml" href="../../public/assets/images/favicon.svg" />
12
- <link rel="shortcut icon" href="../../public/assets/images/favicon.ico" />
13
- <link rel="apple-touch-icon" sizes="180x180" href="../../public/assets/images/apple-touch-icon.png" />
14
- <link rel="manifest" href="../../public/assets/images/site.webmanifest" />
15
-
6
+ <title>Offizielle Entwicklerdokumentation – ArtiFrame PHP Framework</title>
7
+ <meta content="ArtiFrame framework kullanım rehberi ve API referansları. En hızlı ve güvenli PHP framework'ünü öğrenin." name="description"/>
8
+ <meta content="artiframe, artiframe framework, php framework, fast php framework, secure php framework, artilingo framework, php, framework, mvc" name="keywords"/>
9
+ <meta content="Artilingo" name="author"/>
10
+ Open Graph / Social Media
11
+ <meta content="Resmi Geliştirici Dokümantasyonu — ArtiFrame PHP Framework" property="og:title"/>
12
+ <meta content="ArtiFrame framework kullanım rehberi ve API referansları. En hızlı ve güvenli PHP framework'ünü öğrenin." property="og:description"/>
13
+ <meta content="website" property="og:type"/>
14
+ <meta content="https://artiframe.artilingo.com/docs/tr.html" property="og:url"/>
15
+ <meta content="ArtiFrame" property="og:site_name"/>
16
+ <link href="../../public/assets/images/favicon-96x96.png" rel="icon" sizes="96x96" type="image/png"/>
17
+ <link href="../../public/assets/images/favicon.svg" rel="icon" type="image/svg+xml"/>
18
+ <link href="../../public/assets/images/favicon.ico" rel="shortcut icon"/>
19
+ <link href="../../public/assets/images/apple-touch-icon.png" rel="apple-touch-icon" sizes="180x180"/>
20
+ <link href="../../public/assets/images/site.webmanifest" rel="manifest"/>
16
21
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&amp;family=JetBrains+Mono:wght@400;500&amp;display=swap" rel="stylesheet"/>
17
22
  <style>
18
23
  :root {
@@ -33,9 +38,7 @@
33
38
  --sidebar-w: 280px;
34
39
  }
35
40
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
36
-
37
41
  html { scroll-behavior: smooth; }
38
-
39
42
  body {
40
43
  font-family: 'Inter', sans-serif;
41
44
  background: var(--bg);
@@ -43,7 +46,6 @@
43
46
  line-height: 1.75;
44
47
  display: flex;
45
48
  }
46
-
47
49
  /* ---- SIDEBAR ---- */
48
50
  .sidebar {
49
51
  width: var(--sidebar-w);
@@ -57,7 +59,6 @@
57
59
  display: flex;
58
60
  flex-direction: column;
59
61
  }
60
-
61
62
  .sb-logo {
62
63
  padding: 0 22px 24px;
63
64
  border-bottom: 1px solid var(--border);
@@ -75,7 +76,6 @@
75
76
  color: var(--muted);
76
77
  margin-top: 3px;
77
78
  }
78
-
79
79
  .sb-subcat {
80
80
  padding: 12px 22px 4px;
81
81
  font-size: 0.62rem;
@@ -107,7 +107,6 @@
107
107
  background: var(--green-dim);
108
108
  border-left-color: var(--green);
109
109
  }
110
-
111
110
  /* ---- MAIN ---- */
112
111
  .content {
113
112
  margin-left: var(--sidebar-w);
@@ -115,7 +114,6 @@
115
114
  max-width: 1100px;
116
115
  width: 100%;
117
116
  }
118
-
119
117
  /* ---- TYPOGRAPHY ---- */
120
118
  h1 { font-size: 2.6rem; font-weight: 700; letter-spacing: -0.5px; margin-bottom: 16px; }
121
119
  h1 span { color: var(--green); }
@@ -133,10 +131,8 @@
133
131
  li { margin-bottom: 8px; }
134
132
  a { color: var(--green-light); text-decoration: none; }
135
133
  a:hover { text-decoration: underline; }
136
-
137
134
  /* ---- LEAD ---- */
138
135
  .lead { font-size: 1.05rem; color: var(--muted); margin-bottom: 0; max-width: 720px; }
139
-
140
136
  /* ---- BADGES ---- */
141
137
  .badge { font-size: 0.68rem; padding: 3px 8px; border-radius: 4px; font-weight: 700; text-transform: uppercase; letter-spacing: .5px; white-space: nowrap; }
142
138
  .b-view { background: rgba(88,166,255,.12); color: #58a6ff; border: 1px solid rgba(88,166,255,.3); }
@@ -144,7 +140,6 @@
144
140
  .b-cli { background: rgba(0,200,140,.12); color: #00c88c; border: 1px solid rgba(0,200,140,.3); }
145
141
  .b-core { background: rgba(227,179,65,.12); color: #e3b341; border: 1px solid rgba(227,179,65,.3); }
146
142
  .b-sec { background: rgba(248,81,73,.12); color: #f85149; border: 1px solid rgba(248,81,73,.3); }
147
-
148
143
  /* ---- CODE ---- */
149
144
  pre {
150
145
  background: var(--code-bg);
@@ -172,7 +167,6 @@
172
167
  .cm { color: #8b949e; } /* comment */
173
168
  .nu { color: #79c0ff; } /* number / bool */
174
169
  .var { color: #ffa657; } /* variable */
175
-
176
170
  /* ---- CARDS ---- */
177
171
  .card {
178
172
  background: var(--surface);
@@ -182,21 +176,17 @@
182
176
  margin-bottom: 20px;
183
177
  }
184
178
  .card.highlight { border-left: 3px solid var(--green); }
185
-
186
179
  /* ---- ALERTS ---- */
187
180
  .alert { padding: 18px 22px; border-radius: 8px; margin: 24px 0; border-left: 3px solid; font-size: 0.95rem; }
188
181
  .a-info { background: rgba(88,166,255,.08); border-color: var(--blue); color: #93c5fd; }
189
182
  .a-warn { background: rgba(227,179,65,.08); border-color: var(--yellow); color: #fbbf24; }
190
183
  .a-danger { background: rgba(248,81,73,.08); border-color: var(--red); color: #fca5a5; }
191
184
  .a-success { background: rgba(0,157,108,.08); border-color: var(--green); color: #6ee7b7; }
192
-
193
185
  /* ---- RETURN TYPE ---- */
194
186
  .ret { display: inline-block; font-size: 0.78rem; color: var(--green); font-family: 'JetBrains Mono', monospace; background: rgba(0,157,108,.12); padding: 3px 10px; border-radius: 4px; border: 1px solid rgba(0,157,108,.25); margin-bottom: 12px; }
195
-
196
187
  /* ---- GRID ---- */
197
188
  .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; margin-bottom: 24px; }
198
189
  @media(max-width: 900px) { .grid-2 { grid-template-columns: 1fr; } }
199
-
200
190
  /* ---- DIR TREE ---- */
201
191
  .tree { background: var(--code-bg); border: 1px solid var(--border); border-radius: 8px; padding: 22px 24px; font-family: 'JetBrains Mono', monospace; font-size: 0.875rem; line-height: 1.9; white-space: pre; overflow-x: auto; }
202
192
  .tree .dir { color: var(--blue); font-weight: 600; }
@@ -204,7 +194,6 @@
204
194
  .tree .note { color: #8b949e; }
205
195
  .tree .warn { color: var(--yellow); }
206
196
  .tree .safe { color: var(--green); }
207
-
208
197
  /* ---- STEP LIST ---- */
209
198
  .steps { counter-reset: step; list-style: none; margin: 0 0 24px; padding: 0; }
210
199
  .steps li { counter-increment: step; display: flex; gap: 18px; margin-bottom: 20px; }
@@ -220,17 +209,14 @@
220
209
  font-weight: 700; font-size: 0.85rem;
221
210
  margin-top: 2px;
222
211
  }
223
-
224
212
  /* ---- SIGNATURE TABLE ---- */
225
213
  .sig-table { width: 100%; border-collapse: collapse; margin: 16px 0 24px; font-size: 0.87rem; }
226
214
  .sig-table th { text-align: left; padding: 10px 14px; background: var(--surface-2); color: var(--muted); font-weight: 600; border-bottom: 1px solid var(--border); }
227
215
  .sig-table td { padding: 10px 14px; border-bottom: 1px solid rgba(48,54,61,.5); vertical-align: top; }
228
216
  .sig-table td:first-child { font-family: 'JetBrains Mono', monospace; color: var(--yellow); white-space: nowrap; }
229
217
  .sig-table td:last-child { color: var(--muted); }
230
-
231
218
  /* ---- SCROLL SPY ---- */
232
219
  header#page-header { margin-bottom: 52px; }
233
-
234
220
  .table-wrapper {
235
221
  width: 100%;
236
222
  overflow-x: auto;
@@ -241,7 +227,6 @@
241
227
  margin-bottom: 0; /* Override default table margin if any */
242
228
  white-space: nowrap; /* Keep table cells on one line for better scroll */
243
229
  }
244
-
245
230
  @media(max-width: 900px) {
246
231
  body { flex-direction: column; }
247
232
  .sidebar { position: relative; width: 100%; height: auto; border-right: none; border-bottom: 1px solid var(--border); padding: 20px; z-index: 10; }
@@ -255,7 +240,7 @@
255
240
  </style>
256
241
  </head>
257
242
  <body>
258
- <!-- SIDEBAR -->
243
+ SEITENLEISTE
259
244
  <aside class="sidebar">
260
245
  <div class="sb-logo">
261
246
  <strong>ArtiFrame</strong>
@@ -268,64 +253,68 @@
268
253
  <a href="#kurulum">Aufstellen</a>
269
254
  <a href="#dizin">Verzeichnisstruktur</a>
270
255
  <div class="sb-cat">Architektonisch</div>
256
+ <a href="#v2-routing">Zero-Config-Routing (v2.0)</a>
271
257
  <a href="#bootstrapper">Bootstrapper-Architektur</a>
272
258
  <a href="#kurallar">Regelsatz</a>
273
259
  <div class="sb-cat">CLI-Tool</div>
274
- <a href="#cli-giris">CLI'ye Giriş</a>
275
- <a href="#cli-new">new</a>
260
+ <a href="#cli-giris">Einführung in CLI</a>
261
+ <a href="#cli-new">neu</a>
262
+ <a href="#cli-upgrade">Upgrade</a>
276
263
  <a href="#cli-view">make:view</a>
277
264
  <a href="#cli-api">make:api</a>
278
- <a href="#cli-class">make:class</a>
279
- <a href="#cli-table">table:</a>
265
+ <a href="#cli-class">make:class</a>
266
+ <a href="#cli-table">Tisch:</a>
280
267
  <a href="#cli-cliv">cli v</a>
281
- <a href="#cli-show">show</a>
282
- <a href="#cli-list">list</a>
283
- <a href="#cli-go">go</a>
284
- <a href="#cli-remove">remove</a>
285
- <a href="#cli-version">version</a>
286
- <a href="#cli-mode">mode</a>
287
- <a href="#cli-serve">serve</a>
288
- <a href="#cli-add">add</a>
268
+ <a href="#cli-show">zeigen</a>
269
+ <a href="#cli-list">Liste</a>
270
+ <a href="#cli-go">gehen</a>
271
+ <a href="#cli-remove">entfernen</a>
272
+ <a href="#cli-version">Version</a>
273
+ <a href="#cli-mode">Modus</a>
274
+ <a href="#cli-serve">Aufschlag</a>
275
+ <a href="#cli-auth">Autor</a>
276
+ <a href="#cli-suggest">vorschlagen</a>
277
+ <a href="#cli-add">hinzufügen</a>
289
278
  <div class="sb-cat">Integrierte Dienste</div>
290
- <a href="#svc-qrcode">QR Code</a>
291
- <a href="#svc-phpmailer">PHPMailer (Mail)</a>
292
- <a href="#svc-iyzico">Iyzico <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></a>
293
- <a href="#svc-stripe">Stripe <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></a>
294
- <a href="#svc-jwt">JWT</a>
295
- <a href="#svc-image">Image Processing</a>
296
- <a href="#svc-s3">AWS S3 <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></a>
279
+ <a href="#svc-qrcode">QR-Code</a>
280
+ <a href="#svc-phpmailer">PHPMailer (Mail)</a>
281
+ <a href="#svc-iyzico">Iyzico<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></a>
282
+ <a href="#svc-stripe">Streifen<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></a>
283
+ <a href="#svc-jwt">J.W.T.</a>
284
+ <a href="#svc-image">Bildverarbeitung</a>
285
+ <a href="#svc-s3">AWS S3<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></a>
297
286
  <a href="#svc-redis">Redis</a>
298
- <a href="#svc-pusher">Pusher <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></a>
299
- <a href="#svc-twilio">Twilio <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></a>
300
- <a href="#svc-sentry">Sentry <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></a>
287
+ <a href="#svc-pusher">Pusher<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></a>
288
+ <a href="#svc-twilio">Twitter<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></a>
289
+ <a href="#svc-sentry">Posten<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></a>
301
290
  <div class="sb-cat">Helfer anzeigen</div>
302
- <a href="#vh-display">display()</a>
291
+ <a href="#vh-display">Anzeige()</a>
303
292
  <a href="#vh-escapeurl">escapeUrl()</a>
304
293
  <a href="#vh-csrf">csrfField()</a>
305
- <a href="#vh-dates">Tarih Fonksiyonları</a>
306
- <a href="#vh-truncate">truncate()</a>
294
+ <a href="#vh-dates">Datumsfunktionen</a>
295
+ <a href="#vh-truncate">kürzen()</a>
307
296
  <a href="#vh-activeclass">activeClass()</a>
308
297
  <a href="#vh-formatsize">formatSize()</a>
309
298
  <a href="#vh-maskemail">maskEmail()</a>
310
299
  <a href="#vh-maskphone">maskPhone()</a>
311
300
  <a href="#vh-slugify">slugify()</a>
312
- <a href="#vh-money">money()</a>
313
- <a href="#vh-uuid">uuid()</a>
301
+ <a href="#vh-money">Geld()</a>
302
+ <a href="#vh-uuid">uuid()</a>
314
303
  <div class="sb-cat">Systemhelfer</div>
315
304
  <div class="sb-subcat">Antwort und Fehlerbehebung</div>
316
305
  <a href="#sh-apiresponse">apiResponse()</a>
317
306
  <a href="#sh-json">jsonResponse()</a>
318
- <a href="#sh-redirect">redirect()</a>
307
+ <a href="#sh-redirect">umleiten()</a>
319
308
  <a href="#sh-dd">dd()</a>
320
309
  <div class="sb-subcat">CSRF-Sicherheit</div>
321
310
  <a href="#sh-generatecsrf">generateCsrf()</a>
322
- <a href="#sh-csrf">verifyCsrf()</a>
311
+ <a href="#sh-csrf">überprüfenCsrf()</a>
323
312
  <div class="sb-subcat">Desinfizieren und validieren</div>
324
313
  <a href="#sh-sanitizeint">sanitizeInt()</a>
325
314
  <a href="#sh-sanitizefloat">sanitizeFloat()</a>
326
315
  <a href="#sh-sanitizestring">sanitizeString()</a>
327
316
  <a href="#sh-sanitizeemail">sanitizeEmail()</a>
328
- <a href="#sh-verifyemail">verifyEmail()</a>
317
+ <a href="#sh-verifyemail">überprüfenEmail()</a>
329
318
  <div class="sb-subcat">HTTP-Anfrage</div>
330
319
  <a href="#sh-ispost">isPost()</a>
331
320
  <a href="#sh-isget">isGet()</a>
@@ -334,7 +323,7 @@
334
323
  <a href="#sh-isajax">isAjax()</a>
335
324
  <a href="#sh-getclientip">getClientIp()</a>
336
325
  <div class="sb-subcat">Authentifizierung</div>
337
- <a href="#sh-generatetoken">generateToken()</a>
326
+ <a href="#sh-generatetoken">generierenToken()</a>
338
327
  <a href="#sh-hashpassword">hashPassword()</a>
339
328
  <a href="#sh-verifypassword">verifyPassword()</a>
340
329
  <div class="sb-subcat">Datendienstprogramme</div>
@@ -346,8 +335,8 @@
346
335
  <a href="#sh-formatid">formatId()</a>
347
336
  <a href="#sh-intid">intId()</a>
348
337
  <a href="#sh-bigintid">bigintId()</a>
349
- <a href="#sh-stringer">stringer()</a>
350
- <a href="#sh-otpcoder">OTP Coder</a>
338
+ <a href="#sh-stringer">stringer()</a>
339
+ <a href="#sh-otpcoder">OTP-Codierer</a>
351
340
  <div class="sb-cat">API-Sicherheit</div>
352
341
  <a href="#api-methods">HTTP-Methodensteuerung</a>
353
342
  <a href="#api-cors">CORS</a>
@@ -356,17 +345,17 @@
356
345
  <a href="#workflow">Vollständiger Workflow</a>
357
346
  </nav>
358
347
  </aside>
359
- <!-- MAIN CONTENT -->
348
+ HAUPTINHALT
360
349
  <main class="content">
361
- <!-- ====== GİRİŞ ====== -->
350
+ ====== ANMELDEN ======
362
351
  <header id="page-header">
363
- <h1>ArtiFrame <span>Dokumentation</span></h1>
352
+ <h1>ArtiFrame<span>Dokumentation</span></h1>
364
353
  <p class="lead">Framework für skalierbare native PHP-Projekte, die ohne externe Abhängigkeiten, strenge Regeln und eine leistungsstarke CLI verwaltet werden. Keine Abhängigkeiten, ein leichtes und schnelles Ökosystem ohne Composer-Paketsuppe, sodass Sie sich auf Ihre Geschäftslogik konzentrieren können.</p>
365
354
  </header>
366
- <!-- ====== GİRİŞ & FELSEFE ====== -->
355
+ ====== EINFÜHRUNG &amp; PHILOSOPHIE ======
367
356
  <section id="giris">
368
357
  <h2>Einführung &amp; Philosophie</h2>
369
- <p>ArtiFrame, <strong>„Konvention statt Konfiguration“</strong> Es basiert auf dem Prinzip (Regeln vor der Konfiguration). Die Leistungsfähigkeit eines Frameworks beruht nicht auf der Vielfalt der Tools, die es bietet, sondern auf der Konsistenz der von ihm festgelegten Ordnung.</p>
358
+ <p>ArtiFrame,<strong>„Konvention statt Konfiguration“</strong>Es basiert auf dem Prinzip (Regeln vor der Konfiguration). Die Leistungsfähigkeit eines Frameworks beruht nicht auf der Vielfalt der Tools, die es bietet, sondern auf der Konsistenz der von ihm festgelegten Ordnung.</p>
370
359
  <div class="grid-2">
371
360
  <div class="card highlight">
372
361
  <h3>Kein Overhead</h3>
@@ -378,32 +367,30 @@
378
367
  </div>
379
368
  <div class="card highlight">
380
369
  <h3>Strenger Regelsatz</h3>
381
- <p>Ein Junior-Entwickler, der gerade dem Projekt beigetreten ist, <code class="ic">data-js</code> Versteht die Architektur und Verzeichnisstruktur in wenigen Minuten. Die Teamkompatibilität ist auf Framework-Ebene gewährleistet.</p>
370
+ <p>Ein Junior-Entwickler, der gerade dem Projekt beigetreten ist,<code class="ic">data-js</code>Versteht die Architektur und Verzeichnisstruktur in wenigen Minuten. Die Teamkompatibilität ist auf Framework-Ebene gewährleistet.</p>
382
371
  </div>
383
372
  <div class="card highlight">
384
373
  <h3>CLI-Priorität</h3>
385
- <p>Es ist nicht erforderlich, Ansichts-, API- und Klassendateien manuell zu erstellen. Die CLI generiert Stub-Dateien, verknüpft Assets und hält das Projekt konsistent.</p>
374
+ <p>Es ist nicht erforderlich, Ansichts-, API- und Klassendateien manuell zu erstellen. Die CLI generiert Stub-Dateien, stellt Asset-Links her und sorgt für die Konsistenz des Projekts.</p>
386
375
  </div>
387
376
  </div>
388
377
  <div class="alert a-info">
389
- <strong>💡 Suchtphilosophie:</strong> Beim Erstellen eines neuen Projekts werden Composer-Pakete nach Weltstandard wie phpmailer, redis, ramsey/uuid installiert. Der ArtiFrame-Kern ist jedoch nicht von ihnen abhängig. Sie können es jederzeit löschen, Ihre eigenen Pakete herunterladen und Ihre Funktionen entsprechend Ihrer eigenen Architektur neu schreiben. ArtiFrame bewahrt Ihre architektonische Freiheit und reduziert gleichzeitig die externe Abhängigkeit auf Null.
390
- </div>
378
+ <strong>💡 Suchtphilosophie:</strong>Beim Erstellen eines neuen Projekts werden Composer-Pakete nach Weltstandard wie phpmailer, redis, ramsey/uuid installiert. Der ArtiFrame-Kern ist jedoch nicht von ihnen abhängig. Sie können es jederzeit löschen, Ihre eigenen Pakete herunterladen und Ihre Funktionen entsprechend Ihrer eigenen Architektur neu schreiben. ArtiFrame bewahrt Ihre architektonische Freiheit und reduziert gleichzeitig die externe Abhängigkeit auf Null.</div>
391
379
  <div class="alert a-info">
392
- <strong>ℹ️ AGPLv3-Lizenz:</strong> ArtiFrame ist Open Source. Von Ihnen erstellte abgeleitete Werke dürfen frei verwendet werden, sofern der Quellcode offen bleibt. Der Copyright-Hinweis kann nicht entfernt werden.
393
- </div>
380
+ <strong>ℹ️ AGPLv3-Lizenz:</strong>ArtiFrame ist Open Source. Von Ihnen erstellte abgeleitete Werke dürfen frei verwendet werden, sofern der Quellcode offen bleibt. Der Copyright-Hinweis kann nicht entfernt werden.</div>
394
381
  </section>
395
- <!-- ====== LİSANS VE KULLANIM ====== -->
382
+ ====== LIZENZ UND NUTZUNG ======
396
383
  <section id="lisans">
397
384
  <h2>Lizenz und Nutzungsbedingungen</h2>
398
385
  <p>ArtiFrame ist ein Open-Source-Framework mit AGPLv3-Lizenz. Es wurden jedoch flexible Nutzungsszenarien entworfen, damit Entwickler ihre Projekte kommerzialisieren und als Closed Source verkaufen können.</p>
399
386
  <div class="grid-2">
400
387
  <div class="card highlight" style="border-left-color: var(--green);">
401
388
  <h3>🗽 Özgür Ticaret (Endbenutzerprojekte)</h3>
402
- <p>Auf den Websites Ihrer Kunden, in internen B2B-Panels, in E-Commerce-Infrastrukturen oder in jedem SaaS/PaaS-Projekt, das dem Endbenutzer dient. <strong>Du bist frei</strong> Sie können Ihren Code verstecken, verkaufen und urheberrechtlich schützen.</p>
389
+ <p>Auf den Websites Ihrer Kunden, in internen B2B-Panels, in E-Commerce-Infrastrukturen oder in jedem SaaS/PaaS-Projekt, das dem Endbenutzer dient.<strong>Du bist frei</strong>Sie können Ihren Code verstecken, verkaufen und urheberrechtlich schützen.</p>
403
390
  </div>
404
391
  <div class="card highlight" style="border-left-color: var(--yellow);">
405
392
  <h3>🔄 Fork und neues Framework</h3>
406
- <p>Die Kerndateien von ArtiFrame (<code>bin/</code> Und <code>app/</code>) Wenn Sie für sich oder andere ein neues Framework, eine neue CMS-Infrastruktur oder ein neues Codierungstool erstellen, können Sie dieses neue Produkt ebenfalls verwenden. <strong>Open Source</strong> Sie müssen es als veröffentlichen.</p>
393
+ <p>Die Kerndateien von ArtiFrame (<code>bin/</code>Und<code>app/</code>) Wenn Sie für sich oder andere ein neues Framework, eine neue CMS-Infrastruktur oder ein neues Codierungstool erstellen, können Sie dieses neue Produkt ebenfalls verwenden.<strong>Open Source</strong>Sie müssen es als veröffentlichen.</p>
407
394
  </div>
408
395
  <div class="card highlight" style="border-left-color: var(--red); grid-column: span 2;">
409
396
  <h3>⚖️ Rechtsdurchsetzungs- und Verstoßsituation</h3>
@@ -417,11 +404,11 @@
417
404
  <button class="tab-btn active" onclick="switchTab('tab-enduser', this)" style="white-space: nowrap; padding: 10px 20px; background: #00c88c; color: #000; font-weight: 600; border: none; border-radius: 5px; cursor: pointer;">Endbenutzerprojekt</button>
418
405
  <button class="tab-btn" onclick="switchTab('tab-core', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">Kernveränderung (Framework/CMS)</button>
419
406
  </div>
420
- <!-- Tab 1 -->
407
+ Registerkarte 1
421
408
  <div class="tab-content" id="tab-enduser" style="display: block;">
422
409
  <div class="card highlight" style="border-left-color: var(--green);">
423
410
  <h3>✅ Du bist völlig frei</h3>
424
- <p>Wenn Sie die ArtiFrame-Infrastruktur in den Websites Ihrer Kunden, B2B-Inhouse-Panels, E-Commerce-Infrastrukturen oder SaaS-Projekten verwenden <strong>Sie unterliegen keinen lizenzrechtlichen Beschränkungen.</strong></p>
411
+ <p>Wenn Sie die ArtiFrame-Infrastruktur auf den Websites Ihrer Kunden, in B2B-Inhouse-Panels, E-Commerce-Infrastrukturen oder SaaS-Projekten verwenden<strong>Sie unterliegen keinen lizenzrechtlichen Beschränkungen.</strong></p>
425
412
  <ul>
426
413
  <li>Sie können Ihren Code verschlüsseln und verbergen.</li>
427
414
  <li>Sie können Ihr Projekt zu jedem gewünschten Preis verkaufen.</li>
@@ -429,11 +416,10 @@
429
416
  </ul>
430
417
  </div>
431
418
  </div>
432
- <!-- Tab 2 -->
419
+ Registerkarte 2
433
420
  <div class="tab-content" id="tab-core" style="display: none;">
434
421
  <div class="alert a-info">
435
- <strong>ℹ️ Kernel-Änderung:</strong> ArtiFrames eigene Quellcodes (<code>bin/</code> Und <code>app/</code>) und ändern Sie dies <strong>ein neues Framework, CMS oder Coding-Tool</strong> Wenn Sie as verwenden, gilt der folgende Entscheidungsbaum:
436
- </div>
422
+ <strong>ℹ️ Kernel-Änderung:</strong>ArtiFrames eigene Quellcodes (<code>bin/</code>Und<code>app/</code>) und ändern Sie dies<strong>ein neues Framework, CMS oder Coding-Tool</strong>Wenn Sie as verwenden, gilt der folgende Entscheidungsbaum:</div>
437
423
  <div class="card" style="padding: 0; overflow-x: auto; background: #0d1117; border-radius: 10px;">
438
424
  <canvas height="520" id="licenseCanvasCore" style="min-width: 800px; display: block;" width="1200"></canvas>
439
425
  </div>
@@ -448,87 +434,61 @@
448
434
  el.style.border = '1px solid #30363d';
449
435
  el.style.fontWeight = '400';
450
436
  });
451
-
452
437
  document.getElementById(tabId).style.display = 'block';
453
-
454
438
  btn.style.background = tabId === 'tab-enduser' ? '#00c88c' : '#58a6ff';
455
439
  btn.style.color = '#000';
456
440
  btn.style.fontWeight = '600';
457
441
  btn.style.border = 'none';
458
442
  }
459
443
  </script>
460
-
461
- <h3 style="margin-top: 30px;">Zusätzliche Befehle</h3>
462
- <p><strong>Tabellen auflisten:</strong> Um alle verfügbaren Tabellenvorlagen und ihre Beschreibungen anzuzeigen:</p>
463
- <pre><code>artiframe&gt; <span class="fn">table</span> <span class="st">list</span></code></pre>
464
-
465
- <p><strong>Tabelleninhalt in der Vorschau anzeigen:</strong> Um den SQL-Inhalt im Terminal zu überprüfen, bevor Sie ihn zur <code>schema.sql</code>-Datei hinzufügen, können Sie den <code>check</code> Parameter anhängen:</p>
466
- <pre><code>artiframe&gt; <span class="fn">table:</span><span class="st">users</span> <span class="st">check</span></code></pre>
467
-
468
- </section>
469
- <!-- ====== KURULUM ====== -->
444
+ <h3 style="margin-top: 30px;">Zusätzliche Befehle</h3>
445
+ <p><strong>Auflistungstabellen:</strong>So sehen Sie alle verfügbaren Tabellenvorlagen und Beschreibungen:</p>
446
+ <pre><code>artiframe&gt; <span class="fn">Tisch</span> <span class="st">Liste</span></code></pre>
447
+ <p><strong>Vorschau des Tabelleninhalts:</strong>ein Gemälde<code>schema.sql</code>am Ende des Befehls, um den SQL-Inhalt im Terminal zu prüfen, bevor er zur Datei hinzugefügt wird.<code>check</code>Sie können den Parameter hinzufügen:</p>
448
+ <pre><code>artiframe&gt; <span class="fn">Tisch:</span><span class="st">Benutzer</span> <span class="st">überprüfen</span></code></pre>
449
+ </section>
450
+ ====== INSTALLATION ======
470
451
  <section id="kurulum">
471
452
  <h2>Aufstellen</h2>
472
453
  <p>ArtiFrame CLI wird als globales PHP-Tool installiert. Einmal installiert, in jedem Projekt verwendet.</p>
473
454
  <h3>1. Installieren Sie das CLI-Tool global</h3>
474
- <pre><code><span class="cm"># NPM üzerinden global kurulum</span>
455
+ <pre><code><span class="cm"># Globale Installation über NPM</span>
475
456
  npm install -g @artilingo/artiframe-cli
476
-
477
- <span class="cm"># Kurulumu doğrula</span>
457
+ <span class="cm"># Installation überprüfen</span>
478
458
  artiframe</code></pre>
479
459
  <h3>2. Interaktive Shell</h3>
480
- <p>Nur zum Terminal <code class="ic">artiframe</code> Geben Sie es ein und drücken Sie die Eingabetaste. CLI wird nicht geschlossen; Es öffnet sich eine interaktive Shell, die ständig auf Befehle wartet:</p>
460
+ <p>Nur zum Terminal<code class="ic">artiframe</code>Geben Sie es ein und drücken Sie die Eingabetaste. CLI wird nicht geschlossen; Es öffnet sich eine interaktive Shell, die ständig auf Befehle wartet:</p>
481
461
  <pre><code>==================================================
482
462
  ArtiFrame CLI Interactive Shell v1.0.0
483
463
  ==================================================
484
464
  Type 'help' for commands, or 'exit' to quit.
485
-
486
465
  artiframe&gt; </code></pre>
487
466
  <h3>3. Starten Sie ein neues Projekt</h3>
488
467
  <pre><code>artiframe&gt; new benim-projem</code></pre>
489
- <p>diesen Befehl <code class="ic">benim-projem/</code> Verzeichnis und kopiert die gesamte Skelettstruktur hinein: <code class="ic">app/</code>, <code class="ic">bin/</code>, <code class="ic">config/</code>, <code class="ic">public/</code>, <code class="ic">src/</code>, <code class="ic">.env.example</code> und zuerst <code class="ic">index.php</code> Seite.</p>
468
+ <p>diesen Befehl<code class="ic">benim-projem/</code>Verzeichnis und kopiert die gesamte Skelettstruktur hinein:<code class="ic">app/</code>, <code class="ic">bin/</code>, <code class="ic">config/</code>, <code class="ic">public/</code>, <code class="ic">src/</code>, <code class="ic">.env.example</code>und zuerst<code class="ic">index.php</code>Seite.</p>
490
469
  <h3>4. Umgebungseinstellungen</h3>
491
470
  <pre><code>cp .env.example .env</code></pre>
492
- <p><code class="ic">.env</code> Öffnen Sie Ihre Datei und geben Sie die Datenbank- und Anwendungsinformationen ein. Diese Datei gelangt nie in die Versionskontrolle.</p>
471
+ <p><code class="ic">.env</code>Öffnen Sie Ihre Datei und geben Sie die Datenbank- und Anwendungsinformationen ein. Diese Datei gelangt nie in die Versionskontrolle.</p>
493
472
  <div class="alert a-warn">
494
- <strong>⚠️ Webserver-Einstellung:</strong> Das Dokumentstammverzeichnis von Apache/Nginx <code class="ic">/public/</code> Zum Ordner umleiten. Andere Verzeichnisse sollten niemals nach außen geöffnet sein.
495
- </div>
473
+ <strong>⚠️ Webserver-Einstellung:</strong>Das Dokumentstammverzeichnis von Apache/Nginx<code class="ic">/public/</code>Zum Ordner umleiten. Andere Verzeichnisse sollten niemals nach außen geöffnet sein.</div>
496
474
  </section>
497
- <!-- ====== DİZİN YAPISI ====== -->
475
+ ====== VERZEICHNISSTRUKTUR ======
498
476
  <section id="dizin">
499
477
  <h2>Verzeichnisstruktur</h2>
500
478
  <p>Die Architektur, die zu Beginn des Projekts erstellt wurde; Bietet eine klare Trennung der Verantwortlichkeiten (SoC).</p>
501
479
  <div class="tree">
502
480
  <span class="dir">Projektname/</span>
503
- ├── <span class="dir">App/</span> <span class="note"># Infrastrukturschicht</span>
504
- │ ├── <span class="file">ViewControl.php</span> <span class="note"># Bootstrapper (HTML-Seite) anzeigen</span>
505
- │ ├── <span class="file">ApiControl.php</span> <span class="note"># API-Endpunkt-Bootstrapper</span>
506
- │ ├── <span class="file">Datenbank.php</span> <span class="note"># PDO-basierte Datenbankverbindung</span>
507
- │ ├── <span class="file">DotEnv.php</span> <span class="note"># .env-Reader</span>
508
- │ └── <span class="file">R2Manager.php</span> <span class="note"># Cloudflare R2-Dateimanager</span>
481
+ ├── <span class="dir">App/</span> <span class="note"># Infrastrukturschicht</span>│ ├──<span class="file">ViewControl.php</span> <span class="note"># Bootstrapper (HTML-Seite) anzeigen</span>│ ├──<span class="file">ApiControl.php</span> <span class="note"># API-Endpunkt-Bootstrapper</span>│ ├──<span class="file">Datenbank.php</span> <span class="note"># PDO-basierte Datenbankverbindung</span>│ └──<span class="file">DotEnv.php</span> <span class="note"># .env-Reader</span>
509
482
 
510
- ├── <span class="dir warn">tausend/</span> <span class="note"># ⚠️ Kernsystem – nicht direkt bearbeiten</span>
511
- │ ├── <span class="file">SystemMethod.php</span> <span class="note"># Globale API/Backend-Helfer</span>
512
- │ ├── <span class="file">ViewMethod.php</span> <span class="note"># Globale View/Frontend-Helfer</span>
513
- │ └── <span class="dir">Stubs/</span> <span class="note"># Von CLI verwendete Vorlagendateien</span>
514
- │ ├── view.stub
483
+ ├── <span class="dir warn">tausend/</span> <span class="note"># ⚠️ Kernsystem – nicht direkt bearbeiten</span>│ ├──<span class="file">SystemMethod.php</span> <span class="note"># Globale API/Backend-Helfer</span>│ ├──<span class="file">ViewMethod.php</span> <span class="note"># Globale View/Frontend-Helfer</span>│ └──<span class="dir">Stubs/</span> <span class="note"># Von CLI verwendete Vorlagendateien</span>│ ├── view.stub
515
484
  │ ├── api-standard.stub
516
485
  │ ├── api-switch-case.stub
517
486
  │ └── class.stub
518
487
 
519
- ├── <span class="dir">config/</span> <span class="note"># Konfigurationsdateien</span>
520
- │ └── <span class="file">app-version.php</span> <span class="note"># APP_VERSION- und APP_ENV-Konstanten</span>
488
+ ├──<span class="dir">config/</span> <span class="note"># Konfigurationsdateien</span>│ └──<span class="file">app-version.php</span> <span class="note"># APP_VERSION- und APP_ENV-Konstanten</span>
521
489
 
522
- ├── <span class="dir">öffentlich/</span> <span class="note"># ← Das einzige offene Verzeichnis des Webservers</span>
523
- ├── <span class="dir safe">Vermögenswerte/</span>
524
- │ │ ├── <span class="dir">CSS/</span> <span class="note"># Bestimmte CSS-Dateien anzeigen</span>
525
- │ │ └── <span class="dir">js/</span> <span class="note"># Bestimmte JS-Dateien anzeigen</span>
526
- │ ├── <span class="dir">beinhaltet/</span> <span class="note"># Gemeinsame Komponenten</span>
527
- │ │ ├── head.php
528
- │ │ ├── header.php
529
- │ │ └── footer.php
530
- │ ├── <span class="dir">API/</span> <span class="note"># API-Endpunktdateien</span>
531
- │ └── <span class="file">index.php</span> <span class="note"># Homepage</span>
490
+ ├── <span class="dir">öffentlich/</span> <span class="note"># ← Das einzige offene Verzeichnis des Webservers</span>│ ├──<span class="dir safe">Vermögenswerte/</span>│ │ ├──<span class="dir">CSS/</span> <span class="note"># Bestimmte CSS-Dateien anzeigen</span>│ │ └──<span class="dir">js/</span> <span class="note"># Bestimmte JS-Dateien anzeigen</span>│ ├──<span class="dir">beinhaltet/</span> <span class="note"># Gemeinsame Komponenten</span>│ │ ├── head.php
491
+ ├──<span class="file">head.php</span>│ ├──<span class="file">header.php</span>│ └──<span class="file">footer.php</span>│ ├──<span class="dir">API/</span> <span class="note"># API-Endpunktdateien</span>│ └──<span class="file">index.php</span> <span class="note"># Startseite</span>
532
492
 
533
493
  ├── <span class="dir">src/</span> <span class="note"># Geschäftslogik und Klassen</span>
534
494
  ├── <span class="file">.env</span> <span class="note"># Umgebungsvariablen (nicht in Git enthalten)</span>
@@ -536,65 +496,128 @@ artiframe&gt; </code></pre>
536
496
  └── <span class="file">guide.html</span> <span class="note"># Dieses Dokument</span>
537
497
  </div>
538
498
  <div class="alert a-danger">
539
- <strong>🚫 Berühren Sie nicht das bin/-Verzeichnis:</strong> <code class="ic">bin/</code> Die darin enthaltenen Dateien sind der Kern des Frameworks. Projektspezifische Geschäftslogik wird hier nicht hinzugefügt. Kurse und Dienstleistungen, die Sie hinzufügen werden <code class="ic">src/</code> Unter Infrastrukturkomponenten <code class="ic">app/</code> befindet sich unten.
540
- </div>
499
+ <strong>🚫 Berühren Sie nicht das bin/-Verzeichnis:</strong> <code class="ic">bin/</code>Die darin enthaltenen Dateien sind der Kern des Frameworks. Projektspezifische Geschäftslogik wird hier nicht hinzugefügt. Kurse und Dienstleistungen, die Sie hinzufügen werden<code class="ic">src/</code>Unter Infrastrukturkomponenten<code class="ic">app/</code>befindet sich unten.</div>
541
500
  </section>
542
- <!-- ====== BOOTSTRAPPER ====== -->
501
+ ====== V2.0 ROUTING &amp; ARCHITEKTUR ======
502
+ <section id="v2-routing">
503
+ <h2>Zero-Config-Routing und v2.0.0-Innovationen<span class="tag b-cli">NEU</span></h2>
504
+ <p class="lead">Mit ArtiFrame v2.0.0 hat die Kernstruktur des Frameworks eine viel leichtere, schnellere und entwicklerfreundliche dateibasierte „Zero-Config“-Routing-Architektur erhalten.</p>
505
+ <h3>1. Dateibasiertes automatisches Routing (routeLink)</h3>
506
+ <p>Im Gegensatz zu herkömmlichen Frameworks ermöglicht ArtiFrame eine individuelle Konfiguration für jede Route (z. B.:<code>web.php</code>Es ist nicht erforderlich, dass Sie eine Route hinzufügen. Alle Anfragen<code>public/index.php</code>in der Datei<strong>zu einem einzelnen Gateway</strong>fällt und<code>routeLink()</code>Es wird durch die Methode auf magische Weise verwaltet.</p>
507
+ <div class="card highlight">
508
+ <h4>Wie funktioniert es?</h4>
509
+ <p>Wenn vom Browser<code>/kategori/elektronik/15</code>Wenn die Adresse eingegeben ist, wird das System<code>DOCUMENT_ROOT</code>Durchsucht das Verzeichnis von unten nach oben nach der am längsten passenden PHP-Datei:</p>
510
+ <ol>
511
+ <li><code>/kategori/elektronik/15.php</code>(Nicht gefunden)</li>
512
+ <li><code>/kategori/elektronik.php</code>(Nicht gefunden)</li>
513
+ <li><code>/kategori.php</code>(Gefunden!)</li>
514
+ </ol>
515
+ <p>Beim Ausführen der passenden Datei werden die verbleibenden URL-Fragmente automatisch angezeigt<code>$_GET</code>in Parameter umgewandelt:</p>
516
+ <pre><code>$_GET['params'] = ['elektronik', '15'];
517
+ $_GET['param1'] = 'elektronik';
518
+ $_GET['param2'] = '15';</code></pre>
519
+ </div>
520
+ <div class="alert a-info">
521
+ <strong>💡 Abwärtskompatibilität (ID):</strong>Um die Gewohnheiten alter Versionen nicht zu brechen<code>$_GET['param1']</code>Stets<code>$_GET['id']</code>Es wird auch in synchronisiert. Also direkt auf den Detailseiten<code>$_GET['id']</code>Sie können verwenden</div>
522
+ <div class="card">
523
+ <h4>Link (a) Wie sollten Etiketten sein?</h4>
524
+ <p>Im neuen Routing-System sind Abfragezeichenfolgenparameter im alten Stil (<code>?id=...&amp;token=...</code>) an seiner Stelle<strong>Saubere URL</strong>Struktur verwendet wird. Auf diese Weise werden Ihre Links sowohl lesbarer als auch SEO-freundlicher.</p>
525
+ <pre><code><span class="cm">&lt;!-- ❌ ALTES GEBÄUDE (Sollte nicht genutzt werden) --&gt;</span>
526
+ &lt;a href="user.php?id=123456&amp;token=123j54m23k"&gt;Profili Gör&lt;/a&gt;
527
+
528
+ <span class="cm">&lt;!-- ✅ NEUE STRUKTUR (ArtiFrame Standard) --&gt;</span>
529
+ &lt;a href="/user/123456/123j54m23k"&gt;Profili Gör&lt;/a&gt;</code></pre>
530
+ <p>In der neuen Struktur oben ist der Zugriff auf die Daten auf der entsprechenden Seite ganz einfach:</p>
531
+ <pre><code><span class="cm">// in public/user.php:</span>
532
+ $userId = sanitizeInt($_GET['param1']); <span class="cm">// 123456 (oder $_GET['id'])</span>
533
+ $token = sanitizeString($_GET['param2']); <span class="cm">// 123j54m23k</span></code></pre>
534
+ </div>
535
+ <h3>2. Globale Helfer</h3>
536
+ <p>In älteren Versionen<code>\Bin\SystemMethod::generateToken()</code>oder<code>\Bin\ViewMethod::display()</code>Lange Namensraumaufrufe wie dieser waren erforderlich. Mit v2.0.0 sind alle diese Funktionen im globalen Namespace verfügbar (<code>namespace { }</code>) enthalten war.</p>
537
+ <p>Jetzt können Sie es von überall in Ihrer Anwendung wie folgt aufrufen:</p>
538
+ <pre><code>$token = generateToken();
539
+ echo display($user['name']);
540
+ echo csrfField();</code></pre>
541
+ <h3>3. Strukturelle Veränderungen (Breaking Changes)</h3>
542
+ <div class="alert a-success">
543
+ <strong>🕊️ Keine Refactor-Angst mehr:</strong>Im Gegensatz zu anderen Frameworks kommt es bei der Veröffentlichung von ArtiFrame-Kernaktualisierungen in Ihren Projekten nicht zu tagelangen „Refactor“-Krisen.<code>artiframe new</code>Sobald Sie dies sagen, werden alle Kerndateien dieser Version in Ihr Projekt kopiert. Neu veröffentlichte Versionen (z. B. v3, v4) werden Ihre bestehenden Projekte niemals zum Scheitern bringen; Es funktioniert über Jahre hinweg stabil, unabhängig von den Anforderungen der im Projekt installierten Version.</div>
544
+ <div class="alert a-danger">
545
+ <strong>⚠️ Wichtig:</strong>In Ihren alten Projekten<code>public/index.php</code>Eine Willkommensseite enthielt HTML. Ab v2.0.0<code>index.php</code>Es handelt sich lediglich um eine Router-Datei. Ihr altes Homepage-Design ist jetzt die Standardeinstellung<code>public/landing.php</code>Es wird angeboten über. (Wenn eine leere URL eintrifft, verwendet das System standardmäßig<code>landing.php</code>Weiterleitungen zur Datei).</div>
546
+ <p>Auch bei neuen Projekten<code>artiframe new</code>damit das System automatisch zurückgreifen kann, wenn Sie es ausführen.<code>public/404.php</code>Und<code>public/503.php</code>Es werden Fehlerseiten erzeugt.</p>
547
+ <div class="card">
548
+ <h4>Intelligentes API-Fehlermanagement</h4>
549
+ <p>Bei Fehlern 404 (Seite nicht gefunden) oder 503 (Wartungsmodus).<strong>zum API-Endpunkt</strong>(Zum Beispiel<code>/api/user/get</code>) kommt; Anstatt dem HTTP-Client (mobile Anwendung, Frontend) eine HTML-Seite anzuzeigen, setzt das System den Statuscode und erstellt automatisch einen Standard<strong>JSON-Fehler</strong>kehrt zurück. Dadurch wird sichergestellt, dass Ihre API immer ohne Absturz auf JSON reagieren kann.</p>
550
+ <pre><code>{
551
+ "status": "error",
552
+ "message": "API Endpoint Not Found",
553
+ "data": []
554
+ }</code></pre>
555
+ <div class="alert a-warning" style="margin-top: 15px;">
556
+ <strong>💡 Hinweis: Frontend-Fehler-Trapping</strong><br/>Der Fehlercode (404, 503 usw.) ist nicht in den JSON-Daten enthalten, sondern direkt im Standard<strong>In HTTP-Netzwerkantwort (Statuscode)</strong>rotierend. Auf diese Weise können Sie Fehler auf der Netzwerkebene erkennen, ohne den JSON-Inhalt analysieren zu müssen:</div>
557
+ <pre><code><span class="cm">// API-Beispiel abrufen:</span>
558
+ fetch('/api/user/get').then(response =&gt; {
559
+ if (!response.ok) {
560
+ console.error("HTTP Hatası:", response.status); <span class="cm">// 404 oder 503</span>
561
+ }
562
+ });
563
+
564
+ <span class="cm">// Axios-Beispiel:</span>
565
+ axios.get('/api/user/get').catch(error =&gt; {
566
+ console.error("HTTP Hatası:", error.response.status); <span class="cm">// 404 oder 503</span>
567
+ });</code></pre>
568
+ </div>
569
+ </section>
570
+ ====== BOOTSTRAPPER ======
543
571
  <section id="bootstrapper">
544
- <h2>Bootstrapper-Architektur <span class="tag b-core">Kritik</span></h2>
545
- <p>ArtiFrame verwendet zwei völlig unabhängige Bootstrapper. Diese Architektur <strong>Probleme mit HTML-Headern und Sicherheitslücken</strong> verhindert es radikal.</p>
572
+ <h2>Bootstrapper-Architektur<span class="tag b-core">Kritisch</span></h2>
573
+ <p>ArtiFrame verwendet zwei völlig unabhängige Bootstrapper. Diese Architektur<strong>Probleme mit HTML-Headern und Sicherheitslücken</strong>verhindert es radikal.</p>
546
574
  <div class="grid-2">
547
575
  <div class="card highlight">
548
- <h3><span class="badge b-view">View</span> ViewControl.php</h3>
549
- <p>Es wird für HTML-Seiten (Ansichtsdateien) verwendet. Sitzung beginnt, <code class="ic">ViewMethod</code>Installiert .</p>
550
- <pre><code><span class="cm">// public/profil.php EN ÜSTE, HTML basmadan önce</span>
576
+ <h3><span class="badge b-view">Sicht</span>ViewControl.php</h3>
577
+ <p>Es wird für HTML-Seiten (Ansichtsdateien) verwendet. Sitzung beginnt,<code class="ic">ViewMethod</code>Installiert .</p>
578
+ <pre><code><span class="cm">// public/profile.php NACH OBEN, bevor HTML gedruckt wird</span>
551
579
  <span class="kw">&lt;?php</span>
552
580
  <span class="fn">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>]
553
581
  . <span class="st">'/../app/ViewControl.php'</span>;
554
- <span class="kw">use</span> Bin\ViewMethod;
582
+ <span class="kw">verwenden</span> Bin\ViewMethod;
555
583
  <span class="kw">?&gt;</span>
556
584
  <span class="kw">&lt;!DOCTYPE html&gt;</span>
557
585
  ...</code></pre>
558
586
  </div>
559
587
  <div class="card highlight">
560
- <h3><span class="badge b-api">API</span> ApiControl.php</h3>
561
- <p>Wird für API-Endpunktdateien verwendet. Legt den JSON-Header fest, führt die HTTP-Methodensteuerung durch, <code class="ic">SystemMethod</code>Installiert .</p>
562
- <pre><code><span class="cm">// public/api/kullanici/getir.php</span>
588
+ <h3><span class="badge b-api">API</span>ApiControl.php</h3>
589
+ <p>Wird für API-Endpunktdateien verwendet. Legt den JSON-Header fest, führt die HTTP-Methodensteuerung durch,<code class="ic">SystemMethod</code>Installiert .</p>
590
+ <pre><code><span class="cm">// public/api/user/getir.php</span>
563
591
  <span class="kw">&lt;?php</span>
564
- <span class="cm">// $allowedMethods MUTLAKA require'dan önce tanımlanmalı</span>
565
- <span class="var">$allowedMethods</span> = [<span class="st">'GET'</span>];
566
-
592
+ <span class="cm">// $allowedMethods MUSS vor require definiert werden</span>
593
+ <span class="var">$allowedMethods</span> = [<span class="st">'ERHALTEN'</span>];
567
594
  <span class="fn">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>]
568
595
  . <span class="st">'/../app/ApiControl.php'</span>;
569
-
570
- <span class="kw">use</span> Bin\SystemMethod;</code></pre>
596
+ <span class="kw">verwenden</span> Bin\SystemMethod;</code></pre>
571
597
  </div>
572
598
  </div>
573
599
  <div class="alert a-danger">
574
- <strong>🚫 ViewControl und ApiControl werden niemals gemischt:</strong> Wenn ViewControl für eine API-Datei erforderlich ist, wird möglicherweise ein HTML-Header anstelle eines JSON-Headers zurückgegeben und die gesamte API-Antwort wird beschädigt. Wenn ApiControl auf einer HTML-Seite erforderlich ist, wird die Sitzung nicht gestartet und die Seite wird unterbrochen.
575
- </div>
600
+ <strong>🚫 ViewControl und ApiControl werden niemals gemischt:</strong>Wenn ViewControl für eine API-Datei erforderlich ist, wird möglicherweise ein HTML-Header anstelle eines JSON-Headers zurückgegeben und die gesamte API-Antwort wird beschädigt. Wenn ApiControl auf einer HTML-Seite erforderlich ist, wird die Sitzung nicht gestartet und die Seite wird unterbrochen.</div>
576
601
  </section>
577
- <!-- ====== KURALLAR ====== -->
602
+ ====== REGELN ======
578
603
  <section id="kurallar">
579
- <h2>Regelsatz <span class="tag b-core">Standart</span></h2>
604
+ <h2>Regelsatz<span class="tag b-core">Standard</span></h2>
580
605
  <div class="card">
581
- <h3>Regel 1: data-js-Architektur <span class="badge b-sec">Kritik</span></h3>
582
- <p>JavaScript-Ereignisse sind niemals vorhanden <code class="ic">class</code> oder <code class="ic">id</code> kann darüber nicht abgehört werden. Dies sind visuelle/stilistische Identitäten. Alle JS-Interaktionen <code class="ic">data-js</code> Es wird durch das Attribut verwaltet. JavaScript stürzt nie ab, wenn CSS eine Klasse löscht.</p>
583
- <pre><code><span class="cm">&lt;!-- ❌ Anti-Pattern desteklenmez --&gt;</span>
606
+ <h3>Regel 1: data-js-Architektur<span class="badge b-sec">Kritisch</span></h3>
607
+ <p>JavaScript-Ereignisse sind niemals vorhanden<code class="ic">class</code>oder<code class="ic">id</code>kann darüber nicht abgehört werden. Dies sind visuelle/stilistische Identitäten. Alle JS-Interaktionen<code class="ic">data-js</code>Es wird durch das Attribut verwaltet. JavaScript stürzt nie ab, wenn CSS eine Klasse löscht.</p>
608
+ <pre><code><span class="cm">&lt;!-- ❌ Anti-Pattern nicht unterstützt --&gt;</span>
584
609
  &lt;button id="submitBtn" class="btn"&gt;Gönder&lt;/button&gt;
585
610
  <span class="cm">// JS: document.getElementById('submitBtn').addEventListener(...)</span>
586
-
587
- <span class="cm">&lt;!-- ✅ ArtiFrame Standardı --&gt;</span>
588
- &lt;button class="btn btn-primary" <span class="var">data-js</span>="login-submit"&gt;Gönder&lt;/button&gt;
611
+ <span class="cm">&lt;!-- ✅ ArtiFrame Standard --&gt;</span>
612
+ &lt;button class="btn btn-primary" <span class="var">Daten-js</span>="login-submit"&gt;Gönder&lt;/button&gt;
589
613
  <span class="cm">// JS: document.querySelector('[data-js="login-submit"]').addEventListener(...)</span></code></pre>
590
614
  </div>
591
615
  <div class="card">
592
616
  <h3>Regel 2: Themenarchitektur</h3>
593
- <p>Dunkel/Hell-Modus und Themen, <code class="ic">&lt;html&gt;</code> des Etiketts <code class="ic">data-theme</code> Und <code class="ic">data-mode</code> Es wird über seine Attribute verwaltet. Körperklassen werden nicht verwendet.</p>
594
- <pre><code><span class="cm">&lt;!-- view.stub şablonundan gelen HTML açılış etiketi --&gt;</span>
617
+ <p>Dunkel/Hell-Modus und Themen,<code class="ic">&lt;html&gt;</code>des Etiketts<code class="ic">data-theme</code>Und<code class="ic">data-mode</code>Es wird über seine Attribute verwaltet. Körperklassen werden nicht verwendet.</p>
618
+ <pre><code><span class="cm">&lt;!-- HTML-Öffnungstag aus der view.stub-Vorlage --&gt;</span>
595
619
  &lt;html lang="tr" data-theme="default" data-mode="light"&gt;
596
-
597
- <span class="cm">/* app.css içindeki tema tanımı */</span>
620
+ <span class="cm">/* Theme-Definition in app.css */</span>
598
621
  html[data-theme="default"][data-mode="dark"] {
599
622
  --bg-color: #0b0c0e;
600
623
  --text-main: #ffffff;
@@ -606,80 +629,69 @@ html[data-theme="default"][data-mode="light"] {
606
629
  </div>
607
630
  <div class="card">
608
631
  <h3>Regel 3: Sicherer Datenfluss</h3>
609
- <p>Alle aus der Datenbank kommenden Daten werden verarbeitet, bevor sie an das DOM übertragen werden. <code class="ic">display()</code> Es ist mit umwickelt. Alle an die API eingehenden Daten werden vor ihrer Verarbeitung verarbeitet. <code class="ic">sanitizeString()</code> oder <code class="ic">sanitizeInt()</code> Es wird mit gereinigt.</p>
632
+ <p>Alle aus der Datenbank kommenden Daten werden verarbeitet, bevor sie an das DOM übertragen werden.<code class="ic">display()</code>Es ist mit umwickelt. Alle an die API eingehenden Daten werden vor ihrer Verarbeitung verarbeitet.<code class="ic">sanitizeString()</code>oder<code class="ic">sanitizeInt()</code>Es wird mit gereinigt.</p>
610
633
  </div>
611
634
  <div class="card">
612
635
  <h3>Regel 4: Fehlerbehandlung mit APP_ENV</h3>
613
- <p><code class="ic">.env</code> in der Datei <code class="ic">APP_ENV</code> Der Wert bestimmt die Fehlersichtbarkeit. In der Produktion wird dem Benutzer keine Fehlermeldung angezeigt.</p>
614
- <pre><code><span class="cm">// config/app-version.php</span>
615
- define(<span class="st">'APP_ENV'</span>, (int)<span class="var">$_ENV</span>[<span class="st">'APP_ENV'</span>]); <span class="cm">// 1=Debug, 0=Production</span>
616
-
617
- <span class="kw">if</span> (APP_ENV === <span class="nu">1</span>) {
636
+ <p><code class="ic">.env</code>in der Datei<code class="ic">APP_ENV</code>Der Wert bestimmt die Fehlersichtbarkeit. In der Produktion wird dem Benutzer keine Fehlermeldung angezeigt.</p>
637
+ <pre><code><span class="cm">//config/app-version.php</span>
638
+ define(<span class="st">'APP_ENV'</span>, (int)<span class="var">$_ENV</span>[<span class="st">'APP_ENV'</span>]); <span class="cm">// 1=Debug, 0=Produktion</span>
639
+ <span class="kw">Wenn</span> (APP_ENV === <span class="nu">1</span>) {
618
640
  ini_set(<span class="st">'display_errors'</span>, <span class="nu">1</span>);
619
641
  error_reporting(E_ALL);
620
- } <span class="kw">else</span> {
642
+ } <span class="kw">anders</span> {
621
643
  ini_set(<span class="st">'display_errors'</span>, <span class="nu">0</span>);
622
644
  }</code></pre>
623
645
  </div>
624
646
  </section>
625
- <!-- ====== CLI GİRİŞ ====== -->
647
+ ====== CLI-LOGIN ======
626
648
  <section id="cli-giris">
627
649
  <h2>CLI-Ökosystem</h2>
628
- <p>ArtiFrame CLI zum Terminal <code class="ic">artiframe</code> Öffnet bei der Eingabe eine interaktive Shell. Alle Befehle werden innerhalb dieser Shell ausgeführt. Befehle können auch einmal ausgeführt werden.</p>
629
- <pre><code><span class="cm"># İnteraktif mod (önerilen)</span>
650
+ <p>ArtiFrame CLI zum Terminal<code class="ic">artiframe</code>Öffnet bei der Eingabe eine interaktive Shell. Alle Befehle werden innerhalb dieser Shell ausgeführt. Befehle können auch einmal ausgeführt werden.</p>
651
+ <pre><code><span class="cm"># Interaktiver Modus (empfohlen)</span>
630
652
  artiframe
631
653
  artiframe&gt; make:view admin/kullanicilar.php
632
-
633
- <span class="cm"># Tek seferlik mod</span>
654
+ <span class="cm"># Einmaliger Modus</span>
634
655
  artiframe make:view admin/kullanicilar.php</code></pre>
635
656
  </section>
636
- <!-- new -->
657
+ neu
637
658
  <section id="cli-new">
638
- <h2><code>new</code> <span class="tag b-cli">CLI Komutu</span></h2>
639
- <p>Erstellt ein neues ArtiFrame-Projekt. Wenn dieser Befehl ausgeführt wird, wird ein interaktiver Assistent gestartet und Ihr Projekt <code>composer.json</code> Es fragt Sie nach den grundlegenden Informationen, die für die Konfiguration erforderlich sind (Paketname, Autor, Lizenztyp usw.). Sobald alle Dateien kopiert sind, werden Abhängigkeiten automatisch installiert.</p>
640
- <pre><code>artiframe&gt; <span class="fn">new</span> <span class="st">benim-projem</span>
641
-
642
- <span class="cm"> ╔══════════════════════════════════════════════════╗
643
- ║ ArtiFrame Project Builder ║
644
- ╚══════════════════════════════════════════════════╝
645
-
646
- Proje : benim-projem
647
- Konum : C:/artiframe/benim-projem</span>
648
-
649
- <span class="kw">?</span> Package name (e.g. vendor/project) <span class="st">[artiframe/benim-projem]</span>:
650
- <span class="kw">?</span> Description <span class="st">[ArtiFrame Core PHP Application]</span>:
659
+ <h2><code>new</code> <span class="tag b-cli">CLI-Befehl</span></h2>
660
+ <p>Erstellt ein neues ArtiFrame-Projekt. Wenn dieser Befehl ausgeführt wird, wird ein interaktiver Assistent gestartet und Ihr Projekt<code>composer.json</code>Es fragt Sie nach den grundlegenden Informationen, die für die Konfiguration erforderlich sind (Paketname, Autor, Lizenztyp usw.). Sobald alle Dateien kopiert sind, werden Abhängigkeiten automatisch installiert.</p>
661
+ <pre><code>artiframe&gt; <span class="fn">neu</span> <span class="st">mein-projekt</span>
662
+ <span class="cm">╔═════════════════════════ ═════════════════════════╗
663
+ ArtiFrame Project Builder ║
664
+ ╚═════════════════════════ ═════════════════════════╝
665
+ Projekt: mein-projekt
666
+ Speicherort: C:/artiframe/my-project</span>
667
+ <span class="kw">?</span> Package name (e.g. vendor/project) <span class="st">[artiframe/mein-projekt]</span>:
668
+ <span class="kw">?</span> Description <span class="st">[ArtiFrame Core PHP-Anwendung]</span>:
651
669
  <span class="kw">?</span> Author name <span class="st">[Artilingo]</span>:
652
670
  <span class="kw">?</span> Author homepage <span class="st">[https://artilingo.com]</span>:
653
- <span class="kw">?</span> Type (project, library, composer-plugin) <span class="st">[project]</span>:
654
- <span class="kw">?</span> License (AGPL-3.0-or-later, MIT, Apache-2.0, GPL-2.0-or-later, GPL-3.0-or-later, BSD-2-Clause, BSD-3-Clause, ISC, proprietary, none) <span class="st">[AGPL-3.0-or-later]</span>:
655
-
656
- <span class="cm"> ┌─────────────────────────────────────────────────┐
657
- 📂 Faz 1/4 Kopyalanıyor...
658
- │ İşlenecek Dosya: 42 Adet │
659
- └─────────────────────────────────────────────────┘
660
- [████████████████████] 100% (42/42) docs/kilavuz.html...
661
-
662
- ┌─────────────────────────────────────────────────┐
663
- │ 📂 Faz 2/4 — Dizinler Oluşturuluyor... │
664
- │ İşlenecek Dosya: 10 Adet │
665
- └─────────────────────────────────────────────────┘
666
- [████████████████████] 100% (52/52) public/assets/images/...
667
-
668
- ┌─────────────────────────────────────────────────┐
669
- │ 📂 Faz 3/4 Dinamik Dosyalar Üretiliyor...
670
- │ İşlenecek Dosya: 14 Adet │
671
- └─────────────────────────────────────────────────┘
672
- [████████████████████] 100% (66/66) .agents/AGENTS.md...
673
-
674
- ┌─────────────────────────────────────────────────┐
675
- │ 📦 Faz 4/4 Bağımlılıklar Kuruluyor (Composer)│
676
- └─────────────────────────────────────────────────┘</span>
677
- <span class="cm">Installing dependencies from lock file (including require-dev)...</span>
678
-
679
- <span class="cm"> ╔══════════════════════════════════════════════════╗
680
- ║ Tebrikler! Proje başarıyla oluşturuldu. ║
681
- ╚══════════════════════════════════════════════════╝</span>
682
-
671
+ <span class="kw">?</span> Type (project, library, composer-plugin) <span class="st">[Projekt]</span>:
672
+ <span class="kw">?</span> License (AGPL-3.0-or-later, MIT, Apache-2.0, GPL-2.0-or-later, GPL-3.0-or-later, BSD-2-Clause, BSD-3-Clause, ISC, proprietary, none) <span class="st">[AGPL-3.0-oder höher]</span>:
673
+ <span class="cm">┌──────────────────────── ─────────────────────────┐
674
+ 📂 Phase 1/4 – Kopieren... │
675
+ Zu verarbeitende Dateien: 42 Stück
676
+ └──────────────────────── ─────────────────────────┘
677
+ [████████████████████] 100 % (42/42) docs/guide.html...
678
+ ┌──────────────────────── ─────────────────────────┐
679
+ │ 📂 Phase 2/4 – Verzeichnisse erstellen... │
680
+ │ Zu verarbeitende Dateien: 10 Stück │
681
+ └──────────────────────── ─────────────────────────┘
682
+ [████████████████████] 100 % (52/52) öffentlich/Vermögenswerte/Bilder/...
683
+ ┌──────────────────────── ─────────────────────────┐
684
+ 📂 Phase 3/4 – Dynamische Dateien generieren... │
685
+ │ Zu verarbeitende Dateien: 14 Stück │
686
+ └──────────────────────── ─────────────────────────┘
687
+ [████████████████████] 100 % (66/66) .agents/AGENTS.md...
688
+ ┌──────────────────────── ─────────────────────────┐
689
+ │ 📦 Phase 4/4 – Abhängigkeiten installieren (Composer)│
690
+ └──────────────────────── ─────────────────────────┘</span>
691
+ <span class="cm">Abhängigkeiten aus der Sperrdatei installieren (einschließlich require-dev) ...</span>
692
+ <span class="cm">╔═════════════════════════ ═════════════════════════╗
693
+ Herzlichen Glückwunsch! Das Projekt wurde erfolgreich erstellt. ║
694
+ ╚═════════════════════════ ═════════════════════════╝</span>
683
695
  📂 benim-projem/
684
696
  │ ├── 📂 bin/
685
697
  │ ├── 📂 config/
@@ -693,247 +705,238 @@ artiframe make:view admin/kullanicilar.php</code></pre>
693
705
  │ └── 📄 kilavuz.html [125 KB]
694
706
 
695
707
  Sonraki Adım: Lütfen .env dosyasındaki ortam değişkenlerini yapılandırın.
696
-
697
708
  </code></pre>
698
- <p>Sobald das Projekt erstellt ist, führt ArtiFrame CLI es für Sie aus. <strong>öffnet automatisch ein neues Terminalfenster</strong>, geht in dieses Verzeichnis und startet das auf dieses Projekt fokussierte Tool neu. Sie können das alte Terminalfenster schließen.</p>
709
+ <p>Sobald das Projekt erstellt ist, führt ArtiFrame CLI es für Sie aus.<strong>öffnet automatisch ein neues Terminalfenster</strong>, geht in dieses Verzeichnis und startet das auf dieses Projekt fokussierte Tool neu. Sie können das alte Terminalfenster schließen.</p>
699
710
  <p>Skelettstruktur erstellt:</p>
700
- <div class="tree" style="font-size:0.82rem; line-height:1.7">
701
- Projektname/
711
+ <div class="tree" style="font-size:0.82rem; line-height:1.7">Projektname/
702
712
  ├── app/ (ViewControl.php, ApiControl.php, Database.php, DotEnv.php)
703
713
  ├── bin/ (SystemMethod.php, ViewMethod.php, stubs/)
704
714
  ├── config/ (app-version.php)
705
- ├── public/ (index.php, Assets/, Includes/, API/)
715
+ ├── public/ (index.php, asset/, Includes/, api/)
706
716
  ├── src/
707
717
  ├── .env.example
708
- └──guide.html
709
- </div>
718
+ └──guide.html</div>
719
+ </section>
720
+ Upgrade
721
+ <section id="cli-upgrade">
722
+ <h2><code>upgrade</code> <span class="tag b-cli">CLI-Befehl</span></h2>
723
+ <p>Damit können Sie neue Funktionen im ArtiFrame CLI-Tool, die Sie global über NPM aktualisiert haben, sicher in Ihr bestehendes Projekt integrieren.</p>
724
+ <pre><code>artiframe&gt; <span class="fn">Upgrade</span></code></pre>
725
+ <ul style="margin-left: 20px; margin-bottom: 15px; line-height: 1.6;">
726
+ <li>Nur<code>app/</code>Und<code>bin/</code>mit Kernordnern<code>src/Service/</code>Aktualisiert die darunter liegenden festen Dienstklassen (falls vorhanden).</li>
727
+ <li>Wo sich Ihre Geschäftslogik befindet<code>src/</code>, <code>public/</code>Und<code>config/</code>Auf jeden Fall in Ihren Verzeichnissen<strong>unantastbar</strong>(damit Ihr Projekt nicht beschädigt wird).</li>
728
+ <li><strong>Firewall:</strong>Wenn Ihr Projekt v1.x ist und<code>public/index.php</code>Wenn Ihre Datei nicht zur neuen Router-Struktur passt, wird eine Fehlermeldung angezeigt und Sie werden nach dem Namen Ihrer vorhandenen index.php gefragt.<code>landing.php</code>Sie werden aufgefordert, es in zu ändern.</li>
729
+ <li><strong>Änderungshinweis:</strong>wenn vorher<code>bin/</code>Wenn Sie die Kernfunktionen unter manuell geändert haben<strong>eingeben</strong>Es fordert eine manuelle Bestätigung (Backup-Warnung) mit der Schaltfläche an.</li>
730
+ <li><strong>Smart-Change-Bericht (Diff):</strong>Wenn die Aktualisierung abgeschlossen ist, wird auf dem Terminal ein detaillierter Bericht über die neu hinzugefügten oder geänderten (aktualisierten) Dateien in Ihrem Projekt gedruckt.</li>
731
+ <li><strong>Funktionsebenenanalyse:</strong>Wenn es sich bei der aktualisierten Datei um eine<code>.php</code>Die Datei vergleicht die Methoden in der alten und der neuen Datei. Wenn eine neue Funktion hinzugefügt wird, wird der Bericht<code>[YENİ FONKSİYON] ad()</code>Es weist Sie mit einer besonderen Warnung darauf hin, die Dokumentation zu lesen.</li>
732
+ </ul>
710
733
  </section>
711
- <!-- make:view -->
734
+ make:view
712
735
  <section id="cli-view">
713
- <h2><code>make:view</code> <span class="tag b-cli">CLI Komutu</span></h2>
714
- <p>Erstellt eine neue Seitendatei (Ansichtsdatei) und ihre benutzerdefinierten CSS/JS-Assets. Assets werden automatisch mit der Seite verknüpft und <code class="ic">?v=APP_VERSION</code> Cache-Busting wird mit angewendet.</p>
715
- <pre><code>artiframe&gt; <span class="fn">make:view</span> <span class="st">admin/kullanicilar.php</span></code></pre>
736
+ <h2><code>make:view</code> <span class="tag b-cli">CLI-Befehl</span></h2>
737
+ <p>Erstellt eine neue Seitendatei (Ansichtsdatei) und ihre benutzerdefinierten CSS/JS-Assets. Assets werden automatisch mit der Seite verknüpft und<code class="ic">?v=APP_VERSION</code>Cache-Busting wird mit angewendet.</p>
738
+ <pre><code>artiframe&gt; <span class="fn">make:view</span> <span class="st">admin/users.php</span></code></pre>
716
739
  <p>Erstellte Dateien:</p>
717
- <pre><code><span class="cm">✔ public/admin/kullanicilar.php</span>
718
- <span class="cm">✔ public/assets/css/admin/kullanicilar.css</span>
719
- <span class="cm">✔ public/assets/js/admin/kullanicilar.js</span></code></pre>
740
+ <pre><code><span class="cm">✔ public/admin/users.php</span>
741
+ <span class="cm">✔ public/assets/css/admin/users.css</span>
742
+ <span class="cm">✔ public/assets/js/admin/users.js</span></code></pre>
720
743
  <p>Am Anfang der erstellten Ansichtsdatei ist ViewControl erforderlich, Kopf-/Kopf-/Fußzeilen-Includes werden hinzugefügt und CSS/JS-Links werden mit Cache-Busting verbunden.</p>
721
744
  </section>
722
- <!-- make:api -->
745
+ make:api
723
746
  <section id="cli-api">
724
- <h2><code>make:api</code> <span class="tag b-cli">CLI Komutu</span></h2>
725
- <p>Es erstellt eine API-Endpunktdatei, indem es eine von zwei verschiedenen Vorlagen auswählt. Mit jeder neuen API-Datei <code class="ic">$allowedMethods</code> variabel und <code class="ic">ApiControl.php</code> Es wird mit der erforderlichen Vorbereitung geliefert.</p>
747
+ <h2><code>make:api</code> <span class="tag b-cli">CLI-Befehl</span></h2>
748
+ <p>Es erstellt eine API-Endpunktdatei, indem es eine von zwei verschiedenen Vorlagen auswählt. Mit jeder neuen API-Datei<code class="ic">$allowedMethods</code>variabel und<code class="ic">ApiControl.php</code>Es wird mit der erforderlichen Vorbereitung geliefert.</p>
726
749
  <div class="card">
727
- <h3><span class="badge b-api">standart</span> Single-Action-API</h3>
750
+ <h3><span class="badge b-api">Standard</span>– Single-Action-API</h3>
728
751
  <p>Für Endpunkte, die einen einzelnen Job ausführen (Anmelden, Senden, Löschen). Geschäftslogik wird direkt geschrieben.</p>
729
- <pre><code>artiframe&gt; <span class="fn">make:api</span> <span class="st">standart</span> <span class="st">api/auth/giris.php</span></code></pre>
752
+ <pre><code>artiframe&gt; <span class="fn">make:api</span> <span class="st">Standard</span> <span class="st">api/auth/login.php</span></code></pre>
730
753
  <pre><code><span class="kw">&lt;?php</span>
731
- <span class="var">$allowedMethods</span> = [<span class="st">'POST'</span>]; <span class="cm">// Sadece POST kabul et</span>
754
+ <span class="var">$allowedMethods</span> = [<span class="st">'POST'</span>]; <span class="cm">// Nur POST akzeptieren</span>
732
755
  <span class="fn">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/../app/ApiControl.php'</span>;
733
-
734
- <span class="kw">use</span> Bin\SystemMethod;
735
-
736
- <span class="cm">// İş mantığı buraya...</span>
737
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'success'</span>], <span class="nu">200</span>);</code></pre>
756
+ <span class="kw">verwenden</span> Bin\SystemMethod;
757
+ <span class="cm">//Geschäftslogik hier...</span>
758
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Erfolg'</span>], <span class="nu">200</span>);</code></pre>
738
759
  </div>
739
760
  <div class="card">
740
- <h3><span class="badge b-api">switch-case</span> Multi-Action-API</h3>
741
- <p>Eine Struktur, die CRUD-Vorgänge für ein Modul in einem einzelnen Endpunkt verwaltet. <code class="ic">action</code> Der Parameter bestimmt, welcher Vorgang ausgeführt wird.</p>
742
- <pre><code>artiframe&gt; <span class="fn">make:api</span> <span class="st">switch-case</span> <span class="st">api/kullanici/yonet.php</span></code></pre>
761
+ <h3><span class="badge b-api">Schaltergehäuse</span>– Multi-Action-API</h3>
762
+ <p>Eine Struktur, die CRUD-Vorgänge für ein Modul in einem einzelnen Endpunkt verwaltet.<code class="ic">action</code>Der Parameter bestimmt, welcher Vorgang ausgeführt wird.</p>
763
+ <pre><code>artiframe&gt; <span class="fn">make:api</span> <span class="st">Schaltergehäuse</span> <span class="st">api/user/admin.php</span></code></pre>
743
764
  <pre><code><span class="kw">&lt;?php</span>
744
765
  <span class="var">$allowedMethods</span> = [<span class="st">'POST'</span>];
745
766
  <span class="fn">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/../app/ApiControl.php'</span>;
746
-
747
- <span class="kw">use</span> Bin\SystemMethod;
748
-
749
- <span class="var">$action</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'action'</span>] ?? <span class="st">''</span>);
750
-
751
- <span class="kw">switch</span> (<span class="var">$action</span>) {
752
- <span class="kw">case</span> <span class="st">'create'</span>:
753
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'success'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Oluşturuldu.'</span>], <span class="nu">200</span>);
754
- <span class="kw">break</span>;
755
- <span class="kw">case</span> <span class="st">'update'</span>:
756
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'success'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Güncellendi.'</span>], <span class="nu">200</span>);
757
- <span class="kw">break</span>;
758
- <span class="kw">case</span> <span class="st">'delete'</span>:
759
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'success'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Silindi.'</span>], <span class="nu">200</span>);
760
- <span class="kw">break</span>;
761
- <span class="kw">default</span>:
762
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'error'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Geçersiz action.'</span>], <span class="nu">400</span>);
767
+ <span class="kw">verwenden</span> Bin\SystemMethod;
768
+ <span class="var">$Aktion</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'Aktion'</span>] ?? <span class="st">''</span>);
769
+ <span class="kw">schalten</span> (<span class="var">$Aktion</span>) {
770
+ <span class="kw">Fall</span> <span class="st">'erstellen'</span>:
771
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Erfolg'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Erstellt.“</span>], <span class="nu">200</span>);
772
+ <span class="kw">brechen</span>;
773
+ <span class="kw">Fall</span> <span class="st">'aktualisieren'</span>:
774
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Erfolg'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Aktualisiert.“</span>], <span class="nu">200</span>);
775
+ <span class="kw">brechen</span>;
776
+ <span class="kw">Fall</span> <span class="st">'löschen'</span>:
777
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Erfolg'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Gelöscht.“</span>], <span class="nu">200</span>);
778
+ <span class="kw">brechen</span>;
779
+ <span class="kw">Standard</span>:
780
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Fehler'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Ungültige Aktion.“</span>], <span class="nu">400</span>);
763
781
  }</code></pre>
764
782
  </div>
765
783
  </section>
766
- <!-- make:class -->
784
+ make:class
767
785
  <section id="cli-class">
768
- <h2><code>make:class</code> <span class="tag b-cli">CLI Komutu</span></h2>
769
- <p>Es erstellt eine neue PHP-Klassendatei mit dem Namensraum und dem Klassenbaustein. Der Namespace wird automatisch anhand des Klassenpfads ermittelt. Wenn <strong>App/</strong> Und <strong>src/</strong> draußen (z.B <strong>Privat/</strong>) Wird ein Verzeichnis verwendet, läuft das CLI-Tool im Hintergrund <code>composer dump-autoload</code> führt das Skript automatisch aus.</p>
786
+ <h2><code>make:class</code> <span class="tag b-cli">CLI-Befehl</span></h2>
787
+ <p>Es erstellt eine neue PHP-Klassendatei mit dem Namensraum und dem Klassenbaustein. Der Namespace wird automatisch anhand des Klassenpfads ermittelt. Wenn<strong>App/</strong>Und<strong>src/</strong>draußen (z.B<strong>Privat/</strong>) Wird ein Verzeichnis verwendet, läuft das CLI-Tool im Hintergrund<code>composer dump-autoload</code>führt das Skript automatisch aus.</p>
770
788
  <pre><code>artiframe&gt; <span class="fn">make:class</span> <span class="st">src/Service/EmailService.php</span></code></pre>
771
789
  <p>Wenn das Klassenverzeichnis nicht angegeben ist, gibt der Befehl einen Fehler zurück:</p>
772
790
  <pre><code>artiframe&gt; <span class="fn">make:class</span>
773
791
  ❌ Hata: Sınıfın oluşturulacağı dizin belirtilmeli! (örn: /app veya /src)
774
792
  Example: /src/Service/PaymentService</code></pre>
775
793
  </section>
776
-
777
- <!-- table: -->
778
- <section id="cli-table">
779
- <h2><code>table:</code> <span class="tag b-cli">CLI-Befehl</span></h2>
780
- <p>Ermöglicht das schnelle Anhängen von standardmäßigen und relationalen Datenbanktabellen an die <code>schema.sql</code>-Datei Ihres Projekts. Die Vorlagen werden aus der globalen Datei <code>stubs/sql.stub</code> gelesen.</p>
781
- <pre><code>artiframe&gt; <span class="fn">table:</span><span class="st">users</span></code></pre>
782
- <p>Derzeit unterstützte Standardtabellen:</p>
783
- <div class="table-tabs-container" style="margin-top: 20px;">
784
- <div class="tabs-header" style="display: flex; gap: 10px; margin-bottom: 10px; overflow-x: auto; padding-bottom: 5px;">
785
- <button class="table-tab-btn active" onclick="switchTableTab('tab-users', this)" style="white-space: nowrap; padding: 10px 20px; background: #00c88c; color: #000; font-weight: 600; border: none; border-radius: 5px; cursor: pointer;">users</button>
786
- <button class="table-tab-btn" onclick="switchTableTab('tab-sessions', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">user_sessions</button>
787
- <button class="table-tab-btn" onclick="switchTableTab('tab-prefs', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">user_preferences</button>
788
- </div>
789
-
790
- <!-- Tab: users -->
791
- <div id="tab-users" class="table-tab-content" style="display: block;">
792
- <pre><code><span class="kw">CREATE TABLE `users` (
793
- `id` binary(16) NOT NULL,
794
- `email` varchar(255) NOT NULL,
795
- `password` varchar(255) NOT NULL,
796
- `name` varchar(255) DEFAULT NULL,
797
- `role` enum('user','admin','moderator') NOT NULL DEFAULT 'user',
798
- `status` tinyint(1) NOT NULL DEFAULT '1',
799
- `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
800
- `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
801
- PRIMARY KEY (`id`),
802
- UNIQUE KEY `email` (`email`)
803
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
804
- </div>
805
-
806
- <!-- Tab: user_sessions -->
807
- <div id="tab-sessions" class="table-tab-content" style="display: none;">
808
- <pre><code><span class="kw">CREATE TABLE `user_sessions` (
809
- `id` binary(16) NOT NULL,
810
- `user_id` binary(16) NOT NULL,
811
- `token` varchar(255) NOT NULL,
812
- `ip_address` varchar(45) DEFAULT NULL,
813
- `user_agent` varchar(255) DEFAULT NULL,
814
- `expires_at` timestamp NULL DEFAULT NULL,
815
- `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
816
- PRIMARY KEY (`id`),
817
- UNIQUE KEY `token` (`token`),
818
- KEY `user_id` (`user_id`),
819
- CONSTRAINT `fk_user_sessions_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
820
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
821
- </div>
822
-
823
- <!-- Tab: user_preferences -->
824
- <div id="tab-prefs" class="table-tab-content" style="display: none;">
825
- <pre><code><span class="kw">CREATE TABLE `user_preferences` (
826
- `id` binary(16) NOT NULL,
827
- `user_id` binary(16) NOT NULL,
828
- `language` varchar(10) NOT NULL DEFAULT 'tr',
829
- `theme` varchar(20) NOT NULL DEFAULT 'light',
830
- `push_notifications` tinyint(1) NOT NULL DEFAULT '1',
831
- `email_notifications` tinyint(1) NOT NULL DEFAULT '1',
832
- `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
833
- `updated_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
834
- PRIMARY KEY (`id`),
835
- UNIQUE KEY `user_id` (`user_id`),
836
- CONSTRAINT `fk_user_prefs_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
837
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
838
- </div>
839
- </div>
840
-
841
- <script>
842
- function switchTableTab(tabId, btn) {
843
- const container = btn.closest('.table-tabs-container');
844
- container.querySelectorAll('.table-tab-content').forEach(el => el.style.display = 'none');
845
- container.querySelectorAll('.table-tab-btn').forEach(el => {
846
- el.style.background = '#1c2128';
847
- el.style.color = '#fff';
848
- el.style.border = '1px solid #30363d';
849
- el.style.fontWeight = '400';
850
- });
851
-
852
- container.querySelector('#' + tabId).style.display = 'block';
853
- btn.style.background = '#00c88c';
854
- btn.style.color = '#000';
855
- btn.style.fontWeight = '600';
856
- btn.style.border = 'none';
857
- }
858
- </script>
859
-
860
- <h3 style="margin-top: 30px;">Zusätzliche Befehle</h3>
861
- <p><strong>Tabellen auflisten:</strong> Um alle verfügbaren Tabellenvorlagen und ihre Beschreibungen anzuzeigen:</p>
862
- <pre><code>artiframe&gt; <span class="fn">table</span> <span class="st">list</span></code></pre>
863
-
864
- <p><strong>Tabelleninhalt in der Vorschau anzeigen:</strong> Um den SQL-Inhalt im Terminal zu überprüfen, bevor Sie ihn zur <code>schema.sql</code>-Datei hinzufügen, können Sie den <code>check</code> Parameter anhängen:</p>
865
- <pre><code>artiframe&gt; <span class="fn">table:</span><span class="st">users</span> <span class="st">check</span></code></pre>
866
-
867
- </section>
868
-
869
- <!-- cli v -->
794
+ Tisch:
795
+ <section id="cli-table">
796
+ <h2><code>table:</code> <span class="tag b-cli">CLI-Befehl</span></h2>
797
+ <p>in Ihrem Projekt<code>schema.sql</code>Es ermöglicht Ihnen, der Datei schnell Standard- und relationale Datenbanktabellen hinzuzufügen. Vorlagen global<code>stubs/sql.stub</code>wird aus der Datei gelesen.</p>
798
+ <pre><code>artiframe&gt; <span class="fn">Tisch:</span><span class="st">Benutzer</span></code></pre>
799
+ <p>Derzeit unterstützte Standardtabellen:</p>
800
+ <div class="table-tabs-container" style="margin-top: 20px;">
801
+ <div class="tabs-header" style="display: flex; gap: 10px; margin-bottom: 10px; overflow-x: auto; padding-bottom: 5px;">
802
+ <button class="table-tab-btn active" onclick="switchTableTab('tab-users', this)" style="white-space: nowrap; padding: 10px 20px; background: #00c88c; color: #000; font-weight: 600; border: none; border-radius: 5px; cursor: pointer;">Benutzer</button>
803
+ <button class="table-tab-btn" onclick="switchTableTab('tab-sessions', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">user_sessions</button>
804
+ <button class="table-tab-btn" onclick="switchTableTab('tab-prefs', this)" style="white-space: nowrap; padding: 10px 20px; background: #1c2128; color: #fff; border: 1px solid #30363d; border-radius: 5px; cursor: pointer;">user_preferences</button>
805
+ </div>
806
+ Tab: Benutzer
807
+ <div class="table-tab-content" id="tab-users" style="display: block;">
808
+ <pre><code><span class="kw">TABELLE „Benutzer“ ERSTELLEN (
809
+ id binär(16) NICHT NULL,
810
+ `email` varchar(255) NOT NULL,
811
+ „Passwort“ varchar(255) NICHT NULL,
812
+ `name` varchar(255) DEFAULT NULL,
813
+ `role` enum('user','admin','moderator') NOT NULL DEFAULT 'user',
814
+ `status` tinyint(1) NOT NULL DEFAULT '1',
815
+ `created_at` Zeitstempel NULL DEFAULT CURRENT_TIMESTAMP,
816
+ `updated_at` Zeitstempel NULL STANDARD CURRENT_TIMESTAMP BEI UPDATE CURRENT_TIMESTAMP,
817
+ PRIMÄRSCHLÜSSEL („id“),
818
+ EINZIGARTIGER SCHLÜSSEL „email“ („email“)
819
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
820
+ </div>
821
+ Tab: user_sessions
822
+ <div class="table-tab-content" id="tab-sessions" style="display: none;">
823
+ <pre><code><span class="kw">TABELLE „user_sessions“ ERSTELLEN (
824
+ „id“ binär(16) NICHT NULL,
825
+ „user_id“ binär(16) NICHT NULL,
826
+ „Token“ varchar(255) NICHT NULL,
827
+ `ip_address` varchar(45) DEFAULT NULL,
828
+ `user_agent` varchar(255) DEFAULT NULL,
829
+ `expires_at` Zeitstempel NULL STANDARD NULL,
830
+ `created_at` Zeitstempel NULL DEFAULT CURRENT_TIMESTAMP,
831
+ PRIMÄRSCHLÜSSEL („id“),
832
+ EINZIGARTIGER SCHLÜSSEL „token“ („token“),
833
+ SCHLÜSSEL `user_id` (`user_id`),
834
+ CONSTRAINT `fk_user_sessions_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
835
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
836
+ </div>
837
+ Tab: Benutzereinstellungen
838
+ <div class="table-tab-content" id="tab-prefs" style="display: none;">
839
+ <pre><code><span class="kw">TABELLE „user_preferences“ ERSTELLEN (
840
+ „id“ binär(16) NICHT NULL,
841
+ „user_id“ binär(16) NICHT NULL,
842
+ `Sprache` varchar(10) NOT NULL DEFAULT 'tr',
843
+ `theme` varchar(20) NOT NULL DEFAULT 'light',
844
+ `push_notifications` tinyint(1) NOT NULL DEFAULT '1',
845
+ `email_notifications` tinyint(1) NOT NULL DEFAULT '1',
846
+ `created_at` Zeitstempel NULL DEFAULT CURRENT_TIMESTAMP,
847
+ `updated_at` Zeitstempel NULL STANDARD CURRENT_TIMESTAMP BEI UPDATE CURRENT_TIMESTAMP,
848
+ PRIMÄRSCHLÜSSEL („id“),
849
+ EINZIGARTIGER SCHLÜSSEL `user_id` (`user_id`),
850
+ CONSTRAINT `fk_user_prefs_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
851
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;</span></code></pre>
852
+ </div>
853
+ </div>
854
+ <script>
855
+ function switchTableTab(tabId, btn) {
856
+ const container = btn.closest('.table-tabs-container');
857
+ container.querySelectorAll('.table-tab-content').forEach(el => el.style.display = 'none');
858
+ container.querySelectorAll('.table-tab-btn').forEach(el => {
859
+ el.style.background = '#1c2128';
860
+ el.style.color = '#fff';
861
+ el.style.border = '1px solid #30363d';
862
+ el.style.fontWeight = '400';
863
+ });
864
+ container.querySelector('#' + tabId).style.display = 'block';
865
+ btn.style.background = '#00c88c';
866
+ btn.style.color = '#000';
867
+ btn.style.fontWeight = '600';
868
+ btn.style.border = 'none';
869
+ }
870
+ </script>
871
+ <h3 style="margin-top: 30px;">Zusätzliche Befehle</h3>
872
+ <p><strong>Auflistungstabellen:</strong>So sehen Sie alle verfügbaren Tabellenvorlagen und Beschreibungen:</p>
873
+ <pre><code>artiframe&gt; <span class="fn">Tisch</span> <span class="st">Liste</span></code></pre>
874
+ <p><strong>Vorschau des Tabelleninhalts:</strong>ein Gemälde<code>schema.sql</code>am Ende des Befehls, um den SQL-Inhalt im Terminal zu prüfen, bevor er zur Datei hinzugefügt wird.<code>check</code>Sie können den Parameter hinzufügen:</p>
875
+ <pre><code>artiframe&gt; <span class="fn">Tisch:</span><span class="st">Benutzer</span> <span class="st">überprüfen</span></code></pre>
876
+ </section>
877
+ Upgrade
878
+ cli v
870
879
  <section id="cli-cliv">
871
- <h2><code>cli v</code> (oder <code>cli version</code>) <span class="tag b-cli">CLI Komutu</span></h2>
872
- <p>ArtiFrame CLI steuert seine eigene (globale) Version des Tools. Zeigt nicht nur die aktuelle Version, <strong>NPM-Registrierung</strong> Außerdem wird geprüft, ob die aktuellste Version verfügbar ist. Wenn es eine neue Version gibt, kann diese sich mit einem Klick global aktualisieren (j/n).<code>npm install -g @artilingo/artiframe-cli@latest</code>).</p>
880
+ <h2><code>cli v</code>(oder<code>cli version</code>) <span class="tag b-cli">CLI-Befehl</span></h2>
881
+ <p>Steuert die eigene (globale) Version des ArtiFrame CLI-Tools. Zeigt nicht nur die aktuelle Version,<strong>NPM-Registrierung</strong>Außerdem wird geprüft, ob die aktuellste Version verfügbar ist. Wenn es eine neue Version gibt, kann diese sich mit einem Klick global aktualisieren (j/n).<code>npm install -g @artilingo/artiframe-cli@latest</code>).</p>
873
882
  <pre><code>artiframe&gt; <span class="fn">cli v</span>
874
- <span class="cm"> Mevcut Sürüm : v1.0.0
875
- Güncel Sürüm : v1.0.1
876
-
877
- Yeni bir güncelleme mevcut! v1.0.0 v1.0.1
878
- Şimdi güncellemek ister misiniz? (y/n)</span> <span class="st">y</span>
879
-
880
- <span class="cm"> Güncelleniyor...
881
- ✅ CLI başarıyla güncellendi!</span></code></pre>
883
+ <span class="cm">Aktuelle Version: v1.0.0
884
+ Aktuelle Version: v1.0.1
885
+ Ein neues Update ist verfügbar! v1.0.0 → v1.0.1
886
+ Möchten Sie jetzt aktualisieren? (j/n)</span> <span class="st">j</span>
887
+ <span class="cm">Aktualisierung...
888
+ ✅ CLI erfolgreich aktualisiert!</span></code></pre>
882
889
  </section>
883
- <!-- show -->
890
+ zeigen
884
891
  <section id="cli-show">
885
- <h2><code>show</code> <span class="tag b-cli">CLI Komutu</span></h2>
892
+ <h2><code>show</code> <span class="tag b-cli">CLI-Befehl</span></h2>
886
893
  <p>Es zeigt an, in welchem ​​Arbeitsverzeichnis sich die CLI derzeit befindet. Nützlich für die Navigation.</p>
887
- <pre><code>artiframe&gt; <span class="fn">show</span>
894
+ <pre><code>artiframe&gt; <span class="fn">zeigen</span>
888
895
  📍 Mevcut Çalışma Dizini:
889
896
  C:\projeler\benim_projem</code></pre>
890
897
  </section>
891
- <!-- list -->
898
+ Liste
892
899
  <section id="cli-list">
893
- <h2><code>list</code> <span class="tag b-cli">CLI Komutu</span></h2>
900
+ <h2><code>list</code> <span class="tag b-cli">CLI-Befehl</span></h2>
894
901
  <p>Es listet die Dateien und Ordner im aktuellen Verzeichnis in einer Baumstruktur in der Reihenfolge ihrer Priorität auf. Zeigt die Anzahl der Elemente in Ordnern und die Größe der Dateien an.</p>
895
- <pre><code>artiframe&gt; <span class="fn">list</span>
902
+ <pre><code>artiframe&gt; <span class="fn">Liste</span>
896
903
  📂 benim_projem/
897
904
  │ ├── 📂 src/ (5 öğe)
898
905
  │ ├── 📂 public/ (4 öğe)
899
906
  │ ├── 📄 composer.json [1.2 KB]
900
907
  │ └── 📄 README.md [4.5 KB]</code></pre>
901
908
  </section>
902
- <!-- go -->
909
+ gehen
903
910
  <section id="cli-go">
904
- <h2><code>go</code> <span class="tag b-cli">CLI Komutu</span></h2>
911
+ <h2><code>go</code> <span class="tag b-cli">CLI-Befehl</span></h2>
905
912
  <p>Sie können damit zwischen Verzeichnissen navigieren, während Sie sich in der interaktiven Shell der CLI befinden. Es hat keine dauerhafte Auswirkung auf Betriebssystemebene, ändert jedoch Ihr Arbeitsverzeichnis, solange die CLI geöffnet bleibt.</p>
906
- <pre><code>artiframe&gt; <span class="fn">go</span> <span class="st">public</span>
913
+ <pre><code>artiframe&gt; <span class="fn">gehen</span> <span class="st">öffentlich</span>
907
914
  ✅ Dizin başarıyla değiştirildi.
908
915
  C:\projeler\benim_projem\public
909
-
910
- artiframe&gt; <span class="fn">go</span> <span class="st">back</span>
916
+ artiframe&gt; <span class="fn">gehen</span> <span class="st">zurück</span>
911
917
  ✅ Dizin başarıyla değiştirildi.
912
918
  C:\projeler\benim_projem</code></pre>
913
919
  </section>
914
- <!-- remove -->
920
+ entfernen
915
921
  <section id="cli-remove">
916
- <h2><code>remove</code> <span class="tag b-cli">CLI Komutu</span></h2>
917
- <p>Löscht sicher eine angegebene Datei. <code>make</code> Es funktioniert entgegengesetzt zu den Befehlen und analysiert die Abhängigkeiten im Projekt und gibt Warnungen vor dem Löschen aus:</p>
922
+ <h2><code>remove</code> <span class="tag b-cli">CLI-Befehl</span></h2>
923
+ <p>Löscht sicher eine angegebene Datei.<code>make</code>Es funktioniert entgegengesetzt zu den Befehlen und analysiert die Abhängigkeiten im Projekt und gibt Warnungen vor dem Löschen aus:</p>
918
924
  <ul>
919
- <li><strong>Wenn die Ansicht gelöscht wird:</strong> if-Datei <code>public/</code> und CSS/JS-Dateien, die mit dieser Datei verknüpft sind <code>public/assets</code> Wenn ja, werden Sie gefragt, ob Sie diese ebenfalls reinigen möchten.</li>
920
- <li><strong>Wenn die Klasse gelöscht wird:</strong> if-Datei <code>src/</code> oder <code>app/</code> wenn unten, <code>public/api/</code> durchsucht das Verzeichnis. Es warnt Sie, indem es die API-Enden und Zeilennummern ausgibt, in denen die von Ihnen gelöschte Klasse verwendet wird. Die APIs werden jedoch nicht automatisch gelöscht (aus Sicherheitsgründen müssen Sie die relevanten APIs manuell bearbeiten).</li>
925
+ <li><strong>Wenn die Ansicht gelöscht wird:</strong>if-Datei<code>public/</code>und CSS/JS-Dateien, die mit dieser Datei verknüpft sind<code>public/assets</code>Wenn ja, werden Sie gefragt, ob Sie diese ebenfalls reinigen möchten.</li>
926
+ <li><strong>Wenn die Klasse gelöscht wird:</strong>if-Datei<code>src/</code>oder<code>app/</code>wenn unten,<code>public/api/</code>durchsucht das Verzeichnis. Es warnt Sie, indem es die API-Enden und Zeilennummern ausgibt, in denen die von Ihnen gelöschte Klasse verwendet wird. Die APIs werden jedoch nicht automatisch gelöscht (aus Sicherheitsgründen müssen Sie die relevanten APIs manuell bearbeiten).</li>
921
927
  </ul>
922
- <pre><code>artiframe&gt; <span class="fn">remove</span> <span class="st">src/Auth/UserManager.php</span>
928
+ <pre><code>artiframe&gt; <span class="fn">entfernen</span> <span class="st">src/Auth/UserManager.php</span>
923
929
  ⚠️ Bu dosyayı KÖKTEN silmek üzeresiniz. Emin misiniz? C:\...\src\Auth\UserManager.php [y/N]: y
924
-
925
930
  🚨 DİKKAT: Sildiğiniz UserManager sınıfı şu API dosyalarında kullanılıyor:
926
931
  -&gt; C:\...\public\api\auth\login.php (Satır: 12)
927
932
  -&gt; C:\...\public\api\auth\register.php (Satır: 15)
928
-
929
933
  📌 Yukarıdaki API dosyalarındaki ilgili satırları kendiniz düzenlemeli veya silmelisiniz.
930
-
931
934
  ✅ Dosya başarıyla silindi: C:\...\src\Auth\UserManager.php</code></pre>
932
935
  </section>
933
- <!-- version -->
936
+ Version
934
937
  <section id="cli-version">
935
- <h2><code>version</code> <span class="tag b-cli">CLI Komutu</span></h2>
936
- <p><code class="ic">config/app-version.php</code> Die darin enthaltene Versionsnummer wird gemäß den Regeln der semantischen Versionierung (SemVer) aktualisiert. Versionsformat: <strong>MAJOR.MINOR.PATCH</strong></p>
938
+ <h2><code>version</code> <span class="tag b-cli">CLI-Befehl</span></h2>
939
+ <p><code class="ic">config/app-version.php</code>Die darin enthaltene Versionsnummer wird gemäß den Regeln der semantischen Versionierung (SemVer) aktualisiert. Versionsformat:<strong>MAJOR.MINOR.PATCH</strong></p>
937
940
  <table class="sig-table">
938
941
  <thead>
939
942
  <tr><th>Befehl</th><th>Erläuterung</th><th>Beispiel</th></tr>
@@ -947,49 +950,73 @@ artiframe&gt; <span class="fn">go</span> <span class="st">back</span>
947
950
  <tr><td>Versions-Downgrade schwerwiegend</td><td>Machen Sie den letzten Major rückgängig</td><td>2.0.0 → 1.0.0</td></tr>
948
951
  </tbody>
949
952
  </table>
950
- <pre><code>artiframe&gt; <span class="fn">version</span> upgrade minor
951
- <span class="cm">✔ Sürüm 1.2.0 → 1.3.0 olarak güncellendi.</span></code></pre>
953
+ <pre><code>artiframe&gt; <span class="fn">Version</span> upgrade minor
954
+ <span class="cm">✔ Aktualisiert auf Version 1.2.0 → 1.3.0.</span></code></pre>
952
955
  </section>
953
- <!-- mode -->
954
- <section id="cli-mode">
955
- <h2><code>mode</code> <span class="tag b-cli">CLI-Befehl</span></h2>
956
- <p>Ermöglicht es Ihnen, den Betriebsmodus des Projekts (Entwicklung oder Produktion) mit einem einzigen Befehl zu ändern. Dies erspart Ihnen das mühsame manuelle Öffnen und Bearbeiten der Datei <code>config/app-version.php</code>.</p>
957
- <pre><code>artiframe&gt; <span class="fn">mode</span> <span class="st">1</span>
958
- Vom Prod- in den Debug-Modus gewechselt.</code></pre>
959
- <p>Sie können den Parameter <code>0</code> verwenden, um zur Produktionsfreigabe zu wechseln:</p>
960
- <pre><code>artiframe&gt; <span class="fn">mode</span> <span class="st">0</span></code></pre>
961
- </section>
962
- <!-- serve -->
956
+ Modus
957
+ <section id="cli-mode">
958
+ <h2><code>mode</code> <span class="tag b-cli">CLI-Befehl</span></h2>
959
+ <p>Es ermöglicht Ihnen, den Arbeitsmodus des Projekts (Entwicklung oder Live) mit einem einzigen Befehl zu ändern. Dieser Befehl kann manuell erfolgen<code>config/app-version.php</code>Es erspart Ihnen die Mühe, die Datei zu öffnen und zu bearbeiten.</p>
960
+ <pre><code>artiframe&gt; <span class="fn">Modus</span> <span class="st">1</span>
961
+ ✅ Prod modundan Debug moduna geçiş yapıldı.</code></pre>
962
+ <p>Um zur Live-Version zu wechseln<code>0</code>Sie können den Parameter verwenden:</p>
963
+ <pre><code>artiframe&gt; <span class="fn">Modus</span> <span class="st">0</span></code></pre>
964
+ </section>
965
+ Aufschlag
963
966
  <section id="cli-serve">
964
- <h2><code>serve</code> <span class="tag b-cli">CLI Komutu</span></h2>
965
- <p>Startet einen lokalen Entwicklungsserver (localhost), um das Projekt zu testen. Es startet Ihr Projekt in Sekundenschnelle und öffnet es automatisch in Ihrem Browser, ohne dass ein zusätzlicher Webserver (XAMPP, Nginx usw.) installiert werden muss.</p>
966
- <pre><code>artiframe&gt; <span class="fn">serve</span>
967
- 🚀 Geliştirme sunucusu başlatılıyor: http://localhost:8000
968
- Durdurmak için CTRL+C tuşlarına basın.</code></pre>
967
+ <h2><code>serve</code> <span class="tag b-cli">CLI-Befehl</span></h2>
968
+ <p>Um das Projekt zu testen, startet es einen lokalen Entwicklungsserver und öffnet ihn über 0.0.0.0 (alle Netzwerkschnittstellen) für das lokale Netzwerk (Local Network). Es startet Ihr Projekt in Sekundenschnelle, ohne dass ein zusätzlicher Webserver (XAMPP, Nginx usw.) installiert werden muss, öffnet automatisch die Registerkarte „Localhost“ auf Ihrem eigenen Computer und druckt die Verbindungs-IP für andere Geräte im Netzwerk (Telefon/Tablet) auf dem Bildschirm aus.</p>
969
+ <pre><code>artiframe&gt; <span class="fn">Aufschlag</span>
970
+ 🚀 Geliştirme sunucusu başlatıldı: 0.0.0.0:8000
971
+ Durdurmak için CTRL+C tuşlarına basın.
972
+
973
+ Local: http://localhost:8000
974
+ Network: http://192.168.1.34:8000</code></pre>
969
975
  <p>Sie können bei Bedarf eine andere Portnummer angeben:</p>
970
- <pre><code>artiframe&gt; <span class="fn">serve</span> <span class="st">8080</span></code></pre>
976
+ <pre><code>artiframe&gt; <span class="fn">Aufschlag</span> <span class="st">8080</span></code></pre>
977
+ </section>
978
+ Autor
979
+ <section id="cli-auth">
980
+ <h2><code>auth</code> <span class="tag b-cli">CLI-Befehl</span></h2>
981
+ <p>Das Problem autorisiert die CLI mit Ihrem GitHub-Konto (über OAuth Device Flow), Vorschläge und Fehlerberichte senden zu können.</p>
982
+ <pre><code>artiframe&gt; <span class="fn">Autor</span></code></pre>
983
+ <p>Dieser Befehl druckt einen Benutzercode und öffnet die GitHub-Autorisierungsseite in Ihrem Browser. Sobald die Autorisierung bestätigt ist, wird der Token sicher gespeichert.</p>
984
+ </section>
985
+ vorschlagen
986
+ <section id="cli-suggest">
987
+ <h2><code>suggest</code> <span class="tag b-cli">CLI-Befehl</span></h2>
988
+ <p>Damit können Sie Funktionsanfragen, Fehlerberichte oder Vorschläge direkt an GitHub senden, ohne das Terminal zu verlassen. vor<code>auth</code>Es ist zwingend erforderlich, sich mit dem Befehl anzumelden.</p>
989
+ <pre><code>artiframe&gt; <span class="fn">vorschlagen</span></code></pre>
990
+ <p>Das Skript fordert Sie interaktiv auf, eine Kategorie auszuwählen, einen Titel zu schreiben und eine detaillierte Beschreibung einzugeben. Sobald es abgeschlossen ist, wird es als Problem im offiziellen ArtiFrame-Repository veröffentlicht.</p>
971
991
  </section>
972
- <!-- add -->
992
+ Probleme
993
+ <section id="cli-issues">
994
+ <h2><code>issues</code> <span class="tag b-cli">CLI-Befehl</span></h2>
995
+ <p>Listen Sie die von Ihnen eingereichten Probleme auf und lesen Sie deren Kommentare direkt von Ihrem Terminal aus.<code>auth</code>Dazu ist eine Anmeldung mit dem Befehl erforderlich.</p>
996
+ <pre><code>artiframe&gt; <span class="fn">Probleme</span> [id]</code></pre>
997
+ <p>Um eine Liste Ihrer Probleme anzuzeigen<code>issues</code>Führen Sie es aus. Hier finden Sie die Details und Kommentare zu Ausgabe Nr. 4<code>issues 4</code>Führen Sie es aus.</p>
998
+ </section>
999
+ hinzufügen
973
1000
  <section id="cli-add">
974
- <h2><code>add</code> <span class="tag b-cli">CLI Komutu</span></h2>
975
- <p>Es ist der leistungsstärkste Befehl, mit dem Sie externe Module oder vorgefertigte Integrationen in Ihr Projekt einbinden können. Klassisch <code>composer require</code> Über den Prozess hinaus erstellt es automatische Serviceklassen (Stubs) für einige Module und <code>.env</code> Es erstellt automatisch die erforderlichen Definitionen für Ihre Dateien.</p>
976
- <pre><code>artiframe&gt; <span class="fn">add</span> <span class="st">paket_kisa_adi</span></code></pre>
1001
+ <h2><code>add</code> <span class="tag b-cli">CLI-Befehl</span></h2>
1002
+ <p>Es ist der leistungsstärkste Befehl, mit dem Sie externe Module oder vorgefertigte Integrationen in Ihr Projekt einbinden können. Klassisch<code>composer require</code>Über den Prozess hinaus erstellt es automatische Serviceklassen (Stubs) für einige Module und<code>.env</code>Es erstellt automatisch die erforderlichen Definitionen für Ihre Dateien.</p>
1003
+ <pre><code>artiframe&gt; <span class="fn">hinzufügen</span> <span class="st">Paketkurzname</span></code></pre>
977
1004
  <h3>1. Integrierte Pakete (klassenabhängig)</h3>
978
- <p>Bei der Installation dieser Pakete wird automatisch eine Serviceklasse erstellt und <code>.env</code> Verbindungsschlüssel werden Ihrer Datei hinzugefügt. Nachfolgend sind die Speicherorte dieser Pakete und die von ihnen erstellten Klassen aufgeführt:</p>
1005
+ <p>Bei der Installation dieser Pakete wird automatisch eine Serviceklasse erstellt und<code>.env</code>Verbindungsschlüssel werden Ihrer Datei hinzugefügt. Diese Pakete und die Speicherorte der von ihnen erstellten Klassen sind unten aufgeführt:</p>
979
1006
  <div class="table-wrapper">
980
1007
  <table class="sig-table">
981
1008
  <thead>
982
1009
  <tr><th>Befehl</th><th>Komponistenpaket</th><th>Generierte Klassendatei</th></tr>
983
1010
  </thead>
984
1011
  <tbody>
985
- <tr><td><code>add phpmailer</code></td><td>phpmailer/phpmailer</td><td><span class="tag b-core">src/Service/Mailer.php</span></td></tr>
986
- <tr><td><code>add iyzico</code></td><td>iyzipay/iyzipay-php</td><td><span class="tag b-core">src/Service/Iyzico.php</span></td></tr>
1012
+ <tr><td><code>add phpmailer</code></td><td>phpmailer/phpmailer</td><td><span class="tag b-core">src/Service/Mailer.php</span></td></tr>
1013
+ <tr><td><code>add iyzico</code></td><td>iyzipay/iyzipay-php</td><td><span class="tag b-core">src/Service/Iyzico.php</span></td></tr>
987
1014
  <tr><td><code>add stripe</code></td><td>Stripe/Stripe-php</td><td><span class="tag b-core">src/Service/Stripe.php</span></td></tr>
988
- <tr><td><code>add qrcode</code></td><td>endroid/qr-code</td><td><span class="tag b-core">src/Service/QrCode.php</span></td></tr>
989
- <tr><td><code>add jwt</code></td><td>firebase/php-jwt</td><td><span class="tag b-core">src/Auth/JwtAuth.php</span></td></tr>
1015
+ <tr><td><code>add qrcode</code></td><td>Endroid/QR-Code</td><td><span class="tag b-core">src/Service/QrCode.php</span></td></tr>
1016
+ <tr><td><code>add jwt</code></td><td>firebase/php-jwt</td><td><span class="tag b-core">src/Auth/JwtAuth.php</span></td></tr>
990
1017
  <tr><td><code>add image</code></td><td>Intervention/Bild</td><td><span class="tag b-core">src/Service/ImageProcessor.php</span></td></tr>
991
1018
  <tr><td><code>add s3</code></td><td>aws/aws-sdk-php</td><td><span class="tag b-core">src/Service/S3Storage.php</span></td></tr>
992
- <tr><td><code>add sentry</code></td><td>Wache/Wächter</td><td><span class="tag b-core">config/sentry.php</span></td></tr>
1019
+ <tr><td><code>add sentry</code></td><td>Wache/Wächter</td><td><span class="tag b-core">src/Service/Sentry.php</span></td></tr>
993
1020
  <tr><td><code>add redis</code></td><td>predis/predis</td><td><span class="tag b-core">src/Service/RedisCache.php</span></td></tr>
994
1021
  <tr><td><code>add pusher</code></td><td>pusher/pusher-php-server</td><td><span class="tag b-core">src/Service/Pusher.php</span></td></tr>
995
1022
  <tr><td><code>add twilio</code></td><td>twilio/sdk</td><td><span class="tag b-core">src/Service/Twilio.php</span></td></tr>
@@ -1004,11 +1031,9 @@ artiframe&gt; <span class="fn">go</span> <span class="st">back</span>
1004
1031
  <tr><th>Befehl</th><th>Komponistenpaket</th></tr>
1005
1032
  </thead>
1006
1033
  <tbody>
1007
- <tr><td><code>add phpmailer</code></td><td>phpmailer/phpmailer</td></tr>
1008
1034
  <tr><td><code>add mpdf</code></td><td>mpdf/mpdf</td></tr>
1009
1035
  <tr><td><code>add dompdf</code></td><td>dompdf/dompdf</td></tr>
1010
1036
  <tr><td><code>add spreadsheet</code></td><td>phpoffice/phpspreadsheet</td></tr>
1011
- <tr><td><code>add qrcode</code></td><td>Endroid/QR-Code</td></tr>
1012
1037
  <tr><td><code>add guzzle</code></td><td>guzzlehttp/guzzle</td></tr>
1013
1038
  <tr><td><code>add uuid</code></td><td>ramsey/uuid</td></tr>
1014
1039
  <tr><td><code>add carbon</code></td><td>nesbot/carbon</td></tr>
@@ -1017,101 +1042,87 @@ artiframe&gt; <span class="fn">go</span> <span class="st">back</span>
1017
1042
  </table>
1018
1043
  </div>
1019
1044
  <div class="alert a-info">
1020
- <strong>ℹ️ Tipp:</strong> Um die gesamte Liste der installierten oder unterstützten Programme anzuzeigen, öffnen Sie einfach das Terminal <code>add list</code> du kannst schreiben. Die Codeverwendung der Module finden Sie rechts im Menü „Integrierte Dienste“.
1021
- </div>
1045
+ <strong>ℹ️ Tipp:</strong>Um die gesamte Liste der installierten oder unterstützten Programme anzuzeigen, öffnen Sie einfach das Terminal<code>add list</code>du kannst schreiben. Die Codeverwendung der Module finden Sie rechts im Menü „Integrierte Dienste“.</div>
1022
1046
  </section>
1023
- <!-- ====== ENTEGRE SERVİSLER ====== -->
1047
+ ====== INTEGRIERTE DIENSTLEISTUNGEN ======
1024
1048
  <section id="entegre-servisler">
1025
- <h2>Integrierte Dienste (Wrapper) <span class="tag b-core">Stubs</span></h2>
1026
- <p>Anstatt gängige Pakete direkt zu verwenden, bietet ArtiFrame <strong>vorkonfigurierter Wrapper</strong> Es bietet Kurse für Sie an.</p>
1027
- <div class="card" id="svc-qrcode">
1028
- <h2>QR Code</h2>
1029
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Wrapper-Klasse:</strong> Wenn Sie <code>add qrcode</code> ausführen, wird die Klasse <code>src/Service/QrCode.php</code> erstellt.</div>
1030
- <p>Eine fließende (fluent) Klasse, die den komplexen Instanziierungsprozess der Endroid QR Code-Bibliothek verbirgt.</p>
1031
-
1032
- <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Methoden</h3>
1033
- <ul style="line-height: 1.6; margin-bottom: 20px;">
1034
- <li><code>->generate('Metin')</code> : Startet die Kette.</li>
1035
- <li><code>->size(300)</code> : Größe in Pixeln.</li>
1036
- <li><code>->margin(10)</code> : Weißer Rand.</li>
1037
- <li><code>->color('#000000', '#ffffff')</code> : Vordergrund- und Hintergrundfarbe als HEX.</li>
1038
- <li><code>->logo('/path/logo.png', 50, true)</code> : Bettet ein Logo ein.</li>
1039
- <li><code>->format('png')</code> : png oder svg.</li>
1040
- <li><code>->save('/path/save.png')</code> : Speichert die Datei.</li>
1041
- <li><code>->base64()</code> : Gibt als base64 zurück.</li>
1042
- <li><code>->output()</code> : Gibt direkt an den Browser aus.</li>
1043
- </ul>
1044
-
1045
- <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Beispiele</h3>
1046
- <pre><code><span class="kw">use</span> <span class="var">App\Service\QrCode</span>;
1047
-
1048
- <span class="cm">// Örnek 1: Ekrana HTML Img olarak basma</span>
1049
- <span class="var">$base64</span> = <span class="var">QrCode</span>::generate(<span class="st">'https://artiframe.dev'</span>)
1050
- -&gt;<span class="fn">size</span>(400)
1051
- -&gt;<span class="fn">logo</span>(<span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/assets/logo.png'</span>)
1052
- -&gt;<span class="fn">base64</span>();
1053
-
1054
- <span class="kw">echo</span> <span class="st">'&lt;img src="'</span> . <span class="var">$base64</span> . <span class="st">'" alt="QR"&gt;'</span>;
1055
-
1056
- <span class="cm">// Örnek 2: Fiziksel PNG Olarak Kaydetme</span>
1057
- <span class="var">QrCode</span>::generate(<span class="st">'VCARD Bilgileri'</span>)
1058
- -&gt;<span class="fn">color</span>(<span class="st">'#ff0000'</span>, <span class="st">'#ffffff'</span>)
1059
- -&gt;<span class="fn">save</span>(<span class="st">'/temp/kullanici_karti.png'</span>);
1060
-
1061
- <span class="cm">// Örnek 3: API Endpoint olarak resmi tarayıcıya basma</span>
1062
- <span class="var">QrCode</span>::generate(<span class="st">'https://artilingo.com'</span>)-&gt;<span class="fn">output</span>();</code></pre>
1063
- </div>
1064
-
1065
- <div class="card" id="svc-phpmailer">
1066
- <h2>PHPMailer (Mail)</h2>
1067
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Automatische .env-Einrichtung:</strong> Wenn Sie den Befehl <code>add phpmailer</code> ausführen, werden die SMTP-Einstellungen automatisch zu Ihrer <code>.env</code>-Datei hinzugefügt und die Klasse <code>src/Service/Mailer.php</code> erstellt.</div>
1068
- <p>Eine viel modernere, fließende und sichere (CRLF-geschützte) Wrapper-Klasse, die auf der PHPMailer-Bibliothek aufbaut. Alle Methoden der Klasse sind verkettbar (chainable).</p>
1069
-
1070
- <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Methoden und Verwendung</h3>
1071
- <ul style="line-height: 1.6; margin-bottom: 20px;">
1072
- <li><code>->to('mail@adres.com', 'İsim')</code> : Legt fest, an wen die E-Mail gesendet wird.</li>
1073
- <li><code>->cc('mail@adres.com')</code> : Fügt CC-Empfänger (Carbon Copy) hinzu.</li>
1074
- <li><code>->bcc('mail@adres.com')</code> : Fügt BCC-Empfänger (Blind Carbon Copy) hinzu. Primäre Empfänger können diese nicht sehen.</li>
1075
- <li><code>->subject('Konu')</code> : Legt den Betreff (Titel) der E-Mail fest.</li>
1076
- <li><code>->attach('/path/fatura.pdf', 'Isim.pdf')</code> : Fügt eine physische Datei vom Server (oder Temp) als Anhang zur E-Mail hinzu.</li>
1077
- <li><code>->embedImage('/path/logo.png', 'logo_cid')</code> : Bettet ein Bild in die E-Mail ein, das im HTML verwendet wird (<code>&lt;img src="cid:logo_cid"&gt;</code>).</li>
1078
- <li><code>->html('HTML Kodu')</code> : Legt den HTML-Inhalt der E-Mail fest. Erstellt automatisch eine reine Textversion (AltBody).</li>
1079
- <li><code>->text('Düz Metin')</code> : Wird verwendet, wenn die E-Mail ausschließlich als reiner Text gesendet werden soll.</li>
1080
- <li><code>->send()</code> : Schließt alle Operationen ab und sendet die E-Mail über SMTP. Wirft bei Fehler eine Exception.</li>
1081
- </ul>
1082
-
1083
- <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Erweitertes Beispiel: PHP-Vorlage (View) und dynamischer Dateianhang</h3>
1084
- <p>Wenn Sie den HTML-Inhalt nicht direkt in Strings schreiben möchten, können Sie <code>ob_start()</code> verwenden, um eine externe PHP-Vorlagendatei (mit Variablen) einzubinden und ein dynamisch generiertes PDF anzuhängen:</p>
1085
- <pre><code><span class="kw">use</span> <span class="var">App\Service\Mailer</span>;
1086
-
1087
- <span class="cm">// 1. Ihre dynamischen Daten</span>
1088
- <span class="var">$siparisNo</span> = <span class="st">'#90210'</span>;
1089
- <span class="var">$pdfDosyasi</span> = <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/temp/fatura_90210.pdf'</span>;
1090
-
1091
- <span class="cm">// 2. HTML-Vorlage extern laden (Output Buffering)</span>
1092
- <span class="fn">ob_start</span>();
1093
- <span class="kw">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/views/email/siparis.php'</span>;
1094
- <span class="var">$htmlIcerik</span> = <span class="fn">ob_get_clean</span>();
1095
-
1096
- <span class="cm">// 3. E-Mail senden</span>
1097
- <span class="var">Mailer</span>::create()
1098
- -&gt;<span class="fn">to</span>(<span class="st">'musteri@mail.com'</span>, <span class="st">'Ahmet Yılmaz'</span>)
1099
- -&gt;<span class="fn">bcc</span>(<span class="st">'arsiv@sirket.com'</span>) <span class="cm">// Der Kunde kann dies nicht sehen</span>
1100
- -&gt;<span class="fn">subject</span>(<span class="st">'Siparişiniz Onaylandı: '</span> . <span class="var">$siparisNo</span>)
1101
- -&gt;<span class="fn">html</span>(<span class="var">$htmlIcerik</span>)
1102
- -&gt;<span class="fn">attach</span>(<span class="var">$pdfDosyasi</span>, <span class="st">'Siparis_Faturasi.pdf'</span>)
1103
- -&gt;<span class="fn">send</span>();</code></pre>
1104
- </div>
1105
-
1106
- <div class="card" id="svc-iyzico">
1107
- <h2>Iyzico <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></h2>
1108
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong> Zur Nutzung der Iyzico-Zahlungsinfrastruktur <a href="https://www.iyzico.com" style="color: var(--green); font-weight: bold;" target="_blank">iyzico.com</a> (live) oder <a href="https://sandbox-merchants.iyzipay.com/" style="color: var(--green); font-weight: bold;" target="_blank">sandbox.iyzipay.com</a> Sie müssen über (Test) ein Verkäuferkonto erstellen und Ihre API/Geheimschlüssel erhalten.</div>
1049
+ <h2>Integrierte Dienste (Wrapper)<span class="tag b-core">Stubs</span></h2>
1050
+ <p>Anstatt gängige Pakete direkt zu verwenden, bietet ArtiFrame<strong>vorkonfigurierter Wrapper</strong>Es bietet Kurse für Sie an.</p>
1051
+ <div class="card" id="svc-qrcode">
1052
+ <h2>QR-Code</h2>
1053
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Immersiver Unterricht:</strong> <code>add qrcode</code>wenn Sie den Befehl ausführen<code>endroid/qr-code</code>Bibliothek ist geladen und<code>src/Service/QrCode.php</code>Die Wrapper-Klasse wird erstellt.</div>
1054
+ <p>Es handelt sich um einen modernen und fließenden Kurs, der die schwierigen Objektproduktionsprozesse (Builder/Writer) der Endroid QR Code-Bibliothek verbirgt, in der Sie einen QR-Code in einer einzigen Zeile erstellen und ein Logo darin einbetten können.</p>
1055
+ <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Methoden und Verwendungen</h3>
1056
+ <ul style="line-height: 1.6; margin-bottom: 20px;">
1057
+ <li><code>-&gt;generate('Metin')</code>: Gibt den Text oder die URL an, die in einen QR-Code umgewandelt werden soll, und startet die Kette.</li>
1058
+ <li><code>-&gt;size(300)</code>: Bestimmt die Breite/Höhe des QR-Codes in Pixel (z. B. 300).</li>
1059
+ <li><code>-&gt;margin(10)</code>: Bestimmt den Leerraum um den QR-Code.</li>
1060
+ <li><code>-&gt;color('#000000', '#ffffff')</code>: Gibt die Vordergrund- (Linien) und Hintergrundfarben als HEX-Code an. (z.B:<code>#000000, #ffffff</code>).</li>
1061
+ <li><code>-&gt;logo('/path/logo.png', 50, true)</code>: Bettet ein Bild (Logo) in der Mitte des QR-Codes ein. Ruft den physischen Pfad zum Logo, seine Größe und ob der Hintergrund ausgestanzt wird, ab.</li>
1062
+ <li><code>-&gt;format('png')</code>: Bestimmt das Ausgabeformat.<code>png</code>oder<code>svg</code>wird unterstützt. Standard: png.</li>
1063
+ <li><code>-&gt;save('/path/save.png')</code>: Speichert den erstellten QR-Code in einer physischen Datei auf dem Server.</li>
1064
+ <li><code>-&gt;base64()</code>: QR-Code HTML<code>&lt;img src="..."&gt;</code>Es gibt es als Base64-String zurück, sodass Sie es direkt im Tag verwenden können.</li>
1065
+ <li><code>-&gt;output()</code>: Druckt den QR-Code mit den entsprechenden HTTP-Headern direkt an den Browser.</li>
1066
+ </ul>
1067
+ <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Anwendungsbeispiele</h3>
1068
+ <pre><code><span class="kw">verwenden</span> <span class="var">App\Service\QrCode</span>;
1069
+ <span class="cm">// Beispiel 1: HTML-Bild auf dem Bildschirm ausgeben</span>
1070
+ <span class="var">$base64</span> = <span class="var">QrCode</span>::generate(<span class="st">'https://artiframe.dev'</span>)
1071
+ -&gt;<span class="fn">Du</span>(400)
1072
+ -&gt;<span class="fn">Logo</span>(<span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/assets/logo.png'</span>)
1073
+ -&gt;<span class="fn">base64</span>();
1074
+ <span class="kw">Echo</span> <span class="st">'&lt;img src="'</span> . <span class="var">$base64</span> . <span class="st">'" alt="QR"&gt;'</span>;
1075
+ <span class="cm">// Beispiel 2: Speichern als physisches PNG</span>
1076
+ <span class="var">QrCode</span>::generate(<span class="st">„VCARD-Informationen“</span>)
1077
+ -&gt;<span class="fn">Farbe</span>(<span class="st">'#ff0000'</span>, <span class="st">'#ffffff'</span>)
1078
+ -&gt;<span class="fn">speichern</span>(<span class="st">'/temp/user_card.png'</span>);
1079
+ <span class="cm">// Beispiel 3: Bild als API-Endpunkt an den Browser übertragen</span>
1080
+ <span class="var">QrCode</span>::generate(<span class="st">'https://artilingo.com'</span>)-&gt;<span class="fn">Ausgabe</span>();</code></pre>
1081
+ </div>
1082
+ <div class="card" id="svc-phpmailer">
1083
+ <h2>PHPMailer (Mail)</h2>
1084
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Automatische .env-Installation:</strong> <code>add phpmailer</code>SMTP-Einstellungen, wenn Sie den Befehl ausführen<code>.env</code>automatisch zu Ihrer Datei hinzugefügt und<code>src/Service/Mailer.php</code>Klasse wird erstellt.</div>
1085
+ <p>Es handelt sich um eine viel modernere, flüssigere und sicherere (CRLF-geschützte) Wrapper-Klasse, die auf der PHPMailer-Bibliothek läuft. Alle von der Klasse angebotenen Methoden sind verkettbar.</p>
1086
+ <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Methoden und Verwendungen</h3>
1087
+ <ul style="line-height: 1.6; margin-bottom: 20px;">
1088
+ <li><code>-&gt;to('mail@adres.com', 'İsim')</code>: Legt fest, an wen die E-Mail gesendet wird.</li>
1089
+ <li><code>-&gt;cc('mail@adres.com')</code>: Fügt Informationsempfänger (Carbon Copy) hinzu.</li>
1090
+ <li><code>-&gt;bcc('mail@adres.com')</code>: Fügt Blind Carbon Copy-Empfänger hinzu. Primärempfänger können diese Adressen nicht sehen.</li>
1091
+ <li><code>-&gt;subject('Konu')</code>: Bestimmt den Titel (Betreff) der E-Mail.</li>
1092
+ <li><code>-&gt;attach('/path/fatura.pdf', 'Isim.pdf')</code>: Es wird eine physische Datei auf dem Server (oder temporär) als Anhang in die E-Mail eingefügt.</li>
1093
+ <li><code>-&gt;embedImage('/path/logo.png', 'logo_cid')</code>: Zur Verwendung in HTML in E-Mails (<code>&lt;img src="cid:logo_cid"&gt;</code>) bettet Bilder ein.</li>
1094
+ <li><code>-&gt;html('HTML Kodu')</code>: Legt den HTML-Inhalt der E-Mail fest. Erstellt aus Sicherheitsgründen automatisch eine Nur-Text-Version (AltBody).</li>
1095
+ <li><code>-&gt;text('Düz Metin')</code>: Wird verwendet, wenn Sie die E-Mail nur im Klartext senden möchten.</li>
1096
+ <li><code>-&gt;send()</code>: Schließt alle Transaktionen in der Kette ab und sendet die E-Mail über SMTP. Wenn ein Fehler vorliegt, wird eine Ausnahme ausgelöst.</li>
1097
+ </ul>
1098
+ <h3 style="margin-top:20px; margin-bottom:10px; font-size: 1.1em; color: var(--text-color);">Erweitertes Beispiel: PHP-Vorlage (Ansicht) und dynamische Dateiübermittlung</h3>
1099
+ <p>Wenn Sie den HTML-Inhalt der E-Mail nicht in einen String wie Spaghetti-Code schreiben möchten,<code>ob_start()</code>Sie können eine externe PHP-Vorlagendatei (mit darin enthaltenen Variablen) importieren und ein vom System generiertes PDF direkt in die E-Mail einbetten, indem Sie Folgendes verwenden:</p>
1100
+ <pre><code><span class="kw">verwenden</span> <span class="var">App\Service\Mailer</span>;
1101
+ <span class="cm">// 1. Ihre dynamischen Daten</span>
1102
+ <span class="var">$orderNo</span> = <span class="st">'#90210'</span>;
1103
+ <span class="var">$pdfFile</span> = <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/temp/invoice_90210.pdf'</span>;
1104
+ <span class="cm">// 2. Laden der HTML-Vorlage von außen (Ausgabepufferung)</span>
1105
+ <span class="fn">ob_start</span>();
1106
+ <span class="kw">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/views/email/order.php'</span>;
1107
+ <span class="var">$htmlContent</span> = <span class="fn">ob_get_clean</span>();
1108
+ <span class="cm">// 3. Versenden der E-Mail</span>
1109
+ <span class="var">Mailer</span>::create()
1110
+ -&gt;<span class="fn">Zu</span>(<span class="st">'custeri@mail.com'</span>, <span class="st">„Ahmet Yilmaz“</span>)
1111
+ -&gt;<span class="fn">bcc</span>(<span class="st">'archive@company.com'</span>) <span class="cm">// Der Client kann dies nicht sehen</span>
1112
+ -&gt;<span class="fn">Thema</span>(<span class="st">„Ihre Bestellung bestätigt:“</span> . <span class="var">$orderNo</span>)
1113
+ -&gt;<span class="fn">html</span>(<span class="var">$htmlContent</span>)
1114
+ -&gt;<span class="fn">befestigen</span>(<span class="var">$pdfFile</span>, <span class="st">'Bestellung_Rechnung.pdf'</span>)
1115
+ -&gt;<span class="fn">schicken</span>();</code></pre>
1116
+ </div>
1117
+ <div class="card" id="svc-iyzico">
1118
+ <h2>Iyzico<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></h2>
1119
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong>Zur Nutzung der Iyzico-Zahlungsinfrastruktur<a href="https://www.iyzico.com" style="color: var(--green); font-weight: bold;" target="_blank">iyzico.com</a>(live) oder<a href="https://sandbox-merchants.iyzipay.com/" style="color: var(--green); font-weight: bold;" target="_blank">sandbox.iyzipay.com</a>Sie müssen über (Test) ein Verkäuferkonto erstellen und Ihre API/Geheimschlüssel erhalten.</div>
1109
1120
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
1110
1121
  <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/Iyzico.php</code>
1111
1122
  </div>
1112
1123
  <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Iyzico-Zahlungsdienst<br/>Bietet einen sauberen Wrapper um das iyzipay-php SDK für die Zahlungsabwicklung.<br/>3D Secure-Flows, Rückerstattungen, Stornierungen, Kartentresor und Marktplatz-Unterhändler.<br/>Erforderliche Umgebungsvariablen:<br/>IYZICO_API_KEY – Ihr iyzico-API-Schlüssel<br/>IYZICO_SECRET_KEY – Ihr geheimer iyzico-Schlüssel<br/>IYZICO_BASE_URL – API-Basis-URL (https://sandbox-api.iyzipay.com oder https://api.iyzipay.com)</p>
1113
1124
  <div class="alert a-info" style="margin-bottom: 20px;">
1114
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
1125
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
1115
1126
  </div>
1116
1127
  <h3>Methoden und Anwendungsbeispiele</h3>
1117
1128
  <div class="accordion-group">
@@ -1153,7 +1164,6 @@ artiframe&gt; <span class="fn">go</span> <span class="st">back</span>
1153
1164
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1154
1165
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1155
1166
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1156
-
1157
1167
  $response = $iyzico-&gt;pay([
1158
1168
  'price' =&gt; 150.50,
1159
1169
  'paidPrice' =&gt; 160.00,
@@ -1186,7 +1196,6 @@ $response = $iyzico-&gt;pay([
1186
1196
  ]
1187
1197
  ]
1188
1198
  ]);
1189
-
1190
1199
  if ($response['status'] === 'success') {
1191
1200
  $paymentId = $response['data']['paymentId'];
1192
1201
  echo "Ödeme başarılı! ID: " . $paymentId;
@@ -1219,7 +1228,6 @@ if ($response['status'] === 'success') {
1219
1228
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1220
1229
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1221
1230
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1222
-
1223
1231
  $response = $iyzico-&gt;threeDSecureInit([
1224
1232
  'price' =&gt; 500.00,
1225
1233
  'paidPrice' =&gt; 500.00,
@@ -1253,7 +1261,6 @@ $response = $iyzico-&gt;threeDSecureInit([
1253
1261
  ]
1254
1262
  ]
1255
1263
  ]);
1256
-
1257
1264
  if ($response['status'] === 'success') {
1258
1265
  // Bankanın 3D doğrulama sayfasına yönlendirecek HTML formu
1259
1266
  echo $response['data']['threeDSHtmlContent'];
@@ -1285,10 +1292,8 @@ if ($response['status'] === 'success') {
1285
1292
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1286
1293
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1287
1294
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1288
-
1289
1295
  // Bankadan dönen POST verisi (paymentId ve conversationData vb.)
1290
1296
  $response = $iyzico-&gt;threeDSecureComplete($_POST);
1291
-
1292
1297
  if ($response['status'] === 'success') {
1293
1298
  echo "3D Doğrulama başarılı, ödeme çekildi: " . $response['data']['paymentId'];
1294
1299
  }</code></pre>
@@ -1319,9 +1324,7 @@ if ($response['status'] === 'success') {
1319
1324
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1320
1325
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1321
1326
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1322
-
1323
1327
  $response = $iyzico-&gt;refund('dummy_data', $price);
1324
-
1325
1328
  if ($response['status'] === 'success') {
1326
1329
  // Başarılı
1327
1330
  }</code></pre>
@@ -1350,9 +1353,7 @@ if ($response['status'] === 'success') {
1350
1353
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1351
1354
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1352
1355
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1353
-
1354
1356
  $response = $iyzico-&gt;cancel('dummy_data');
1355
-
1356
1357
  if ($response['status'] === 'success') {
1357
1358
  // Başarılı
1358
1359
  }</code></pre>
@@ -1388,9 +1389,7 @@ if ($response['status'] === 'success') {
1388
1389
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1389
1390
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1390
1391
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1391
-
1392
1392
  $response = $iyzico-&gt;saveCard($cardData, $email);
1393
-
1394
1393
  if ($response['status'] === 'success') {
1395
1394
  // Başarılı
1396
1395
  }</code></pre>
@@ -1421,9 +1420,7 @@ if ($response['status'] === 'success') {
1421
1420
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1422
1421
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1423
1422
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1424
-
1425
1423
  $response = $iyzico-&gt;listCards($cardUserKey);
1426
-
1427
1424
  if ($response['status'] === 'success') {
1428
1425
  // Başarılı
1429
1426
  }</code></pre>
@@ -1452,9 +1449,7 @@ if ($response['status'] === 'success') {
1452
1449
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1453
1450
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1454
1451
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1455
-
1456
1452
  $response = $iyzico-&gt;checkPayment('dummy_data');
1457
-
1458
1453
  if ($response['status'] === 'success') {
1459
1454
  // Başarılı
1460
1455
  }</code></pre>
@@ -1495,9 +1490,7 @@ if ($response['status'] === 'success') {
1495
1490
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1496
1491
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1497
1492
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$iyzico = new \Service\Iyzico();
1498
-
1499
1493
  $response = $iyzico-&gt;createSubMerchant($data);
1500
-
1501
1494
  if ($response['status'] === 'success') {
1502
1495
  // Başarılı
1503
1496
  }</code></pre>
@@ -1515,14 +1508,14 @@ if ($response['status'] === 'success') {
1515
1508
  </div>
1516
1509
  </div>
1517
1510
  <div class="card" id="svc-stripe">
1518
- <h2>Stripe <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></h2>
1519
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong> Um die globale Zahlungsinfrastruktur von Stripe zu nutzen <a href="https://stripe.com" style="color: var(--green); font-weight: bold;" target="_blank">stripe.com</a> Sie müssen über das Entwicklerpanel ein Konto erstellen und Ihre öffentlichen und geheimen Schlüssel erhalten.</div>
1511
+ <h2>Streifen<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></h2>
1512
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong>Um die globale Zahlungsinfrastruktur von Stripe zu nutzen<a href="https://stripe.com" style="color: var(--green); font-weight: bold;" target="_blank">stripe.com</a>Sie müssen über das Entwicklerpanel ein Konto erstellen und Ihre öffentlichen und geheimen Schlüssel erhalten.</div>
1520
1513
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
1521
1514
  <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/Stripe.php</code>
1522
1515
  </div>
1523
1516
  <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Stripe-Zahlungsdienst<br/>Bietet einen sauberen Wrapper um das Stripe-PHP-SDK für die Zahlungsabwicklung.<br/>Kundenverwaltung, Abonnements, Produkterstellung und Webhook-Verwaltung.<br/>Erforderliche Umgebungsvariablen:<br/>STRIPE_SECRET_KEY – Ihr geheimer API-Schlüssel für Stripe<br/>STRIPE_PUBLISHABLE_KEY – Ihr für Stripe veröffentlichbarer Schlüssel (zur Front-End-Referenz)<br/>STRIPE_WEBHOOK_SECRET – Webhook-Endpunkt-Signaturgeheimnis</p>
1524
1517
  <div class="alert a-info" style="margin-bottom: 20px;">
1525
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
1518
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
1526
1519
  </div>
1527
1520
  <h3>Methoden und Anwendungsbeispiele</h3>
1528
1521
  <div class="accordion-group">
@@ -1541,12 +1534,10 @@ if ($response['status'] === 'success') {
1541
1534
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1542
1535
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1543
1536
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1544
-
1545
1537
  $response = $stripe-&gt;createPaymentIntent(199.50, 'usd', [
1546
1538
  'order_id' =&gt; 'ORD-54321',
1547
1539
  'customer_email' =&gt; 'utku@artilingo.com'
1548
1540
  ]);
1549
-
1550
1541
  if ($response['status'] === 'success') {
1551
1542
  $clientSecret = $response['data']['clientSecret'];
1552
1543
  echo json_encode(['clientSecret' =&gt; $clientSecret]);
@@ -1576,9 +1567,7 @@ if ($response['status'] === 'success') {
1576
1567
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1577
1568
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1578
1569
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1579
-
1580
1570
  $response = $stripe-&gt;confirmPayment('dummy_data');
1581
-
1582
1571
  if ($response['status'] === 'success') {
1583
1572
  // Başarılı
1584
1573
  }</code></pre>
@@ -1610,9 +1599,7 @@ if ($response['status'] === 'success') {
1610
1599
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1611
1600
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1612
1601
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1613
-
1614
1602
  $response = $stripe-&gt;charge($amount, $source);
1615
-
1616
1603
  if ($response['status'] === 'success') {
1617
1604
  // Başarılı
1618
1605
  }</code></pre>
@@ -1642,9 +1629,7 @@ if ($response['status'] === 'success') {
1642
1629
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1643
1630
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1644
1631
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1645
-
1646
1632
  $response = $stripe-&gt;refund('dummy_data');
1647
-
1648
1633
  if ($response['status'] === 'success') {
1649
1634
  // Başarılı
1650
1635
  }</code></pre>
@@ -1675,9 +1660,7 @@ if ($response['status'] === 'success') {
1675
1660
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1676
1661
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1677
1662
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1678
-
1679
1663
  $response = $stripe-&gt;createCustomer($email);
1680
-
1681
1664
  if ($response['status'] === 'success') {
1682
1665
  // Başarılı
1683
1666
  }</code></pre>
@@ -1706,9 +1689,7 @@ if ($response['status'] === 'success') {
1706
1689
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1707
1690
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1708
1691
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1709
-
1710
1692
  $response = $stripe-&gt;subscribe('dummy_data', 'dummy_data');
1711
-
1712
1693
  if ($response['status'] === 'success') {
1713
1694
  // Başarılı
1714
1695
  }</code></pre>
@@ -1737,9 +1718,7 @@ if ($response['status'] === 'success') {
1737
1718
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1738
1719
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1739
1720
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1740
-
1741
1721
  $response = $stripe-&gt;cancelSubscription('dummy_data');
1742
-
1743
1722
  if ($response['status'] === 'success') {
1744
1723
  // Başarılı
1745
1724
  }</code></pre>
@@ -1770,9 +1749,7 @@ if ($response['status'] === 'success') {
1770
1749
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1771
1750
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1772
1751
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1773
-
1774
1752
  $response = $stripe-&gt;createProduct('dummy_data', $price);
1775
-
1776
1753
  if ($response['status'] === 'success') {
1777
1754
  // Başarılı
1778
1755
  }</code></pre>
@@ -1802,9 +1779,7 @@ if ($response['status'] === 'success') {
1802
1779
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1803
1780
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1804
1781
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1805
-
1806
1782
  $response = $stripe-&gt;webhook($payload, $signature);
1807
-
1808
1783
  if ($response['status'] === 'success') {
1809
1784
  // Başarılı
1810
1785
  }</code></pre>
@@ -1833,9 +1808,7 @@ if ($response['status'] === 'success') {
1833
1808
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1834
1809
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1835
1810
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$stripe = new \Service\Stripe();
1836
-
1837
1811
  $response = $stripe-&gt;listPayments();
1838
-
1839
1812
  if ($response['status'] === 'success') {
1840
1813
  // Başarılı
1841
1814
  }</code></pre>
@@ -1860,7 +1833,7 @@ if ($response['status'] === 'success') {
1860
1833
  </div>
1861
1834
  <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">JWT-Authentifizierungsdienst<br/>Bietet einen sauberen Wrapper um Firebase/php-jwt für die Token-Generierung.<br/>Überprüfung, Aktualisierung und HTTP-Middleware-Integration.<br/>Erforderliche Umgebungsvariablen:<br/>JWT_SECRET_KEY – Geheimer Schlüssel zum Signieren und Überprüfen von Token<br/>JWT_ALGORITHM – Signierungsalgorithmus (z. B. HS256, HS384, HS512)<br/>JWT_EXPIRY – Standard-Token-Lebensdauer in Sekunden (z. B. 3600)</p>
1862
1835
  <div class="alert a-info" style="margin-bottom: 20px;">
1863
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
1836
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
1864
1837
  </div>
1865
1838
  <h3>Methoden und Anwendungsbeispiele</h3>
1866
1839
  <div class="accordion-group">
@@ -1878,13 +1851,11 @@ if ($response['status'] === 'success') {
1878
1851
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1879
1852
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1880
1853
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
1881
-
1882
1854
  $payload = [
1883
1855
  'user_id' =&gt; 1453,
1884
1856
  'role' =&gt; 'admin',
1885
1857
  'email' =&gt; 'utku@artilingo.com'
1886
1858
  ];
1887
-
1888
1859
  $token = $jwt-&gt;generate($payload, 7200);
1889
1860
  echo "Bearer " . $token;</code></pre>
1890
1861
  </div>
@@ -1916,9 +1887,7 @@ echo "Bearer " . $token;</code></pre>
1916
1887
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1917
1888
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1918
1889
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
1919
-
1920
1890
  $response = $jwt-&gt;verify('dummy_data');
1921
-
1922
1891
  if ($response['status'] === 'success') {
1923
1892
  // Başarılı
1924
1893
  }</code></pre>
@@ -1950,9 +1919,7 @@ if ($response['status'] === 'success') {
1950
1919
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1951
1920
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1952
1921
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
1953
-
1954
1922
  $response = $jwt-&gt;payload('dummy_data');
1955
-
1956
1923
  if ($response['status'] === 'success') {
1957
1924
  // Başarılı
1958
1925
  }</code></pre>
@@ -1982,9 +1949,7 @@ if ($response['status'] === 'success') {
1982
1949
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
1983
1950
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
1984
1951
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
1985
-
1986
1952
  $response = $jwt-&gt;refresh('dummy_data');
1987
-
1988
1953
  if ($response['status'] === 'success') {
1989
1954
  // Başarılı
1990
1955
  }</code></pre>
@@ -2013,9 +1978,7 @@ if ($response['status'] === 'success') {
2013
1978
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2014
1979
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2015
1980
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
2016
-
2017
1981
  $response = $jwt-&gt;isExpired('dummy_data');
2018
-
2019
1982
  if ($response['status'] === 'success') {
2020
1983
  // Başarılı
2021
1984
  }</code></pre>
@@ -2042,9 +2005,7 @@ true</code></pre>
2042
2005
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2043
2006
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2044
2007
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
2045
-
2046
2008
  $response = $jwt-&gt;getUserId('dummy_data');
2047
-
2048
2009
  if ($response['status'] === 'success') {
2049
2010
  // Başarılı
2050
2011
  }</code></pre>
@@ -2072,9 +2033,7 @@ if ($response['status'] === 'success') {
2072
2033
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2073
2034
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2074
2035
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
2075
-
2076
2036
  $response = $jwt-&gt;generateRefreshToken($payload);
2077
-
2078
2037
  if ($response['status'] === 'success') {
2079
2038
  // Başarılı
2080
2039
  }</code></pre>
@@ -2097,9 +2056,7 @@ if ($response['status'] === 'success') {
2097
2056
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2098
2057
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2099
2058
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$jwt = new \Auth\JwtAuth();
2100
-
2101
2059
  $response = $jwt-&gt;middleware();
2102
-
2103
2060
  if ($response['status'] === 'success') {
2104
2061
  // Başarılı
2105
2062
  }</code></pre>
@@ -2122,9 +2079,9 @@ if ($response['status'] === 'success') {
2122
2079
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
2123
2080
  <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/ImageProcessor.php</code>
2124
2081
  </div>
2125
- <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">ImageProcessor – Wrapper für Intervention Image v3.<br/>Stellt einfache Methoden für gängige Bildoperationen bereit, z<br/>Größenänderung, Zuschneiden, Wasserzeichen, Formatkonvertierung und Komprimierung.<br/>Erforderliche ENV-Variablen:<br/>IMAGE_DRIVER – „gd“ oder „imagick“ (Standard: gd)<br/>IMAGE_QUALITY – Standard-JPEG/WebP-Qualität 1-100 (Standard: 80)</p>
2082
+ <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">ImageProcessor – Wrapper für Intervention Image v3.<br/>Stellt einfache Methoden für gängige Bildoperationen bereit, z<br/>Größenänderung, Zuschneiden, Wasserzeichen, Formatkonvertierung und Komprimierung.<br/>Erforderliche ENV-Variablen:<br/>IMAGE_DRIVER – „gd“ oder „imagick“ (Standard: gd)<br/>IMAGE_QUALITY – Standard-JPEG/WebP-Qualität 1100 (Standard: 80)</p>
2126
2083
  <div class="alert a-info" style="margin-bottom: 20px;">
2127
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
2084
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
2128
2085
  </div>
2129
2086
  <h3>Methoden und Anwendungsbeispiele</h3>
2130
2087
  <div class="accordion-group">
@@ -2144,7 +2101,6 @@ if ($response['status'] === 'success') {
2144
2101
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2145
2102
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2146
2103
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$img = new \Service\ImageProcessor();
2147
-
2148
2104
  $success = $img-&gt;resize(
2149
2105
  '/var/www/uploads/orijinal.jpg',
2150
2106
  '/var/www/uploads/resized.jpg',
@@ -2179,9 +2135,7 @@ true</code></pre>
2179
2135
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2180
2136
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2181
2137
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2182
-
2183
2138
  $response = $image-&gt;crop($inputPath, $outputPath, 'dummy_data', $height);
2184
-
2185
2139
  if ($response['status'] === 'success') {
2186
2140
  // Başarılı
2187
2141
  }</code></pre>
@@ -2198,7 +2152,7 @@ true</code></pre>
2198
2152
  <details class="accordion" style="margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 5px; background: rgba(0,0,0,0.1); box-sizing: border-box; max-width: 100%;">
2199
2153
  <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">thumbnail(string $inputPath, string $outputPath, int $size = 200)</code></summary>
2200
2154
  <div class="accordion-content" style="padding: 15px; border-top: 1px solid rgba(255,255,255,0.05); box-sizing: border-box; max-width: 100%; overflow-x: hidden;">
2201
- <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Erstellen Sie ein quadratisches Miniaturbild, indem Sie es auf die angegebene Größe zuschneiden. Die Größe des Bildes wird so geändert, dass die kürzeste Seite mit der Größe $ übereinstimmt, und dann wird es in der Mitte beschnitten, um ein perfektes Quadrat zu erhalten.</p>
2155
+ <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Erstellen Sie ein quadratisches Miniaturbild, indem Sie es auf die angegebene Größe zuschneiden. Die Größe des Bildes wird so geändert, dass die kürzeste Seite der $size entspricht, und dann in der Mitte beschnitten, um ein perfektes Quadrat zu erhalten.</p>
2202
2156
  <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
2203
2157
  <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2204
2158
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
@@ -2210,9 +2164,7 @@ true</code></pre>
2210
2164
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2211
2165
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2212
2166
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2213
-
2214
2167
  $response = $image-&gt;thumbnail($inputPath, $outputPath);
2215
-
2216
2168
  if ($response['status'] === 'success') {
2217
2169
  // Başarılı
2218
2170
  }</code></pre>
@@ -2250,9 +2202,7 @@ left, center, right, bottom-left, bottom, bottom-right.
2250
2202
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2251
2203
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2252
2204
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2253
-
2254
2205
  $response = $image-&gt;watermark($inputPath, $outputPath, $watermarkPath);
2255
-
2256
2206
  if ($response['status'] === 'success') {
2257
2207
  // Başarılı
2258
2208
  }</code></pre>
@@ -2281,9 +2231,7 @@ true</code></pre>
2281
2231
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2282
2232
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2283
2233
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2284
-
2285
2234
  $response = $image-&gt;toWebp($inputPath);
2286
-
2287
2235
  if ($response['status'] === 'success') {
2288
2236
  // Başarılı
2289
2237
  }</code></pre>
@@ -2312,9 +2260,7 @@ true</code></pre>
2312
2260
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2313
2261
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2314
2262
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2315
-
2316
2263
  $response = $image-&gt;compress($inputPath);
2317
-
2318
2264
  if ($response['status'] === 'success') {
2319
2265
  // Başarılı
2320
2266
  }</code></pre>
@@ -2343,9 +2289,7 @@ Returns an array with an 'error' key on failure.</code></pre>
2343
2289
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2344
2290
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2345
2291
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2346
-
2347
2292
  $response = $image-&gt;info($path);
2348
-
2349
2293
  if ($response['status'] === 'success') {
2350
2294
  // Başarılı
2351
2295
  }</code></pre>
@@ -2378,9 +2322,7 @@ if ($response['status'] === 'success') {
2378
2322
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2379
2323
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2380
2324
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2381
-
2382
2325
  $response = $image-&gt;rotate($inputPath, $outputPath, $angle);
2383
-
2384
2326
  if ($response['status'] === 'success') {
2385
2327
  // Başarılı
2386
2328
  }</code></pre>
@@ -2408,9 +2350,7 @@ true</code></pre>
2408
2350
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2409
2351
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2410
2352
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$image = new \Service\ImageProcessor();
2411
-
2412
2353
  $response = $image-&gt;greyscale($inputPath, $outputPath);
2413
-
2414
2354
  if ($response['status'] === 'success') {
2415
2355
  // Başarılı
2416
2356
  }</code></pre>
@@ -2427,14 +2367,14 @@ true</code></pre>
2427
2367
  </div>
2428
2368
  </div>
2429
2369
  <div class="card" id="svc-s3">
2430
- <h2>AWS S3 <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></h2>
2431
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong> Zur Verwendung des S3-Buckets <a href="https://aws.amazon.com/s3/" style="color: var(--green); font-weight: bold;" target="_blank">aws.amazon.com/s3</a> Sie müssen über ein AWS-Konto eröffnen, einen Bucket erstellen und über IAM einen Zugriffsschlüssel und einen geheimen Schlüssel mit programmgesteuerter Zugriffsberechtigung erhalten.</div>
2370
+ <h2>AWS S3<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></h2>
2371
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong>Zur Verwendung des S3-Buckets<a href="https://aws.amazon.com/s3/" style="color: var(--green); font-weight: bold;" target="_blank">aws.amazon.com/s3</a>Sie müssen über ein AWS-Konto eröffnen, einen Bucket erstellen und über IAM einen Zugriffsschlüssel und einen geheimen Schlüssel mit programmgesteuerter Zugriffsberechtigung erhalten.</div>
2432
2372
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
2433
2373
  <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/S3Storage.php</code>
2434
2374
  </div>
2435
2375
  <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">S3Storage – Wrapper für AWS S3 SDK.<br/>Bietet einfache Methoden zum Hochladen, Herunterladen, Löschen, Auflisten,<br/>und Verwalten von Dateien auf Amazon S3, MinIO, DigitalOcean Spaces oder anderen<br/>S3-kompatibler Objektspeicher.<br/>Erforderliche ENV-Variablen:<br/>AWS_ACCESS_KEY_ID – IAM-Zugriffsschlüssel<br/>AWS_SECRET_ACCESS_KEY – Geheimer IAM-Schlüssel<br/>AWS_DEFAULT_REGION – z.B. „eu-zentral-1“<br/>AWS_BUCKET – Standard-Bucket-Name<br/>Optionale ENV-Variablen:<br/>AWS_ENDPOINT – Benutzerdefinierte Endpunkt-URL (MinIO, Spaces usw.)</p>
2436
2376
  <div class="alert a-info" style="margin-bottom: 20px;">
2437
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
2377
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
2438
2378
  </div>
2439
2379
  <h3>Methoden und Anwendungsbeispiele</h3>
2440
2380
  <div class="accordion-group">
@@ -2453,9 +2393,7 @@ true</code></pre>
2453
2393
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2454
2394
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2455
2395
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2456
-
2457
2396
  $response = $s3-&gt;upload($localPath, $remotePath);
2458
-
2459
2397
  if ($response['status'] === 'success') {
2460
2398
  // Başarılı
2461
2399
  }</code></pre>
@@ -2487,9 +2425,7 @@ if ($response['status'] === 'success') {
2487
2425
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2488
2426
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2489
2427
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2490
-
2491
2428
  $response = $s3-&gt;uploadFromString($content, $remotePath, $contentType);
2492
-
2493
2429
  if ($response['status'] === 'success') {
2494
2430
  // Başarılı
2495
2431
  }</code></pre>
@@ -2519,9 +2455,7 @@ if ($response['status'] === 'success') {
2519
2455
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2520
2456
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2521
2457
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2522
-
2523
2458
  $response = $s3-&gt;download($remotePath, $localPath);
2524
-
2525
2459
  if ($response['status'] === 'success') {
2526
2460
  // Başarılı
2527
2461
  }</code></pre>
@@ -2548,9 +2482,7 @@ true</code></pre>
2548
2482
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2549
2483
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2550
2484
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2551
-
2552
2485
  $response = $s3-&gt;delete($remotePath);
2553
-
2554
2486
  if ($response['status'] === 'success') {
2555
2487
  // Başarılı
2556
2488
  }</code></pre>
@@ -2571,15 +2503,13 @@ true</code></pre>
2571
2503
  <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
2572
2504
  <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2573
2505
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
2574
- <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>@param array<string> $remotePaths List of object keys to delete.</code></pre>
2506
+ <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>@param array<string>$remotePaths Liste der zu löschenden Objektschlüssel.</string></code></pre>
2575
2507
  </div>
2576
2508
  <div style="display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; width: 100%;">
2577
2509
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2578
2510
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2579
2511
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2580
-
2581
2512
  $response = $s3-&gt;deleteMany($remotePaths);
2582
-
2583
2513
  if ($response['status'] === 'success') {
2584
2514
  // Başarılı
2585
2515
  }</code></pre>
@@ -2606,9 +2536,7 @@ true</code></pre>
2606
2536
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2607
2537
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2608
2538
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2609
-
2610
2539
  $response = $s3-&gt;url($remotePath);
2611
-
2612
2540
  if ($response['status'] === 'success') {
2613
2541
  // Başarılı
2614
2542
  }</code></pre>
@@ -2636,9 +2564,7 @@ if ($response['status'] === 'success') {
2636
2564
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2637
2565
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2638
2566
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2639
-
2640
2567
  $response = $s3-&gt;signedUrl($remotePath);
2641
-
2642
2568
  if ($response['status'] === 'success') {
2643
2569
  // Başarılı
2644
2570
  }</code></pre>
@@ -2665,9 +2591,7 @@ if ($response['status'] === 'success') {
2665
2591
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2666
2592
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2667
2593
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2668
-
2669
2594
  $response = $s3-&gt;exists($remotePath);
2670
-
2671
2595
  if ($response['status'] === 'success') {
2672
2596
  // Başarılı
2673
2597
  }</code></pre>
@@ -2694,9 +2618,7 @@ true</code></pre>
2694
2618
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2695
2619
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2696
2620
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2697
-
2698
2621
  $response = $s3-&gt;list();
2699
-
2700
2622
  if ($response['status'] === 'success') {
2701
2623
  // Başarılı
2702
2624
  }</code></pre>
@@ -2726,9 +2648,7 @@ if ($response['status'] === 'success') {
2726
2648
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2727
2649
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2728
2650
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2729
-
2730
2651
  $response = $s3-&gt;copy($from, $to);
2731
-
2732
2652
  if ($response['status'] === 'success') {
2733
2653
  // Başarılı
2734
2654
  }</code></pre>
@@ -2756,9 +2676,7 @@ true</code></pre>
2756
2676
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2757
2677
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2758
2678
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2759
-
2760
2679
  $response = $s3-&gt;move($from, $to);
2761
-
2762
2680
  if ($response['status'] === 'success') {
2763
2681
  // Başarılı
2764
2682
  }</code></pre>
@@ -2785,9 +2703,7 @@ true</code></pre>
2785
2703
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2786
2704
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2787
2705
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$s3 = new \Service\S3Storage();
2788
-
2789
2706
  $response = $s3-&gt;size($remotePath);
2790
-
2791
2707
  if ($response['status'] === 'success') {
2792
2708
  // Başarılı
2793
2709
  }</code></pre>
@@ -2810,7 +2726,7 @@ if ($response['status'] === 'success') {
2810
2726
  </div>
2811
2727
  <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Redis-Cache-Dienst<br/>Bietet eine saubere, einfache Schnittstelle für Redis-Caching-Vorgänge<br/>unter Verwendung des predis/predis SDK. Die gesamte Konfiguration wird von $_ENV gelesen.<br/>Erforderliche Umgebungsvariablen:<br/>REDIS_HOST – Hostname des Redis-Servers (Standard: 127.0.0.1)<br/>REDIS_PORT – Redis-Server-Port (Standard: 6379)<br/>REDIS_PASSWORD – Redis-Authentifizierungskennwort (Standard: null)<br/>REDIS_DATABASE – Redis-Datenbankindex (Standard: 0)</p>
2812
2728
  <div class="alert a-info" style="margin-bottom: 20px;">
2813
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
2729
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
2814
2730
  </div>
2815
2731
  <h3>Methoden und Anwendungsbeispiele</h3>
2816
2732
  <div class="accordion-group">
@@ -2828,9 +2744,7 @@ if ($response['status'] === 'success') {
2828
2744
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2829
2745
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2830
2746
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
2831
-
2832
2747
  $response = $redis-&gt;get($key);
2833
-
2834
2748
  if ($response['status'] === 'success') {
2835
2749
  // Başarılı
2836
2750
  }</code></pre>
@@ -2859,9 +2773,7 @@ if ($response['status'] === 'success') {
2859
2773
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2860
2774
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2861
2775
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
2862
-
2863
2776
  $response = $redis-&gt;set($key, $value);
2864
-
2865
2777
  if ($response['status'] === 'success') {
2866
2778
  // Başarılı
2867
2779
  }</code></pre>
@@ -2888,9 +2800,7 @@ true</code></pre>
2888
2800
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2889
2801
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2890
2802
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
2891
-
2892
2803
  $response = $redis-&gt;has($key);
2893
-
2894
2804
  if ($response['status'] === 'success') {
2895
2805
  // Başarılı
2896
2806
  }</code></pre>
@@ -2917,9 +2827,7 @@ true</code></pre>
2917
2827
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2918
2828
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2919
2829
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
2920
-
2921
2830
  $response = $redis-&gt;forget($key);
2922
-
2923
2831
  if ($response['status'] === 'success') {
2924
2832
  // Başarılı
2925
2833
  }</code></pre>
@@ -2948,9 +2856,7 @@ true</code></pre>
2948
2856
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2949
2857
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2950
2858
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
2951
-
2952
2859
  $response = $redis-&gt;remember($key, $ttl, $callback);
2953
-
2954
2860
  if ($response['status'] === 'success') {
2955
2861
  // Başarılı
2956
2862
  }</code></pre>
@@ -2980,9 +2886,7 @@ if ($response['status'] === 'success') {
2980
2886
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
2981
2887
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
2982
2888
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
2983
-
2984
2889
  $response = $redis-&gt;increment($key);
2985
-
2986
2890
  if ($response['status'] === 'success') {
2987
2891
  // Başarılı
2988
2892
  }</code></pre>
@@ -3010,9 +2914,7 @@ true</code></pre>
3010
2914
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3011
2915
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3012
2916
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3013
-
3014
2917
  $response = $redis-&gt;decrement($key);
3015
-
3016
2918
  if ($response['status'] === 'success') {
3017
2919
  // Başarılı
3018
2920
  }</code></pre>
@@ -3035,9 +2937,7 @@ true</code></pre>
3035
2937
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3036
2938
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3037
2939
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3038
-
3039
2940
  $response = $redis-&gt;flush();
3040
-
3041
2941
  if ($response['status'] === 'success') {
3042
2942
  // Başarılı
3043
2943
  }</code></pre>
@@ -3064,9 +2964,7 @@ true</code></pre>
3064
2964
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3065
2965
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3066
2966
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3067
-
3068
2967
  $response = $redis-&gt;keys();
3069
-
3070
2968
  if ($response['status'] === 'success') {
3071
2969
  // Başarılı
3072
2970
  }</code></pre>
@@ -3095,9 +2993,7 @@ if ($response['status'] === 'success') {
3095
2993
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3096
2994
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3097
2995
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3098
-
3099
2996
  $response = $redis-&gt;ttl($key);
3100
-
3101
2997
  if ($response['status'] === 'success') {
3102
2998
  // Başarılı
3103
2999
  }</code></pre>
@@ -3125,9 +3021,7 @@ if ($response['status'] === 'success') {
3125
3021
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3126
3022
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3127
3023
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3128
-
3129
3024
  $response = $redis-&gt;expire($key, $seconds);
3130
-
3131
3025
  if ($response['status'] === 'success') {
3132
3026
  // Başarılı
3133
3027
  }</code></pre>
@@ -3156,9 +3050,7 @@ true</code></pre>
3156
3050
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3157
3051
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3158
3052
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3159
-
3160
3053
  $response = $redis-&gt;hSet($hash, $field, $value);
3161
-
3162
3054
  if ($response['status'] === 'success') {
3163
3055
  // Başarılı
3164
3056
  }</code></pre>
@@ -3187,9 +3079,7 @@ true</code></pre>
3187
3079
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3188
3080
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3189
3081
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3190
-
3191
3082
  $response = $redis-&gt;hGet($hash, $field);
3192
-
3193
3083
  if ($response['status'] === 'success') {
3194
3084
  // Başarılı
3195
3085
  }</code></pre>
@@ -3218,9 +3108,7 @@ if ($response['status'] === 'success') {
3218
3108
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3219
3109
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3220
3110
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3221
-
3222
3111
  $response = $redis-&gt;hGetAll($hash);
3223
-
3224
3112
  if ($response['status'] === 'success') {
3225
3113
  // Başarılı
3226
3114
  }</code></pre>
@@ -3250,9 +3138,7 @@ if ($response['status'] === 'success') {
3250
3138
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3251
3139
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3252
3140
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$redis = new \Service\RedisCache();
3253
-
3254
3141
  $response = $redis-&gt;hDel($hash, $field);
3255
-
3256
3142
  if ($response['status'] === 'success') {
3257
3143
  // Başarılı
3258
3144
  }</code></pre>
@@ -3269,14 +3155,14 @@ true</code></pre>
3269
3155
  </div>
3270
3156
  </div>
3271
3157
  <div class="card" id="svc-pusher">
3272
- <h2>Pusher <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></h2>
3273
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong> Zur Kommunikation in Echtzeit über WebSocket <a href="https://pusher.com" style="color: var(--green); font-weight: bold;" target="_blank">pusher.com</a> Sie sollten über eine kostenlose Channels-Anwendung erstellen und Ihre App-ID, Schlüssel- und Geheiminformationen erhalten.</div>
3158
+ <h2>Pusher<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></h2>
3159
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong>Zur Kommunikation in Echtzeit über WebSocket<a href="https://pusher.com" style="color: var(--green); font-weight: bold;" target="_blank">pusher.com</a>Sie sollten über eine kostenlose Channels-Anwendung erstellen und Ihre App-ID, Schlüssel- und Geheiminformationen erhalten.</div>
3274
3160
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
3275
3161
  <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/Pusher.php</code>
3276
3162
  </div>
3277
3163
  <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Pusher-Echtzeitdienst<br/>Bietet eine übersichtliche Schnittstelle für Pusher-Kanäle – Übertragung von Ereignissen,<br/>Authentifizieren von Privat-/Präsenzkanälen und Abfragen des Kanalstatus.<br/>Verwendet das pusher/pusher-php-server SDK. Alle Konfigurationen von $_ENV.<br/>Erforderliche Umgebungsvariablen:<br/>PUSHER_APP_ID – Ihre Pusher-Anwendungs-ID<br/>PUSHER_APP_KEY – Ihr Pusher-Anwendungsschlüssel<br/>PUSHER_APP_SECRET – Ihr Pusher-Anwendungsgeheimnis<br/>PUSHER_CLUSTER – Pusher-Cluster-Region (z. B. „eu“, „us2“, „ap1“)</p>
3278
3164
  <div class="alert a-info" style="margin-bottom: 20px;">
3279
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
3165
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
3280
3166
  </div>
3281
3167
  <h3>Methoden und Anwendungsbeispiele</h3>
3282
3168
  <div class="accordion-group">
@@ -3295,9 +3181,7 @@ true</code></pre>
3295
3181
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3296
3182
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3297
3183
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3298
-
3299
3184
  $response = $pusher-&gt;broadcast($channel, $event, $data);
3300
-
3301
3185
  if ($response['status'] === 'success') {
3302
3186
  // Başarılı
3303
3187
  }</code></pre>
@@ -3326,9 +3210,7 @@ true</code></pre>
3326
3210
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3327
3211
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3328
3212
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3329
-
3330
3213
  $response = $pusher-&gt;broadcastToMany($channels, $event, $data);
3331
-
3332
3214
  if ($response['status'] === 'success') {
3333
3215
  // Başarılı
3334
3216
  }</code></pre>
@@ -3357,9 +3239,7 @@ true</code></pre>
3357
3239
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3358
3240
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3359
3241
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3360
-
3361
3242
  $response = $pusher-&gt;toUser('dummy_data', $event, $data);
3362
-
3363
3243
  if ($response['status'] === 'success') {
3364
3244
  // Başarılı
3365
3245
  }</code></pre>
@@ -3387,9 +3267,7 @@ Returns empty array on failure</code></pre>
3387
3267
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3388
3268
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3389
3269
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3390
-
3391
3270
  $response = $pusher-&gt;channelInfo($channel);
3392
-
3393
3271
  if ($response['status'] === 'success') {
3394
3272
  // Başarılı
3395
3273
  }</code></pre>
@@ -3419,9 +3297,7 @@ if ($response['status'] === 'success') {
3419
3297
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3420
3298
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3421
3299
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3422
-
3423
3300
  $response = $pusher-&gt;channels();
3424
-
3425
3301
  if ($response['status'] === 'success') {
3426
3302
  // Başarılı
3427
3303
  }</code></pre>
@@ -3451,9 +3327,7 @@ if ($response['status'] === 'success') {
3451
3327
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3452
3328
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3453
3329
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3454
-
3455
3330
  $response = $pusher-&gt;auth('dummy_data', 'dummy_data');
3456
-
3457
3331
  if ($response['status'] === 'success') {
3458
3332
  // Başarılı
3459
3333
  }</code></pre>
@@ -3483,9 +3357,7 @@ if ($response['status'] === 'success') {
3483
3357
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3484
3358
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3485
3359
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$pusher = new \Service\Pusher();
3486
-
3487
3360
  $response = $pusher-&gt;presenceAuth('dummy_data', 'dummy_data', 'dummy_data');
3488
-
3489
3361
  if ($response['status'] === 'success') {
3490
3362
  // Başarılı
3491
3363
  }</code></pre>
@@ -3502,14 +3374,14 @@ if ($response['status'] === 'success') {
3502
3374
  </div>
3503
3375
  </div>
3504
3376
  <div class="card" id="svc-twilio">
3505
- <h2>Twilio <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></h2>
3506
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong> Zum Versenden von SMS- und WhatsApp-Nachrichten <a href="https://www.twilio.com" style="color: var(--green); font-weight: bold;" target="_blank">twilio.com</a> Sie müssen ein Konto eröffnen, eine verfügbare Telefonnummer mieten und Ihre Konto-SID- und Auth-Token-Informationen über das Panel abrufen.</div>
3377
+ <h2>Twitter<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></h2>
3378
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong>Zum Versenden von SMS- und WhatsApp-Nachrichten<a href="https://www.twilio.com" style="color: var(--green); font-weight: bold;" target="_blank">twilio.com</a>Sie müssen ein Konto eröffnen, eine verfügbare Telefonnummer mieten und Ihre Konto-SID- und Auth-Token-Informationen über das Panel abrufen.</div>
3507
3379
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
3508
3380
  <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/Twilio.php</code>
3509
3381
  </div>
3510
- <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Twilio-Kommunikationsdienst<br/>Bietet eine vereinfachte Schnittstelle für Twilios Nachrichten-, Sprach- und<br/>und Verifizierungs-APIs mit twilio/sdk. Alle Konfigurationen<br/>wird aus $_ENV gelesen.<br/>Erforderliche Umgebungsvariablen:<br/>TWILIO_SID – Ihre Twilio-Konto-SID<br/>TWILIO_AUTH_TOKEN – Ihr Twilio-Authentifizierungstoken<br/>TWILIO_FROM_NUMBER – Standard-Von-Telefonnummer (E.164-Format, z. B. +15551234567)<br/>Optionale Umgebungsvariablen:<br/>TWILIO_VERIFY_SID – Dienst-SID überprüfen (erforderlich für verifyStart/verifyCheck)</p>
3382
+ <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Twilio-Kommunikationsdienst<br/>Bietet eine vereinfachte Schnittstelle für Twilios Nachrichten-, Sprach- und<br/>und Verifizierungs-APIs mit twilio/sdk. Alle Konfigurationen<br/>wird aus $_ENV gelesen.<br/>Erforderliche Umgebungsvariablen:<br/>TWILIO_SID – Ihre Twilio-Konto-SID<br/>TWILIO_AUTH_TOKEN – Ihr Twilio-Authentifizierungstoken<br/>TWILIO_FROM_NUMBER – Standard-Absender-Telefonnummer (E.164-Format, z. B. +15551234567)<br/>Optionale Umgebungsvariablen:<br/>TWILIO_VERIFY_SID – Dienst-SID überprüfen (erforderlich für verifyStart/verifyCheck)</p>
3511
3383
  <div class="alert a-info" style="margin-bottom: 20px;">
3512
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
3384
+ <strong>ℹ️ Standardrückgabe:</strong>Alle Methoden<code>['status' =&gt; 'success|error', 'message' =&gt; '...', 'data' =&gt; [...]]</code>Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen).<strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird.<code>data</code>Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
3513
3385
  </div>
3514
3386
  <h3>Methoden und Anwendungsbeispiele</h3>
3515
3387
  <div class="accordion-group">
@@ -3522,15 +3394,13 @@ if ($response['status'] === 'success') {
3522
3394
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
3523
3395
  <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>@param string $to Recipient phone number in E.164 format (e.g., +905551234567)
3524
3396
  @param string $message The SMS body text (max 1600 characters)
3525
- On error: 'status' => 'error', 'message' => error description</code></pre>
3397
+ On error: 'status' =&gt; 'error', 'message' =&gt; error description</code></pre>
3526
3398
  </div>
3527
3399
  <div style="display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; width: 100%;">
3528
3400
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3529
3401
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3530
3402
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3531
-
3532
3403
  $response = $twilio-&gt;sendSms($to, $message);
3533
-
3534
3404
  if ($response['status'] === 'success') {
3535
3405
  // Başarılı
3536
3406
  }</code></pre>
@@ -3560,9 +3430,7 @@ if ($response['status'] === 'success') {
3560
3430
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3561
3431
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3562
3432
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3563
-
3564
3433
  $response = $twilio-&gt;sendWhatsApp($to, $message);
3565
-
3566
3434
  if ($response['status'] === 'success') {
3567
3435
  // Başarılı
3568
3436
  }</code></pre>
@@ -3581,7 +3449,7 @@ if ($response['status'] === 'success') {
3581
3449
  <details class="accordion" style="margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 5px; background: rgba(0,0,0,0.1); box-sizing: border-box; max-width: 100%;">
3582
3450
  <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">call(string $to, string $twimlUrl)</code></summary>
3583
3451
  <div class="accordion-content" style="padding: 15px; border-top: 1px solid rgba(255,255,255,0.05); box-sizing: border-box; max-width: 100%; overflow-x: hidden;">
3584
- <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Starten Sie einen Sprachanruf. Tätigt einen ausgehenden Anruf an die angegebene Nummer. Das Aufrufverhalten wird durch das TwiML-Dokument unter der angegebenen URL definiert. Die TwiML-URL sollte Anweisungen zurückgeben wie <say>, <play>, <gather>, usw.</gather></play></say></p>
3452
+ <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Starten Sie einen Sprachanruf. Tätigt einen ausgehenden Anruf an die angegebene Nummer. Das Aufrufverhalten wird durch das TwiML-Dokument unter der angegebenen URL definiert. Die TwiML-URL sollte Anweisungen zurückgeben wie<say>, <play>, <gather>, usw.</gather></play></say></p>
3585
3453
  <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
3586
3454
  <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3587
3455
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
@@ -3592,9 +3460,7 @@ if ($response['status'] === 'success') {
3592
3460
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3593
3461
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3594
3462
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3595
-
3596
3463
  $response = $twilio-&gt;call($to, $twimlUrl);
3597
-
3598
3464
  if ($response['status'] === 'success') {
3599
3465
  // Başarılı
3600
3466
  }</code></pre>
@@ -3625,9 +3491,7 @@ status will be 'pending' on success</code></pre>
3625
3491
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3626
3492
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3627
3493
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3628
-
3629
3494
  $response = $twilio-&gt;verifyStart($to);
3630
-
3631
3495
  if ($response['status'] === 'success') {
3632
3496
  // Başarılı
3633
3497
  }</code></pre>
@@ -3658,9 +3522,7 @@ status will be 'approved' on successful verification</code></pre>
3658
3522
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3659
3523
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3660
3524
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3661
-
3662
3525
  $response = $twilio-&gt;verifyCheck($to, $code);
3663
-
3664
3526
  if ($response['status'] === 'success') {
3665
3527
  // Başarılı
3666
3528
  }</code></pre>
@@ -3690,9 +3552,7 @@ if ($response['status'] === 'success') {
3690
3552
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3691
3553
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3692
3554
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3693
-
3694
3555
  $response = $twilio-&gt;getMessageStatus('dummy_data');
3695
-
3696
3556
  if ($response['status'] === 'success') {
3697
3557
  // Başarılı
3698
3558
  }</code></pre>
@@ -3722,9 +3582,7 @@ if ($response['status'] === 'success') {
3722
3582
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3723
3583
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3724
3584
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3725
-
3726
3585
  $response = $twilio-&gt;listMessages();
3727
-
3728
3586
  if ($response['status'] === 'success') {
3729
3587
  // Başarılı
3730
3588
  }</code></pre>
@@ -3755,9 +3613,7 @@ if ($response['status'] === 'success') {
3755
3613
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3756
3614
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3757
3615
  <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$twilio = new \Service\Twilio();
3758
-
3759
3616
  $response = $twilio-&gt;sendBulkSms($recipients, $message);
3760
-
3761
3617
  if ($response['status'] === 'success') {
3762
3618
  // Başarılı
3763
3619
  }</code></pre>
@@ -3776,85 +3632,25 @@ if ($response['status'] === 'success') {
3776
3632
  </div>
3777
3633
  </div>
3778
3634
  <div class="card" id="svc-sentry">
3779
- <h2>Sentry <span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Ücretli/Lisanslı Servis">$</span></h2>
3780
- <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong> Um Fehler- und Leistungsverfolgung zu ermöglichen <a href="https://sentry.io" style="color: var(--green); font-weight: bold;" target="_blank">sentry.io</a> Sie müssen Ihr kostenloses Konto über erstellen, ein PHP-Projekt hinzufügen und die Ihnen gegebene DSN-Adresse (Client Key) kopieren.</div>
3635
+ <h2>Posten<span class="tag b-core" style="padding: 1px 5px; margin-left: 2px; font-weight: bold;" title="Kostenpflichtiger/lizenzierter Dienst">$</span></h2>
3636
+ <div class="alert a-info" style="margin-top: 10px; padding: 10px 15px; font-size: 0.85em;"><strong>📌 Mitgliedschaft und API-Schlüssel:</strong>Um Fehler- und Leistungsverfolgung zu ermöglichen<a href="https://sentry.io" style="color: var(--green); font-weight: bold;" target="_blank">sentry.io</a>Sie müssen Ihr kostenloses Konto über erstellen, ein PHP-Projekt hinzufügen und die Ihnen gegebene DSN-Adresse (Client Key) kopieren.</div>
3781
3637
  <div class="code-badge" style="margin-bottom: 15px; padding: 10px; background: rgba(0,0,0,0.2); border: 1px solid rgba(255,255,255,0.05); border-radius: 6px; font-family: monospace;">
3782
- <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">config/sentry.php</code>
3638
+ <strong>Unterrichtsort:</strong> <code style="color: #4ade80;">src/Service/Sentry.php</code>
3783
3639
  </div>
3784
- <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;"></p>
3640
+ <p style="margin-bottom: 15px; font-size: 0.95em; color: #a1a1aa;">Es ermöglicht Ihnen, Fehler und Warnungen in Ihrem Projekt in einem zentralen Protokollsystem zu sammeln. Zu Beginn Ihrer Bewerbung (z.B.<code>ApiControl.php</code>oder<code>ViewControl.php</code>Es wird empfohlen, mit zu beginnen.</p>
3785
3641
  <div class="alert a-info" style="margin-bottom: 20px;">
3786
- <strong>ℹ️ Standardrückgabe:</strong> Alle Methoden <code>['status' => 'success|error', 'message' => '...', 'data' => [...]]</code> Konvertiert eine Standardzeichenfolge in das Format (mit Ausnahmen). <strong>im Array, das im Abschnitt „Erwartete Rückgabe“ unten zurückgegeben wird. <code>data</code> Die detaillierte Struktur des Schlüssels wird angezeigt.</strong>
3787
- </div>
3642
+ <strong>ℹ️ Statische Klasse:</strong>Diese Serviceklasse wird direkt mit statischen Methoden verwendet, Sie müssen keine neue Instanz erstellen.</div>
3788
3643
  <h3>Methoden und Anwendungsbeispiele</h3>
3789
3644
  <div class="accordion-group">
3790
3645
  <details class="accordion" style="margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 5px; background: rgba(0,0,0,0.1); box-sizing: border-box; max-width: 100%;">
3791
- <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">captureError(\Throwable $e)</code></summary>
3646
+ <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">init()</code></summary>
3792
3647
  <div class="accordion-content" style="padding: 15px; border-top: 1px solid rgba(255,255,255,0.05); box-sizing: border-box; max-width: 100%; overflow-x: hidden;">
3793
- <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Sentry-Fehlerverfolgungskonfiguration Initialisiert das Sentry SDK für die Fehlerberichterstattung und stellt Hilfsfunktionen zum Erfassen von Ausnahmen und Meldungen bereit. Erforderliche ENV-Variablen: SENTRY_DSN Sentry-Datenquellenname (Projekt-DSN von sentry.io) Optionale ENV-Variablen: APP_ENV – „0“ für Produktion, „1“ für Entwicklung (Standard: 0) APP_VERSION – Anwendungsversionszeichenfolge, wird als Sentry-Release-Tag verwendet. Verwendung: require_once __DIR__ . '/sentry.php'; // Eine Ausnahme einfangen try { ... } Catch (\Throwable $e) { $eventId = captureError($e);</p>
3648
+ <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Initialisiert das Sentry SDK basierend auf Umgebungsvariablen. Es muss einmalig zu Beginn der Anwendung aufgerufen werden.</p>
3794
3649
  <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
3795
- <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3796
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
3797
- <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>}
3798
- // Capture an informational message
3799
- captureMessage('Deployment completed', 'info');
3800
- /
3801
- // ---------------------------------------------------------------
3802
- // Guard — only initialize when a DSN is available
3803
- // ---------------------------------------------------------------
3804
- if (empty($_ENV['SENTRY_DSN'])) {
3805
- /**
3806
- No-op fallback when Sentry is not configured.
3807
- @param \Throwable $e The exception (ignored).</code></pre>
3808
- </div>
3809
3650
  <div style="display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; width: 100%;">
3810
3651
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3811
3652
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3812
- <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$sentry = new \Service\sentry();
3813
-
3814
- $response = $sentry-&gt;captureError($e);
3815
-
3816
- if ($response['status'] === 'success') {
3817
- // Başarılı
3818
- }</code></pre>
3819
- </div>
3820
- <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3821
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Erwartete Rückgabe ($response['data']):</h4>
3822
- <pre style="background: rgba(69,26,3,0.4); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #facc15; border: 1px solid rgba(250,204,21,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>[
3823
- 'id' =&gt; '...',
3824
- 'success' =&gt; true
3825
- ]</code></pre>
3826
- </div>
3827
- </div>
3828
- </div>
3829
- </div>
3830
- </details>
3831
- <details class="accordion" style="margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 5px; background: rgba(0,0,0,0.1); box-sizing: border-box; max-width: 100%;">
3832
- <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">captureMessage(string $message, string $level = 'info')</code></summary>
3833
- <div class="accordion-content" style="padding: 15px; border-top: 1px solid rgba(255,255,255,0.05); box-sizing: border-box; max-width: 100%; overflow-x: hidden;">
3834
- <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">No-Op-Fallback, wenn Sentry nicht konfiguriert ist.</p>
3835
- <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
3836
- <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3837
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
3838
- <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>@param string $message The message (ignored).
3839
- @param string $level Severity level (ignored).</code></pre>
3840
- </div>
3841
- <div style="display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; width: 100%;">
3842
- <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3843
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3844
- <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$sentry = new \Service\sentry();
3845
-
3846
- $response = $sentry-&gt;captureMessage($message);
3847
-
3848
- if ($response['status'] === 'success') {
3849
- // Başarılı
3850
- }</code></pre>
3851
- </div>
3852
- <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3853
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Erwartete Rückgabe ($response['data']):</h4>
3854
- <pre style="background: rgba(69,26,3,0.4); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #facc15; border: 1px solid rgba(250,204,21,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>[
3855
- 'id' =&gt; '...',
3856
- 'success' =&gt; true
3857
- ]</code></pre>
3653
+ <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>\Src\Service\Sentry::init();</code></pre>
3858
3654
  </div>
3859
3655
  </div>
3860
3656
  </div>
@@ -3863,36 +3659,20 @@ if ($response['status'] === 'success') {
3863
3659
  <details class="accordion" style="margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 5px; background: rgba(0,0,0,0.1); box-sizing: border-box; max-width: 100%;">
3864
3660
  <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">captureError(\Throwable $e)</code></summary>
3865
3661
  <div class="accordion-content" style="padding: 15px; border-top: 1px solid rgba(255,255,255,0.05); box-sizing: border-box; max-width: 100%; overflow-x: hidden;">
3866
- <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">$isProduction = ($_ENV['APP_ENV'] ?? '0') === '0'; /** @var string Menschenlesbarer Umgebungsname für Sentry */ $environment = $isProduction ? 'Produktion': 'Entwicklung'; /** Abtastrate: 1,0 – 100 % der Ereignisse in der Produktion erfassen 0,0 – nichts in der Entwicklung erfassen (captureError/captureMessage explizit verwenden) / $sampleRate = $isProduction ? 1,0 : 0,0; // ----------------------------------------------------------------- // Sentry-Initialisierung // ------------------------------------------------------------------------------ $options = [ 'dsn' =&gt; $_ENV['SENTRY_DSN'], 'environment' =&gt; $environment, 'sample_rate' =&gt; $sampleRate, ]; // Release-Version anhängen, wenn verfügbar if (!empty($_ENV['APP_VERSION'])) { $options['release'] = $_ENV['APP_VERSION'];</p>
3662
+ <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Sendet eine abgefangene Ausnahme oder ein auswerfbares Objekt an Sentry.</p>
3867
3663
  <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
3868
- <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3869
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
3870
- <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>}
3871
- \Sentry\init($options);
3872
- // ---------------------------------------------------------------
3873
- // Helper functions
3874
- // ---------------------------------------------------------------
3875
- /**
3876
- Capture a Throwable and send it to Sentry.
3877
- @param \Throwable $e The exception or error to report.</code></pre>
3878
- </div>
3879
3664
  <div style="display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; width: 100%;">
3880
3665
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3881
3666
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3882
- <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$sentry = new \Service\sentry();
3883
-
3884
- $response = $sentry-&gt;captureError($e);
3885
-
3886
- if ($response['status'] === 'success') {
3887
- // Başarılı
3667
+ <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>try {
3668
+ // Hata yapabilecek işlemler...
3669
+ } catch (\Throwable $e) {
3670
+ $eventId = \Src\Service\Sentry::captureError($e);
3888
3671
  }</code></pre>
3889
3672
  </div>
3890
3673
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3891
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Erwartete Rückgabe ($response['data']):</h4>
3892
- <pre style="background: rgba(69,26,3,0.4); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #facc15; border: 1px solid rgba(250,204,21,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>[
3893
- 'id' =&gt; '...',
3894
- 'success' =&gt; true
3895
- ]</code></pre>
3674
+ <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Erwartete Rückgabe (string|null):</h4>
3675
+ <pre style="background: rgba(69,26,3,0.4); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #facc15; border: 1px solid rgba(250,204,21,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>"dfb9370...b86" // Sentry Olay ID'si</code></pre>
3896
3676
  </div>
3897
3677
  </div>
3898
3678
  </div>
@@ -3901,30 +3681,12 @@ if ($response['status'] === 'success') {
3901
3681
  <details class="accordion" style="margin-bottom: 10px; border: 1px solid rgba(255,255,255,0.1); border-radius: 6px; padding: 5px; background: rgba(0,0,0,0.1); box-sizing: border-box; max-width: 100%;">
3902
3682
  <summary style="cursor: pointer; padding: 10px; font-weight: bold; background: rgba(255,255,255,0.05); color: #fff; border-radius: 4px; box-sizing: border-box; max-width: 100%; word-break: break-all;"><code style="background: transparent; color: #60a5fa; font-size: 1.1em; white-space: pre-wrap; word-break: break-all;">captureMessage(string $message, string $level = 'info')</code></summary>
3903
3683
  <div class="accordion-content" style="padding: 15px; border-top: 1px solid rgba(255,255,255,0.05); box-sizing: border-box; max-width: 100%; overflow-x: hidden;">
3904
- <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Erfassen Sie eine Klartextnachricht und senden Sie sie an Sentry. Unterstützte Schweregrade: schwerwiegend, Fehler, Warnung, Info, Debug.</p>
3684
+ <p style="color: #d1d5db; margin-bottom: 15px; word-wrap: break-word;">Sendet einen angegebenen Text als Informations-/Warnmeldung an Sentry. Gültige Level:<code>fatal</code>, <code>error</code>, <code>warning</code>, <code>info</code>, <code>debug</code>.</p>
3905
3685
  <div style="display: flex; flex-direction: column; gap: 15px; box-sizing: border-box; width: 100%; max-width: 100%;">
3906
- <div style="flex: 1; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3907
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Parameterstruktur:</h4>
3908
- <pre style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #a78bfa; border: 1px solid rgba(255,255,255,0.05); margin: 0; box-sizing: border-box; max-width: 100%;"><code>@param string $message Human-readable message to log.
3909
- @param string $level Sentry severity level (default: info).</code></pre>
3910
- </div>
3911
3686
  <div style="display: flex; flex-wrap: wrap; gap: 15px; box-sizing: border-box; width: 100%;">
3912
3687
  <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3913
3688
  <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Beispielverwendung:</h4>
3914
- <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$sentry = new \Service\sentry();
3915
-
3916
- $response = $sentry-&gt;captureMessage($message);
3917
-
3918
- if ($response['status'] === 'success') {
3919
- // Başarılı
3920
- }</code></pre>
3921
- </div>
3922
- <div style="flex: 1; min-width: 250px; max-width: 100%; box-sizing: border-box; overflow: hidden;">
3923
- <h4 style="margin-bottom: 8px; font-size: 0.9em; color: #9ca3af;">Erwartete Rückgabe ($response['data']):</h4>
3924
- <pre style="background: rgba(69,26,3,0.4); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #facc15; border: 1px solid rgba(250,204,21,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>[
3925
- 'id' =&gt; '...',
3926
- 'success' =&gt; true
3927
- ]</code></pre>
3689
+ <pre style="background: rgba(15,23,42,0.6); padding: 10px; border-radius: 4px; font-size: 0.85em; overflow-x: auto; color: #34d399; border: 1px solid rgba(52,211,153,0.2); margin: 0; height: 100%; box-sizing: border-box; max-width: 100%;"><code>$eventId = \Src\Service\Sentry::captureMessage('Sipariş başarıyla tamamlandı.', 'info');</code></pre>
3928
3690
  </div>
3929
3691
  </div>
3930
3692
  </div>
@@ -3933,63 +3695,55 @@ if ($response['status'] === 'success') {
3933
3695
  </div>
3934
3696
  </div>
3935
3697
  </section>
3936
- <!-- ====== VIEW HELPERS ====== -->
3698
+ ====== HELFER ANZEIGEN ======
3937
3699
  <section id="vh-display">
3938
- <h2>ViewHelpers— <code>display()</code> <span class="tag b-view">ViewMethod</span></h2>
3939
- <p>Beim Drucken von Daten aus der Datenbank oder Benutzereingaben im DOM <strong>obligatorischer XSS-Schutz</strong> implementiert. Anstatt bei Null- oder leeren Werten einen Fehler auszulösen, wird der Standardwert zurückgegeben.</p>
3940
- <span class="ret">string display(mixed $data, string $default = '')</span>
3700
+ <h2>ViewHelpers—<code>display()</code> <span class="tag b-view">ViewMethod</span></h2>
3701
+ <p>Beim Drucken von Daten aus der Datenbank oder Benutzereingaben im DOM<strong>obligatorischer XSS-Schutz</strong>implementiert. Anstatt bei Null- oder leeren Werten einen Fehler auszulösen, wird der Standardwert zurückgegeben.</p>
3702
+ <span class="ret">String-Anzeige (gemischte $data, string $default = '')</span>
3941
3703
  <div class="alert a-info" style="margin-top: 10px; margin-bottom: 24px; padding: 12px 20px;">
3942
- <strong>💡 Tipp: <code>$default</code> Verwendung</strong><br/>
3943
- Zweiter Parameter (<code>$default</code>) ist der Rettungstext, der auf dem Bildschirm gedruckt wird, wenn die aus der Datenbank kommenden Daten leer sind (null, falsch, leere Zeichenfolge). Zum Beispiel für einen Benutzer, dessen Namensdaten nicht eingegeben werden <code>display($isim, 'İsimsiz')</code> Wenn Sie es verwenden, präsentiert Ihre Seite aussagekräftige Inhalte anstelle hässlicher Leerzeichen.
3944
- </div>
3945
- <pre><code><span class="cm">&lt;!-- Güvensiz XSS açığı oluşturur --&gt;</span>
3946
- &lt;h1&gt;&lt;?= <span class="var">$user</span>[<span class="st">'isim'</span>] ?&gt;&lt;/h1&gt;
3947
-
3948
- <span class="cm">&lt;!-- ✅ ArtiFrame Güvenli Kullanımı --&gt;</span>
3949
- &lt;h1&gt;&lt;?= <span class="fn">display</span>(<span class="var">$user</span>[<span class="st">'isim'</span>], <span class="st">'İsimsiz Kullanıcı'</span>) ?&gt;&lt;/h1&gt;</code></pre>
3704
+ <strong>💡 Tipp:<code>$default</code>Verwendung</strong><br/>Zweiter Parameter (<code>$default</code>) ist der Rettungstext, der auf dem Bildschirm gedruckt wird, wenn die aus der Datenbank kommenden Daten leer sind (null, falsch, leere Zeichenfolge). Zum Beispiel für einen Benutzer, dessen Namensdaten nicht eingegeben werden<code>display($isim, 'İsimsiz')</code>Wenn Sie es verwenden, präsentiert Ihre Seite aussagekräftige Inhalte anstelle hässlicher Leerzeichen.</div>
3705
+ <pre><code><span class="cm">&lt;!-- Unsicher Erstellt eine XSS-Schwachstelle --&gt;</span>
3706
+ &lt;h1&gt;&lt;?= <span class="var">$Benutzer</span>[<span class="st">'Name'</span>] ?&gt;&lt;/h1&gt;
3707
+ <span class="cm">&lt;!-- Sichere Verwendung von ArtiFrame --&gt;</span>
3708
+ &lt;h1&gt;&lt;?= <span class="fn">Anzeige</span>(<span class="var">$Benutzer</span>[<span class="st">'Name'</span>], <span class="st">„Anonymer Benutzer“</span>) ?&gt;&lt;/h1&gt;</code></pre>
3950
3709
  </section>
3951
3710
  <section id="vh-escapeurl">
3952
- <h2>ViewHelpers— <code>escapeUrl()</code> <span class="tag b-view">ViewMethod</span></h2>
3953
- <p>Von Benutzern erhaltene Links (z. B. Profilwebsites) <code>&lt;a href="..."&gt;</code> oder <code>&lt;img src="..."&gt;</code> Es wird beim Drücken nach innen verwendet. <code>javascript:alert(1)</code> Es verhindert die Codeausführung über die Verbindung, indem es gefährliche Payloads wie (Stored XSS) unschädlich macht.</p>
3711
+ <h2>ViewHelpers—<code>escapeUrl()</code> <span class="tag b-view">ViewMethod</span></h2>
3712
+ <p>Von Benutzern erhaltene Links (z. B. Profilwebsites)<code>&lt;a href="..."&gt;</code>oder<code>&lt;img src="..."&gt;</code>Es wird beim Drücken nach innen verwendet.<code>javascript:alert(1)</code>Es verhindert die Codeausführung über die Verbindung, indem es gefährliche Payloads wie (Stored XSS) unschädlich macht.</p>
3954
3713
  <span class="ret">string escapeUrl(string $url)</span>
3955
- <pre><code><span class="cm">&lt;!-- ❌ Güvensiz URL üzerinden JS kodu sızdırılabilir --&gt;</span>
3956
- &lt;a href="&lt;?= <span class="var">$user</span>[<span class="st">'website'</span>] ?&gt;"&gt;Siteyi Ziyaret Et&lt;/a&gt;
3957
-
3958
- <span class="cm">&lt;!-- ArtiFrame Güvenli Kullanımı --&gt;</span>
3959
- &lt;a href="&lt;?= <span class="fn">escapeUrl</span>(<span class="var">$user</span>[<span class="st">'website'</span>]) ?&gt;"&gt;Siteyi Ziyaret Et&lt;/a&gt;</code></pre>
3714
+ <pre><code><span class="cm">&lt;!-- ❌ Unsicher JS-Code kann über die URL durchgesickert sein --&gt;</span>
3715
+ &lt;a href="&lt;?= <span class="var">$Benutzer</span>[<span class="st">'Webseite'</span>] ?&gt;"&gt;Siteyi Ziyaret Et&lt;/a&gt;
3716
+ <span class="cm">&lt;!-- ✅ Sichere Verwendung von ArtiFrame --&gt;</span>
3717
+ &lt;a href="&lt;?= <span class="fn">escapeUrl</span>(<span class="var">$Benutzer</span>[<span class="st">'Webseite'</span>]) ?&gt;"&gt;Siteyi Ziyaret Et&lt;/a&gt;</code></pre>
3960
3718
  </section>
3961
3719
  <section id="vh-csrf">
3962
- <h2>ViewHelpers— <code>csrfField()</code> <span class="tag b-view">ViewMethod</span></h2>
3963
- <p>Fügt HTML-Formularen ein verstecktes Token-Feld gegen CSRF-Angriffe hinzu. <strong>Es ist obligatorisch, es auf jeder Seite zu verwenden, die ein POST-Formular enthält.</strong></p>
3964
- <span class="ret">string csrfField()</span>
3965
- <p>Diese Methode druckt automatisch die folgende HTML-Ausgabe in Ihr Formular: <code>&lt;input type="hidden" name="csrf_token" value="..."&gt;</code>. Wenn Sie die Methode nicht verwenden möchten, können Sie diese versteckte Eingabe als Wert verwenden. <code>display()</code> Sie können es auch manuell hinzufügen, indem Sie es mit umschließen.</p>
3720
+ <h2>ViewHelpers—<code>csrfField()</code> <span class="tag b-view">ViewMethod</span></h2>
3721
+ <p>Fügt HTML-Formularen ein verstecktes Token-Feld gegen CSRF-Angriffe hinzu.<strong>Es ist obligatorisch, es auf jeder Seite zu verwenden, die ein POST-Formular enthält.</strong></p>
3722
+ <span class="ret">Zeichenfolge csrfField()</span>
3723
+ <p>Diese Methode druckt automatisch die folgende HTML-Ausgabe in Ihr Formular:<code>&lt;input type="hidden" name="csrf_token" value="..."&gt;</code>. Wenn Sie die Methode nicht verwenden möchten, können Sie diese versteckte Eingabe als Wert verwenden.<code>display()</code>Sie können es auch manuell hinzufügen, indem Sie es mit umschließen.</p>
3966
3724
  <pre><code><span class="cm">&lt;!-- Frontend (HTML) --&gt;</span>
3967
3725
  &lt;form data-js="kaydet-form"&gt;
3968
- &lt;?= <span class="fn">csrfField</span>() ?&gt; <span class="cm">&lt;!-- Otomatik hidden input üretir --&gt;</span>
3969
-
3970
- <span class="cm">&lt;!-- VEYA Manuel Kullanım:
3726
+ &lt;?= <span class="fn">csrfField</span>() ?&gt; <span class="cm">&lt;!-- Erzeugt automatisch versteckte Eingaben --&gt;</span>
3727
+ <span class="cm">&lt;!-- ODER Manuelle Verwendung:
3971
3728
  &lt;input type="hidden" name="csrf_token" value="&lt;?= display($_SESSION['csrf_token'] ?? '') ?&gt;"&gt;
3972
- --&gt;</span>
3973
-
3729
+ -&gt;</span>
3974
3730
  &lt;input type="text" name="ad" placeholder="Adınız"&gt;
3975
3731
  &lt;button type="submit"&gt;Kaydet&lt;/button&gt;
3976
3732
  &lt;/form&gt;
3977
-
3978
- <span class="cm">// Frontend (JavaScript) - Veriyi Yakalama ve Gönderme</span>
3979
- <span class="fn">document</span>.<span class="fn">querySelector</span>(<span class="st">'[data-js="kaydet-form"]'</span>).<span class="fn">addEventListener</span>(<span class="st">'submit'</span>, (e) =&gt; {
3980
- e.<span class="fn">preventDefault</span>();
3981
- <span class="kw">const</span> <span class="var">formData</span> = <span class="kw">new</span> <span class="fn">FormData</span>(e.target);
3982
-
3983
- <span class="cm">// csrf_token otomatik olarak formData içerisine dahil olur</span>
3984
- <span class="fn">fetch</span>(<span class="st">'/api/kaydet.php'</span>, {
3985
- <span class="kw">method</span>: <span class="st">'POST'</span>,
3986
- <span class="kw">body</span>: <span class="var">formData</span>
3733
+ <span class="cm">// Frontend (JavaScript) – Daten erfassen und senden</span>
3734
+ <span class="fn">dokumentieren</span>.<span class="fn">querySelector</span>(<span class="st">'[data-js="save-form"]'</span>).<span class="fn">addEventListener</span>(<span class="st">'einreichen'</span>, (e) =&gt; {
3735
+ e.<span class="fn">verhindernStandard</span>();
3736
+ <span class="kw">const</span> <span class="var">formData</span> = <span class="kw">neu</span> <span class="fn">FormData</span>(e.target);
3737
+ <span class="cm">// csrf_token wird automatisch in formData eingefügt</span>
3738
+ <span class="fn">bringen</span>(<span class="st">'/api/save.php'</span>, {
3739
+ <span class="kw">Verfahren</span>: <span class="st">'POST'</span>,
3740
+ <span class="kw">Körper</span>: <span class="var">formData</span>
3987
3741
  });
3988
3742
  });</code></pre>
3989
3743
  </section>
3990
3744
  <section id="vh-dates">
3991
- <h2>Hilfsprogramme anzeigen – Datumsfunktionen <span class="tag b-view">ViewMethod</span></h2>
3992
- <p>in der Datenbank <code class="ic">Y-m-d H:i:s</code> formatındaki tarih stringleri veya UNIX timestamp değerlerini işler. Tüm metinsel çıktılar dile göre (<code class="ic">tr</code>, <code class="ic">en</code>, <code class="ic">de</code>, <code class="ic">fr</code>, <code class="ic">es</code>) ist lokalisiert.</p>
3745
+ <h2>Hilfsprogramme anzeigen – Datumsfunktionen<span class="tag b-view">ViewMethod</span></h2>
3746
+ <p>in der Datenbank<code class="ic">Y-m-d H:i:s</code>Verarbeitet Datumszeichenfolgen oder UNIX-Zeitstempelwerte im Format. Alle Textausgaben nach Sprache (<code class="ic">tr</code>, <code class="ic">en</code>, <code class="ic">de</code>, <code class="ic">fr</code>, <code class="ic">es</code>) ist lokalisiert.</p>
3993
3747
  <table class="sig-table">
3994
3748
  <thead><tr><th>Funktion</th><th>Ausgabebeispiel</th><th>Erläuterung</th></tr></thead>
3995
3749
  <tbody>
@@ -4005,66 +3759,63 @@ if ($response['status'] === 'success') {
4005
3759
  </tbody>
4006
3760
  </table>
4007
3761
  <div class="alert a-info" style="margin-top: 0; margin-bottom: 24px;">
4008
- <strong>💡 Parameter verstehen: <code>$format</code> Und <code>$lang</code></strong>
3762
+ <strong>💡 Parameter verstehen:<code>$format</code>Und<code>$lang</code></strong>
4009
3763
  <ul style="margin-top: 10px; margin-bottom: 0;">
4010
- <li style="margin-bottom: 8px;"><strong><code>$format</code> (Format):</strong> Nur <code>formatDate()</code> Es wird mit der Funktion verwendet. Es akzeptiert Standard-PHP-Datumsbuchstaben. (Zum Beispiel: <code>'d/m/Y'</code> 24.07.2026, bzw <code>'H:i'</code> 15:30). Damit können Sie Ihr eigenes Datumsmuster erstellen, wenn andere vorgefertigte Funktionen (Tag, Jahr usw.) nicht ausreichen.</li>
4011
- <li style="margin-bottom: 0;"><strong><code>$lang</code> (Sprache):</strong> Es wird in Funktionen verwendet, deren Ausgabe Text (Monatsname, Wort „vorher“) enthält. Wenn Sie diesen Parameter leer lassen, wird das System <strong>standardmäßig <code>'tr'</code> (Türkisch)</strong> es funktioniert. Wenn Sie ein mehrsprachiges Projekt durchführen, geben Sie den Sprachcode ein (<code>tr, en, de, fr, es</code>) reicht zur Eingabe aus. (Ex: <code>timeAgo($tarih, 'en')</code> vor 5 Minuten)</li>
3764
+ <li style="margin-bottom: 8px;"><strong><code>$format</code>(Format):</strong>Nur<code>formatDate()</code>Es wird mit der Funktion verwendet. Es akzeptiert Standard-PHP-Datumsbuchstaben. (Zum Beispiel:<code>'d/m/Y'</code>➔ 24.07.2026, bzw<code>'H:i'</code>➔ 15:30). Damit können Sie Ihr eigenes Datumsmuster erstellen, wenn andere vorgefertigte Funktionen (Tag, Jahr usw.) nicht ausreichen.</li>
3765
+ <li style="margin-bottom: 0;"><strong><code>$lang</code>(Sprache):</strong>Es wird in Funktionen verwendet, deren Ausgabe Text (Monatsname, Wort „vorher“) enthält. Wenn Sie diesen Parameter leer lassen, wird das System<strong>standardmäßig<code>'tr'</code>(Türkisch)</strong>es funktioniert. Wenn Sie ein mehrsprachiges Projekt durchführen, geben Sie den Sprachcode ein (<code>tr, en, de, fr, es</code>) reicht zur Eingabe aus. (Ex:<code>timeAgo($tarih, 'en')</code>➔ vor 5 Minuten)</li>
4012
3766
  </ul>
4013
3767
  </div>
4014
- <pre><code><span class="cm">&lt;!-- time() fonksiyonu ile alınmış bir UNIX timestamp olduğunu varsayalım --&gt;</span>
4015
- <span class="kw">&lt;?php</span> <span class="var">$tarih</span> = <span class="fn">time</span>(); <span class="kw">?&gt;</span>
4016
-
4017
- <span class="cm">&lt;!-- Dile göre tam tarih --&gt;</span>
4018
- &lt;span&gt;&lt;?= <span class="fn">fulldateName</span>(<span class="var">$tarih</span>, <span class="st">'tr'</span>) ?&gt;&lt;/span&gt;
4019
- <span class="cm">&lt;!-- Çıktı: 24 Temmuz 2026 --&gt;</span>
4020
-
4021
- <span class="cm">&lt;!-- Sosyal medya tarzı zaman gösterimi --&gt;</span>
4022
- &lt;span&gt;&lt;?= <span class="fn">timeAgo</span>(<span class="var">$tarih</span>, <span class="st">'en'</span>) ?&gt;&lt;/span&gt;
4023
- <span class="cm">&lt;!-- Çıktı: 5 minutes ago --&gt;</span>
4024
-
4025
- &lt;span&gt;&lt;?= <span class="fn">timeAgo</span>(<span class="var">$tarih</span>, <span class="st">'de'</span>) ?&gt;&lt;/span&gt;
4026
- <span class="cm">&lt;!-- Çıktı: vor 5 Minuten --&gt;</span></code></pre>
3768
+ <pre><code><span class="cm">&lt;!-- Angenommen, es handelt sich um einen UNIX-Zeitstempel, der mit der Funktion time() abgerufen wurde --&gt;</span>
3769
+ <span class="kw">&lt;?php</span> <span class="var">$Datum</span> = <span class="fn">Zeit</span>(); <span class="kw">?&gt;</span>
3770
+ <span class="cm">&lt;!-- Genaues Datum nach Sprache --&gt;</span>
3771
+ &lt;span&gt;&lt;?= <span class="fn">vollständiger Datumsname</span>(<span class="var">$Datum</span>, <span class="st">'tr'</span>) ?&gt;&lt;/span&gt;
3772
+ <span class="cm">&lt;!-- Veröffentlicht: 24. Juli 2026 --&gt;</span>
3773
+ <span class="cm">&lt;!-- Zeitanzeige im Social-Media-Stil --&gt;</span>
3774
+ &lt;span&gt;&lt;?= <span class="fn">timeAgo</span>(<span class="var">$Datum</span>, <span class="st">'am meisten'</span>) ?&gt;&lt;/span&gt;
3775
+ <span class="cm">&lt;!-- Veröffentlicht: vor 5 Minuten --&gt;</span>
3776
+ &lt;span&gt;&lt;?= <span class="fn">timeAgo</span>(<span class="var">$Datum</span>, <span class="st">'Auch'</span>) ?&gt;&lt;/span&gt;
3777
+ <span class="cm">&lt;!-- Ausgabe: vor 5 Minuten --&gt;</span></code></pre>
4027
3778
  </section>
4028
3779
  <section id="vh-truncate">
4029
- <h2>ViewHelpers— <code>truncate()</code> <span class="tag b-view">ViewMethod</span></h2>
3780
+ <h2>ViewHelpers—<code>truncate()</code> <span class="tag b-view">ViewMethod</span></h2>
4030
3781
  <span class="ret">string truncate(string $text, int $length = 100, string $append = '...')</span>
4031
3782
  <p>Es kürzt lange Texte auf die gewünschte Zeichenbegrenzung, ohne das letzte Wort abzuschneiden, und fügt am Ende das angegebene Suffix hinzu.</p>
4032
- <pre><code>&lt;p&gt;&lt;?= <span class="fn">truncate</span>(<span class="var">$post</span>[<span class="st">'icerik'</span>], <span class="nu">160</span>, <span class="st">'...'</span>) ?&gt;&lt;/p&gt;</code></pre>
3783
+ <pre><code>&lt;p&gt;&lt;?= <span class="fn">kürzen</span>(<span class="var">$post</span>[<span class="st">'Inhalt'</span>], <span class="nu">160</span>, <span class="st">'...'</span>) ?&gt;&lt;/p&gt;</code></pre>
4033
3784
  </section>
4034
3785
  <section id="vh-activeclass">
4035
- <h2>ViewHelpers— <code>activeClass()</code> <span class="tag b-view">ViewMethod</span></h2>
3786
+ <h2>ViewHelpers—<code>activeClass()</code> <span class="tag b-view">ViewMethod</span></h2>
4036
3787
  <span class="ret">string activeClass(string $currentPath, string $targetPath, string $className = 'active')</span>
4037
3788
  <p>Wenn die aktuelle Seite und der aktivierte Menülink übereinstimmen, wird die CSS-Klasse zurückgegeben. Perfekt für die Navigationsleiste.</p>
4038
- <pre><code>&lt;li class="&lt;?= <span class="fn">activeClass</span>(<span class="var">$current_url</span>, <span class="st">'/iletisim'</span>, <span class="st">'current-page'</span>) ?&gt;"&gt;</code></pre>
3789
+ <pre><code>&lt;li class="&lt;?= <span class="fn">aktiveKlasse</span>(<span class="var">$aktuelle_URL</span>, <span class="st">'/Kommunikation'</span>, <span class="st">'aktuelle-seite'</span>) ?&gt;"&gt;</code></pre>
4039
3790
  </section>
4040
3791
  <section id="vh-formatsize">
4041
- <h2>ViewHelpers— <code>formatSize()</code> <span class="tag b-view">ViewMethod</span></h2>
3792
+ <h2>ViewHelpers—<code>formatSize()</code> <span class="tag b-view">ViewMethod</span></h2>
4042
3793
  <span class="ret">string formatSize(int $bytes)</span>
4043
3794
  <p>Konvertiert die angegebene Dateigröße in Bytes mithilfe einer logarithmischen Berechnung in die Einheiten B, KB, MB, GB.</p>
4044
3795
  <pre><code>&lt;span&gt;&lt;?= <span class="fn">formatSize</span>(<span class="nu">10485760</span>) ?&gt;&lt;/span&gt; <span class="cm">&lt;!-- 10,00 MB --&gt;</span></code></pre>
4045
3796
  </section>
4046
3797
  <section id="vh-maskemail">
4047
- <h2>ViewHelpers— <code>maskEmail()</code> <span class="tag b-view">ViewMethod</span></h2>
3798
+ <h2>ViewHelpers—<code>maskEmail()</code> <span class="tag b-view">ViewMethod</span></h2>
4048
3799
  <span class="ret">string maskEmail(?string $email)</span>
4049
3800
  <p>Maskiert E-Mail-Adressen gemäß KVKK/DSGVO-Konformität. Sterne vom ersten Buchstaben bis zum @-Zeichen.</p>
4050
3801
  <pre><code>&lt;td&gt;&lt;?= <span class="fn">maskEmail</span>(<span class="st">'utku@artilingo.com'</span>) ?&gt;&lt;/td&gt; <span class="cm">&lt;!-- u***@artilingo.com --&gt;</span></code></pre>
4051
3802
  </section>
4052
3803
  <section id="vh-maskphone">
4053
- <h2>ViewHelpers— <code>maskPhone()</code> <span class="tag b-view">ViewMethod</span></h2>
3804
+ <h2>ViewHelpers—<code>maskPhone()</code> <span class="tag b-view">ViewMethod</span></h2>
4054
3805
  <span class="ret">string maskPhone(string $phone)</span>
4055
3806
  <p>Erweiterte Telefonnummernmaskierung. Es verhindert Datenschutzverletzungen, indem kritische Ziffern vollständig ausgeblendet werden.</p>
4056
3807
  <pre><code>&lt;td&gt;&lt;?= <span class="fn">maskPhone</span>(<span class="st">'05551234567'</span>) ?&gt;&lt;/td&gt; <span class="cm">&lt;!-- 0555 *** ** 67 --&gt;</span></code></pre>
4057
3808
  </section>
4058
3809
  <section id="vh-slugify">
4059
- <h2>ViewHelpers— <code>slugify()</code> <span class="tag b-view">ViewMethod</span></h2>
3810
+ <h2>ViewHelpers—<code>slugify()</code> <span class="tag b-view">ViewMethod</span></h2>
4060
3811
  <span class="ret">string slugify(string ...$texts)</span>
4061
3812
  <p>URL-freundlicher SEO-Linkbuilder. Es gibt keine Parameterbegrenzung (Variadic). Sie können die Ausgabe direkt in href schreiben.</p>
4062
- <pre><code>&lt;a href="/yazi/&lt;?= <span class="fn">slugify</span>(<span class="var">$kat</span>, <span class="var">$baslik</span>) ?&gt;"&gt;Oku&lt;/a&gt; <span class="cm">&lt;!-- /yazi/teknoloji/yapay-zeka --&gt;</span></code></pre>
3813
+ <pre><code>&lt;a href="/yazi/&lt;?= <span class="fn">träge machen</span>(<span class="var">$kat</span>, <span class="var">$title</span>) ?&gt;"&gt;Oku&lt;/a&gt; <span class="cm">&lt;!-- /text/technology/artificial-intelligence --&gt;</span></code></pre>
4063
3814
  </section>
4064
3815
  <section id="vh-money">
4065
- <h2>ViewHelpers— <code>money()</code> <span class="tag b-view">ViewMethod</span></h2>
4066
- <p>Formatiert den Betrag mit dem Währungssymbol. Der Währungscode (ISO) bestimmt automatisch die Symbolplatzierung. Standardwährung <code class="ic">usd</code>Ist.</p>
4067
- <span class="ret">string money(float $amount, string $currency = 'usd')</span>
3816
+ <h2>ViewHelpers—<code>money()</code> <span class="tag b-view">ViewMethod</span></h2>
3817
+ <p>Formatiert den Betrag mit dem Währungssymbol. Der Währungscode (ISO) bestimmt automatisch die Symbolplatzierung. Standardwährung<code class="ic">usd</code>Ist.</p>
3818
+ <span class="ret">string geld(float $amount, string $currency = 'usd')</span>
4068
3819
  <table class="sig-table">
4069
3820
  <thead><tr><th>Code</th><th>Ausgabe</th><th>Währung</th></tr></thead>
4070
3821
  <tbody>
@@ -4072,7 +3823,7 @@ if ($response['status'] === 'success') {
4072
3823
  <tr><td>Euro</td><td>1.250,00 €</td><td>Euro</td></tr>
4073
3824
  <tr><td>versuche/tl</td><td>1.250,00 ₺</td><td>Türkische Lira</td></tr>
4074
3825
  <tr><td>GBP</td><td>1.250,00 £</td><td>Britisches Pfund</td></tr>
4075
- <tr><td>jpy</td><td>1.250,00 ¥</td><td>Japanischer Yen</td></tr>
3826
+ <tr><td>jpy</td><td1.250,00</td><td>Japanischer Yen</td></tr>
4076
3827
  <tr><td>inr</td><td>₹1.250,00</td><td>Indische Rupie</td></tr>
4077
3828
  <tr><td>reiben</td><td>₽ 1.250,00</td><td>Russischer Rubel</td></tr>
4078
3829
  <tr><td>krw</td><td>₩1.250,00</td><td>Südkoreanischer Won</td></tr>
@@ -4080,449 +3831,397 @@ if ($response['status'] === 'success') {
4080
3831
  <tr><td>aed</td><td>1.250,00 د.إ</td><td>VAE-Dirham</td></tr>
4081
3832
  </tbody>
4082
3833
  </table>
4083
- <pre><code>&lt;span&gt;&lt;?= <span class="fn">money</span>(<span class="var">$urun</span>[<span class="st">'fiyat'</span>], <span class="st">'try'</span>) ?&gt;&lt;/span&gt;
4084
- <span class="cm">&lt;!-- Çıktı: 1.250,00 --&gt;</span>
4085
-
4086
- &lt;span&gt;&lt;?= <span class="fn">money</span>(<span class="var">$urun</span>[<span class="st">'fiyat'</span>], <span class="st">'usd'</span>) ?&gt;&lt;/span&gt;
4087
- <span class="cm">&lt;!-- Çıktı: $1.250,00 --&gt;</span></code></pre>
4088
- </section>
4089
-
4090
- <section id="vh-uuid">
4091
- <h2>View Helpers - <code>uuid()</code> <span class="tag b-view">ViewMethod</span></h2>
4092
- <p>Konvertiert eine binäre 16-Byte-UUID aus der Datenbank in ein 36-Zeichen-Format und druckt sie mit XSS-Schutz auf den Bildschirm.</p>
4093
- <pre><code><span class="cm">&lt;!-- Ausgabe: 0190ed84-3f12-7a91-8bc4-91823741abcd --&gt;</span>
4094
- &lt;div&gt;<span class="kw">&lt;?=</span> <span class="fn">uuid</span>(<span class="var">$pull</span>[<span class="st">'id'</span>]) <span class="kw">?&gt;</span>&lt;/div&gt;</code></pre>
4095
- </section>
4096
-
4097
- <!-- ====== SYSTEM HELPERS ====== -->
3834
+ <pre><code>&lt;span&gt;&lt;?= <span class="fn">Geld</span>(<span class="var">$Produkt</span>[<span class="st">'Preis'</span>], <span class="st">'versuchen'</span>) ?&gt;&lt;/span&gt;
3835
+ <span class="cm">&lt;!-- Ausgabe: 1.250,00 --&gt;</span>
3836
+ &lt;span&gt;&lt;?= <span class="fn">Geld</span>(<span class="var">$Produkt</span>[<span class="st">'Preis'</span>], <span class="st">'usd'</span>) ?&gt;&lt;/span&gt;
3837
+ <span class="cm">&lt;!-- Ausgabe: 1.250,00 $ --&gt;</span></code></pre>
3838
+ </section>
3839
+ <section id="vh-uuid">
3840
+ <h2>Helfer anzeigen -<code>uuid()</code> <span class="tag b-view">ViewMethod</span></h2>
3841
+ <p>Es konvertiert die 16-Byte-Binär-UUID-Daten aus der Datenbank in ein 36-Zeichen-Format und druckt sie mit XSS-Schutz auf dem Bildschirm aus.</p>
3842
+ <pre><code><span class="cm">&lt;!-- Ausgabe: 0190ed84-3f12-7a91-8bc4-91823741abcd --&gt;</span>
3843
+ &lt;div&gt;<span class="kw">&lt;?=</span> <span class="fn">uuid</span>(<span class="var">$ziehen</span>[<span class="st">'AUSWEIS'</span>]) <span class="kw">?&gt;</span>&lt;/div&gt;</code></pre>
3844
+ </section>
3845
+ ====== SYSTEMHILFE ======
4098
3846
  <section id="sh-apiresponse">
4099
- <h2>Systemhelfer— <code>apiResponse()</code> <span class="tag b-api">SystemMethod</span></h2>
4100
- <p>Diese Funktion wird zwischen Frontend (JS/Mobile) und Backend (PHP) Ihrer Anwendung verwendet. <strong>Es ist die Konstitution der Kommunikation.</strong> Schlüssel in den als Antwort zurückgegebenen JSON-Daten <code>status</code>, <code>message</code> Und <code>data</code> Aspekt <strong>ist absolut festgelegt (muss auf Englisch sein)</strong>.</p>
4101
- <span class="ret">void apiResponse(string $status, string $message, array $data = [], \Throwable $exception = null)</span>
4102
- <p style="margin-top: 15px;"><strong>Statuscode (HTTP-Code):</strong> Auf der PHP-Seite der erste Parameter <code>'success'</code> Bei Eingabe wird automatisch HTTP 200 zurückgegeben, für alles andere (z. B. „error“, „ok“) wird 400 Bad Request zurückgegeben.</p>
4103
- <p><strong>Empfindlichkeit der Live-/Testumgebung (APP_ENV):</strong> Wenn der vierte Parameter ist <code>Exception</code> Wenn Sie es eingeben und sich Ihr System im Entwicklungsmodus (APP_ENV = 1) befindet, wird die von Ihnen geschriebene Nachricht gelöscht und der SQL-Fehler/die Zeilennummer unverändert auf dem Bildschirm ausgegeben. Im Live-Modus (APP_ENV = 0) werden Fehler ausgeblendet und nur die klare Nachricht angezeigt, die Sie eingegeben haben.</p>
3847
+ <h2>Systemhelfer—<code>apiResponse()</code> <span class="tag b-api">SystemMethode</span></h2>
3848
+ <p>Mit dieser Funktion können Sie das Frontend (JS/Mobile) Ihrer Anwendung mit dem Backend (PHP) verbinden.<strong>Es ist die Konstitution der Kommunikation.</strong>Schlüssel in den als Antwort zurückgegebenen JSON-Daten<code>status</code>, <code>message</code>Und<code>data</code>Aspekt<strong>ist absolut festgelegt (muss auf Englisch sein)</strong>.</p>
3849
+ <span class="ret">void apiResponse(string $status, string $message, array $data = [], \Throwable $Exception = null)</span>
3850
+ <p style="margin-top: 15px;"><strong>Statuscode (HTTP-Code):</strong>Auf der PHP-Seite der erste Parameter<code>'success'</code>Bei Eingabe wird automatisch HTTP 200 zurückgegeben, für alles andere (z. B. „error“, „ok“) wird 400 Bad Request zurückgegeben.</p>
3851
+ <p><strong>Empfindlichkeit der Live-/Testumgebung (APP_ENV):</strong>Wenn der vierte Parameter ist<code>Exception</code>Wenn Sie es eingeben und sich Ihr System im Entwicklungsmodus (APP_ENV = 1) befindet, wird die von Ihnen geschriebene Nachricht gelöscht und der SQL-Fehler/die Zeilennummer unverändert auf dem Bildschirm angezeigt. Im Live-Modus (APP_ENV = 0) werden Fehler ausgeblendet und nur die klare Nachricht angezeigt, die Sie eingegeben haben.</p>
4104
3852
  <h3>PHP (Backend)-Übermittlung</h3>
4105
- <pre><code><span class="cm">// 1. Standart Gönderim</span>
4106
- <span class="fn">apiResponse</span>(<span class="st">'success'</span>, <span class="st">'İşlem başarıyla tamamlandı.'</span>, [<span class="st">'id'</span> =&gt; <span class="nu">1453</span>]);
4107
-
4108
- <span class="cm">// 2. Hata Gönderimi (Exception ile)</span>
4109
- <span class="kw">try</span> {
4110
- <span class="cm">// Veritabanı sorguları...</span>
4111
- } <span class="kw">catch</span> (\Exception <span class="var">$e</span>) {
4112
- <span class="fn">apiResponse</span>(<span class="st">'error'</span>, <span class="st">'Bir sorun oluştu.'</span>, [], <span class="var">$e</span>);
3853
+ <pre><code><span class="cm">// 1. Standardversand</span>
3854
+ <span class="fn">apiResponse</span>(<span class="st">'Erfolg'</span>, <span class="st">„Der Vorgang wurde erfolgreich abgeschlossen.“</span>, [<span class="st">'AUSWEIS'</span> =&gt; <span class="nu">1453</span>]);
3855
+ <span class="cm">// 2. Fehlerübermittlung (mit Ausnahme)</span>
3856
+ <span class="kw">versuchen</span> {
3857
+ <span class="cm">// Datenbankabfragen...</span>
3858
+ } <span class="kw">fangen</span> (\Exception <span class="var">$e</span>) {
3859
+ <span class="fn">apiResponse</span>(<span class="st">'Fehler'</span>, <span class="st">„Etwas ist schiefgelaufen.“</span>, [], <span class="var">$e</span>);
4113
3860
  }</code></pre>
4114
3861
  <h3>JavaScript (Frontend)-Erfassung</h3>
4115
- <pre><code><span class="fn">fetch</span>(<span class="st">'/api/endpoint'</span>, { method: <span class="st">'POST'</span> })
3862
+ <pre><code><span class="fn">bringen</span>(<span class="st">'/api/endpoint'</span>, { method: <span class="st">'POST'</span> })
4116
3863
  .then(res =&gt; res.json())
4117
3864
  .then(response =&gt; {
4118
- <span class="cm">// DİKKAT: response.durum veya response.mesaj ÇALIŞMAZ!</span>
4119
- <span class="cm">// PHP tarafından ne yollarsanız yollayın anahtarlar daima status, message ve data'dır.</span>
4120
-
4121
- <span class="kw">if</span> (response.status === <span class="st">'success'</span>) { <span class="cm">// PHP'den ne gelirse ('success', 'ok', 'basarili' vs.)</span>
4122
- console.log(<span class="st">"Mesaj:"</span>, response.message);
4123
- console.log(<span class="st">"Gelen Veri:"</span>, response.data);
4124
- } <span class="kw">else</span> {
4125
- <span class="fn">alert</span>(<span class="st">"Hata oluştu: "</span> + response.message);
3865
+ <span class="cm">// WARNUNG: Response.status oder Response.message funktionieren NICHT!</span>
3866
+ <span class="cm">// Egal was Sie von PHP senden, die Schlüssel sind immer Status, Nachricht und Daten.</span>
3867
+ <span class="kw">Wenn</span> (response.status === <span class="st">'Erfolg'</span>) { <span class="cm">// Was auch immer von PHP kommt („success“, „ok“, „successful“ usw.)</span>
3868
+ console.log(<span class="st">"Nachricht:"</span>, response.message);
3869
+ console.log(<span class="st">„Eingehende Daten:“</span>, response.data);
3870
+ } <span class="kw">anders</span> {
3871
+ <span class="fn">Alarm</span>(<span class="st">„Fehler aufgetreten:“</span> + response.message);
4126
3872
  }
4127
3873
  });</code></pre>
4128
3874
  </section>
4129
3875
  <section id="sh-json">
4130
- <h2>Systemhelfer— <code>jsonResponse()</code> <span class="tag b-api">SystemMethod</span></h2>
4131
- <p>Es legt den JSON-Header fest, gibt den HTTP-Statuscode zurück, druckt die Ausgabe sicher mit json_encode und beendet dann das Skript. <strong>Alle API-Antworten müssen über diese Funktion gegeben werden.</strong></p>
3876
+ <h2>Systemhelfer—<code>jsonResponse()</code> <span class="tag b-api">SystemMethode</span></h2>
3877
+ <p>Es legt den JSON-Header fest, gibt den HTTP-Statuscode zurück, druckt die Ausgabe sicher mit json_encode und beendet dann das Skript.<strong>Alle API-Antworten müssen über diese Funktion gegeben werden.</strong></p>
4132
3878
  <span class="ret">void jsonResponse(array $data, int $statusCode = 200)</span>
4133
- <pre><code><span class="cm">// Başarılı yanıt</span>
4134
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'success'</span>, <span class="st">'data'</span> =&gt; <span class="var">$kullanici</span>], <span class="nu">200</span>);
4135
-
4136
- <span class="cm">// Hata yanıtı</span>
4137
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'error'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Yetkisiz erişim.'</span>], <span class="nu">401</span>);</code></pre>
3879
+ <pre><code><span class="cm">// Erfolgreiche Antwort</span>
3880
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Erfolg'</span>, <span class="st">'Daten'</span> =&gt; <span class="var">$Benutzer</span>], <span class="nu">200</span>);
3881
+ <span class="cm">// Fehlerantwort</span>
3882
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Fehler'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Unberechtigter Zugriff.“</span>], <span class="nu">401</span>);</code></pre>
4138
3883
  </section>
4139
-
4140
3884
  <section id="sh-dd">
4141
- <h2>Systemhelfer— <code>dd()</code> <span class="tag b-api">SystemMethod</span></h2>
4142
- <p>Dump &amp; Die. Während der Entwicklungsphase wurden die Variablen im dunklen Modus, lesbar und stilvoll auf dem Bildschirm angezeigt. <code>&lt;pre&gt;</code> Tag und stoppt die Ausführung des Codes in dieser Zeile (Exit). Es können unbegrenzte Parameter angenommen werden (Variadic).</p>
3885
+ <h2>Systemhelfer—<code>dd()</code> <span class="tag b-api">SystemMethode</span></h2>
3886
+ <p>Dump &amp; Die. Während der Entwicklungsphase wurden die Variablen im dunklen Modus, lesbar und stilvoll auf dem Bildschirm angezeigt.<code>&lt;pre&gt;</code>Tag und stoppt die Ausführung des Codes in dieser Zeile (exit). Es können unbegrenzte Parameter angenommen werden (Variadic).</p>
4143
3887
  <span class="ret">void dd(mixed ...$vars)</span>
4144
- <pre><code><span class="fn">dd</span>(<span class="var">$_POST</span>, <span class="var">$kullanici_id</span>);
4145
- <span class="cm">// Değerleri ekrana basar ve sistemi durdurur.</span></code></pre>
3888
+ <pre><code><span class="fn">dd</span>(<span class="var">$_POST</span>, <span class="var">$user_id</span>);
3889
+ <span class="cm">// Gibt die Werte auf dem Bildschirm aus und stoppt das System.</span></code></pre>
4146
3890
  </section>
4147
- <!-- ====== ID GENERATION & UTILITIES ====== -->
3891
+ ====== ID-GENERIERUNG &amp; DIENSTLEISTUNGEN ======
4148
3892
  <section id="id-generation-utilities">
4149
- </section>
4150
-
4151
-
3893
+ </section>
4152
3894
  <section id="sh-redirect">
4153
- <h2>Systemhelfer— <code>redirect()</code> <span class="tag b-api">SystemMethod</span></h2>
4154
- <span class="ret">void redirect(string $url)</span>
4155
- <p>zur gewünschten Seite <code>header("Location: ...")</code> Es leitet sofort um und funktioniert nicht mehr mit (<code>exit</code>).</p>
4156
- <pre><code><span class="kw">if</span> (!<span class="var">$isLoggedIn</span>) {
4157
- <span class="fn">redirect</span>(<span class="st">'/login'</span>);
3895
+ <h2>Systemhelfer—<code>redirect()</code> <span class="tag b-api">SystemMethode</span></h2>
3896
+ <span class="ret">Leere Weiterleitung (Zeichenfolge $url)</span>
3897
+ <p>zur gewünschten Seite<code>header("Location: ...")</code>Es leitet sofort um und funktioniert nicht mehr mit (<code>exit</code>).</p>
3898
+ <pre><code><span class="kw">Wenn</span> (!<span class="var">$isLoggedIn</span>) {
3899
+ <span class="fn">umleiten</span>(<span class="st">'/Login'</span>);
4158
3900
  }</code></pre>
4159
- </section>
4160
-
4161
- <section id="sh-generatecsrf">
4162
- <h2>Systemhelfer— <code>generateCsrf()</code> <span class="tag b-api">SystemMethod</span></h2>
4163
- <p>Es generiert ein brandneues sitzungsbasiertes sicheres CSRF-Token mit einer Länge von 32 Bytes. Zum Hinzufügen als versteckte Eingabe zu Formularen <code>csrfField()</code> Es wird empfohlen, (View Helper) zu verwenden.</p>
4164
- <span class="ret">string generateCsrf()</span>
4165
- <pre><code><span class="kw">if</span> (<span class="var">$_SESSION</span>[<span class="st">'kullanici'</span>]) {
4166
- <span class="fn">generateCsrf</span>(); <span class="cm">// Oturum başlatıldığında CSRF üretilir</span>
3901
+ </section>
3902
+ <section id="sh-generatecsrf">
3903
+ <h2>Systemhelfer—<code>generateCsrf()</code> <span class="tag b-api">SystemMethode</span></h2>
3904
+ <p>Es generiert ein brandneues sitzungsbasiertes sicheres CSRF-Token mit einer Länge von 32 Bytes. Zum Hinzufügen als versteckte Eingabe zu Formularen<code>csrfField()</code>Es wird empfohlen, (View Helper) zu verwenden.</p>
3905
+ <span class="ret">Zeichenfolge generierenCsrf()</span>
3906
+ <pre><code><span class="kw">Wenn</span> (<span class="var">$_SESSION</span>[<span class="st">'Benutzer'</span>]) {
3907
+ <span class="fn">generierenCsrf</span>(); <span class="cm">// CSRF wird generiert, wenn die Sitzung gestartet wird</span>
4167
3908
  }</code></pre>
4168
3909
  </section>
4169
3910
  <section id="sh-csrf">
4170
- <h2>Systemhelfer— <code>verifyCsrf()</code> <span class="tag b-api">SystemMethod</span></h2>
4171
- <p>Überprüft, ob die eingehende POST-Anfrage von einem legitimen Formular stammt. in das Formular ein <code class="ic">csrfField()</code> Gibt „false“ zurück, wenn es nicht hinzugefügt wurde oder das Token ungültig ist.</p>
3911
+ <h2>Systemhelfer—<code>verifyCsrf()</code> <span class="tag b-api">SystemMethode</span></h2>
3912
+ <p>Überprüft, ob die eingehende POST-Anfrage von einem legitimen Formular stammt. in das Formular ein<code class="ic">csrfField()</code>Gibt „false“ zurück, wenn es nicht hinzugefügt wurde oder das Token ungültig ist.</p>
4172
3913
  <span class="ret">bool verifyCsrf(string $token)</span>
4173
- <pre><code><span class="kw">if</span> (!<span class="fn">verifyCsrf</span>(<span class="var">$_POST</span>[<span class="st">'csrf_token'</span>] ?? <span class="st">''</span>)) {
4174
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'error'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Geçersiz CSRF token.'</span>], <span class="nu">403</span>);
3914
+ <pre><code><span class="kw">Wenn</span> (!<span class="fn">überprüfenCsrf</span>(<span class="var">$_POST</span>[<span class="st">'csrf_token'</span>] ?? <span class="st">''</span>)) {
3915
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Fehler'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Ungültiges CSRF-Token.“</span>], <span class="nu">403</span>);
4175
3916
  }</code></pre>
4176
3917
  </section>
4177
3918
  <section id="sh-sanitizeint">
4178
- <h2>Systemhelfer— <code>sanitizeInt()</code> <span class="tag b-api">SystemMethod</span></h2>
3919
+ <h2>Systemhelfer—<code>sanitizeInt()</code> <span class="tag b-api">SystemMethode</span></h2>
4179
3920
  <span class="ret">int sanitizeInt(mixed $value)</span>
4180
- <p>Es bläst alle darin enthaltenen Buchstaben, Symbole und Kommas weg, <strong>einfach ganzzahlig</strong> verlässt die Zahlen. Wird für ID oder Grenzwerte (Datenbank-Int-Werte) verwendet.</p>
4181
- <pre><code><span class="var">$id</span> = <span class="fn">sanitizeInt</span>(<span class="var">$_GET</span>[<span class="st">'id'</span>] ?? <span class="nu">0</span>);</code></pre>
3921
+ <p>Es bläst alle darin enthaltenen Buchstaben, Symbole und Kommas weg,<strong>einfach ganzzahlig</strong>verlässt die Zahlen. Es wird für ID oder Grenzwerte (Datenbank-Int-Werte) verwendet.</p>
3922
+ <pre><code><span class="var">$id</span> = <span class="fn">sanitizeInt</span>(<span class="var">$_GET</span>[<span class="st">'AUSWEIS'</span>] ?? <span class="nu">0</span>);</code></pre>
4182
3923
  </section>
4183
3924
  <section id="sh-sanitizefloat">
4184
- <h2>Systemhelfer— <code>sanitizeFloat()</code> <span class="tag b-api">SystemMethod</span></h2>
3925
+ <h2>Systemhelfer—<code>sanitizeFloat()</code> <span class="tag b-api">SystemMethode</span></h2>
4185
3926
  <span class="ret">float sanitizeFloat(mixed $value)</span>
4186
- <p>Löscht alles außer Bruchzahlen (Dezimalzahlen). Es kann sicher für Geldbeträge, Verhältnisberechnungen oder Metriken verwendet werden.</p>
4187
- <pre><code><span class="var">$fiyat</span> = <span class="fn">sanitizeFloat</span>(<span class="var">$_POST</span>[<span class="st">'fiyat'</span>]);</code></pre>
3927
+ <p>Löscht alle Zahlen außer Bruchzahlen (Dezimalzahlen). Es kann sicher für Geldbeträge, Verhältnisberechnungen oder Metriken verwendet werden.</p>
3928
+ <pre><code><span class="var">$Preis</span> = <span class="fn">desinfizierenFloat</span>(<span class="var">$_POST</span>[<span class="st">'Preis'</span>]);</code></pre>
4188
3929
  </section>
4189
3930
  <section id="sh-sanitizestring">
4190
- <h2>Systemhelfer— <code>sanitizeString()</code> <span class="tag b-api">SystemMethod</span></h2>
3931
+ <h2>Systemhelfer—<code>sanitizeString()</code> <span class="tag b-api">SystemMethode</span></h2>
4191
3932
  <span class="ret">string sanitizeString(string $value)</span>
4192
- <p>Um XSS und ähnliche Angriffe zu verhindern, alle <strong>HTML- und PHP-Tags (<code>&lt;script&gt;</code>, <code>&lt;iframe&gt;</code> usw.) zerstört</strong>. Es muss verwendet werden, bevor String in der Datenbank gespeichert wird.</p>
4193
- <pre><code><span class="var">$isim</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'isim'</span>]);</code></pre>
3933
+ <p>Um XSS und ähnliche Angriffe zu verhindern, alle<strong>HTML- und PHP-Tags (<code>&lt;script&gt;</code>, <code>&lt;iframe&gt;</code>usw.) zerstört</strong>. Es muss verwendet werden, bevor String in der Datenbank gespeichert wird.</p>
3934
+ <pre><code><span class="var">$name</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'Name'</span>]);</code></pre>
4194
3935
  </section>
4195
3936
  <section id="sh-sanitizeemail">
4196
- <h2>Systemhelfer— <code>sanitizeEmail()</code> <span class="tag b-api">SystemMethod</span></h2>
3937
+ <h2>Systemhelfer—<code>sanitizeEmail()</code> <span class="tag b-api">SystemMethode</span></h2>
4197
3938
  <span class="ret">string sanitizeEmail(string $email)</span>
4198
- <p>Es filtert alle ungültigen und gefährlichen Zeichen heraus, die nicht dem E-Mail-Format entsprechen. (Achtung: Es wird nur die Richtigkeit des Formats gelöscht. <code>verifyEmail()</code> Sie sollten sich bei ) erkundigen.</p>
4199
- <pre><code><span class="var">$email</span> = <span class="fn">sanitizeEmail</span>(<span class="var">$_POST</span>[<span class="st">'email'</span>] ?? <span class="st">''</span>);</code></pre>
3939
+ <p>Es filtert alle ungültigen und gefährlichen Zeichen heraus, die nicht dem E-Mail-Format entsprechen. (Achtung: Es wird nur die Richtigkeit des Formats gelöscht.<code>verifyEmail()</code>Sie sollten sich bei ) erkundigen.</p>
3940
+ <pre><code><span class="var">$E-Mail</span> = <span class="fn">sanitizeEmail</span>(<span class="var">$_POST</span>[<span class="st">'E-Mail'</span>] ?? <span class="st">''</span>);</code></pre>
4200
3941
  </section>
4201
3942
  <section id="sh-ispost">
4202
- <h2>Systemhelfer— <code>isPost()</code> <span class="tag b-api">SystemMethod</span></h2>
3943
+ <h2>Systemhelfer—<code>isPost()</code> <span class="tag b-api">SystemMethode</span></h2>
4203
3944
  <span class="ret">bool isPost()</span>
4204
3945
  <p>Es prüft, ob die eingehende Anfrage (HTTP-Request) mit der POST-Methode erfolgt. Es wird verwendet, um den direkten Zugriff auf die Seite zu verhindern, insbesondere bei Formularübermittlungen.</p>
4205
- <pre><code><span class="kw">if</span> (<span class="fn">isPost</span>()) {
4206
- <span class="cm">// İstek POST ise çalışır (Form gönderimi)</span>
3946
+ <pre><code><span class="kw">Wenn</span> (<span class="fn">isPost</span>()) {
3947
+ <span class="cm">// Funktioniert, wenn die Anfrage POST ist (Formularübermittlung)</span>
4207
3948
  }</code></pre>
4208
3949
  </section>
4209
3950
  <section id="sh-isget">
4210
- <h2>Systemhelfer— <code>isGet()</code> <span class="tag b-api">SystemMethod</span></h2>
3951
+ <h2>Systemhelfer—<code>isGet()</code> <span class="tag b-api">SystemMethode</span></h2>
4211
3952
  <span class="ret">bool isGet()</span>
4212
3953
  <p>Es prüft, ob die eingehende Anfrage mit der GET-Methode erfolgt. Es wird nur zu Kontrollzwecken beim Auslesen von Parametern oder beim Anzeigen von Seiten über URL verwendet.</p>
4213
- <pre><code><span class="kw">if</span> (<span class="fn">isGet</span>()) {
4214
- <span class="cm">// Sayfa normal olarak ziyaret edildiyse çalışır</span>
3954
+ <pre><code><span class="kw">Wenn</span> (<span class="fn">isGet</span>()) {
3955
+ <span class="cm">// Funktioniert, wenn die Seite normal besucht wird</span>
4215
3956
  }</code></pre>
4216
3957
  </section>
4217
3958
  <section id="sh-isput">
4218
- <h2>Systemhelfer— <code>isPut()</code> <span class="tag b-api">SystemMethod</span></h2>
3959
+ <h2>Systemhelfer—<code>isPut()</code> <span class="tag b-api">SystemMethode</span></h2>
4219
3960
  <span class="ret">bool isPut()</span>
4220
3961
  <p>Es überprüft, ob die eingehende Anfrage mit der PUT-Methode erfolgt. Es wird im Allgemeinen für Datenaktualisierungsvorgänge in REST-API-Architekturen bevorzugt.</p>
4221
- <pre><code><span class="kw">if</span> (<span class="fn">isPut</span>()) {
4222
- <span class="cm">// API üzerinden bir kaynağı güncelleme isteği</span>
3962
+ <pre><code><span class="kw">Wenn</span> (<span class="fn">isPut</span>()) {
3963
+ <span class="cm">//Anfrage zum Aktualisieren einer Ressource über die API</span>
4223
3964
  }</code></pre>
4224
3965
  </section>
4225
3966
  <section id="sh-isdelete">
4226
- <h2>Systemhelfer— <code>isDelete()</code> <span class="tag b-api">SystemMethod</span></h2>
3967
+ <h2>Systemhelfer—<code>isDelete()</code> <span class="tag b-api">SystemMethode</span></h2>
4227
3968
  <span class="ret">bool isDelete()</span>
4228
3969
  <p>Es überprüft, ob die eingehende Anfrage mit der DELETE-Methode gestellt wurde. Es wird zum Schutz von Löschrouten in REST-APIs verwendet.</p>
4229
- <pre><code><span class="kw">if</span> (<span class="fn">isDelete</span>()) {
4230
- <span class="cm">// API üzerinden bir kaynağı silme isteği</span>
3970
+ <pre><code><span class="kw">Wenn</span> (<span class="fn">isDelete</span>()) {
3971
+ <span class="cm">// Anforderung zum Löschen einer Ressource über die API</span>
4231
3972
  }</code></pre>
4232
3973
  </section>
4233
3974
  <section id="sh-isajax">
4234
- <h2>Systemhelfer— <code>isAjax()</code> <span class="tag b-api">SystemMethod</span></h2>
3975
+ <h2>Systemhelfer—<code>isAjax()</code> <span class="tag b-api">SystemMethode</span></h2>
4235
3976
  <span class="ret">bool isAjax()</span>
4236
- <p>Ihre eingehende Anfrage <code>XMLHttpRequest</code> Überprüft, ob dies über (AJAX) oder die moderne Fetch-API () erfolgt.<code>HTTP_X_REQUESTED_WITH</code> schaut sich den Header-Wert an).</p>
4237
- <pre><code><span class="kw">if</span> (!<span class="fn">isAjax</span>()) {
4238
- <span class="fn">redirect</span>(<span class="st">'/hata'</span>); <span class="cm">// Sadece AJAX'a izin ver</span>
3977
+ <p>Ihre eingehende Anfrage<code>XMLHttpRequest</code>Überprüft, ob dies über (AJAX) oder die moderne Fetch-API (<code>HTTP_X_REQUESTED_WITH</code>schaut sich den Header-Wert an).</p>
3978
+ <pre><code><span class="kw">Wenn</span> (!<span class="fn">istAjax</span>()) {
3979
+ <span class="fn">umleiten</span>(<span class="st">'/Fehler'</span>); <span class="cm">// Nur AJAX zulassen</span>
4239
3980
  }</code></pre>
4240
3981
  </section>
4241
3982
  <section id="sh-getclientip">
4242
- <h2>Systemhelfer— <code>getClientIp()</code> <span class="tag b-api">SystemMethod</span></h2>
4243
- <span class="ret">string getClientIp()</span>
3983
+ <h2>Systemhelfer—<code>getClientIp()</code> <span class="tag b-api">SystemMethode</span></h2>
3984
+ <span class="ret">Zeichenfolge getClientIp()</span>
4244
3985
  <p>Erkennt die tatsächliche IP-Adresse des Benutzers. Wolkenflare (<code>HTTP_CF_CONNECTING_IP</code>), Proxy (<code>HTTP_X_FORWARDED_FOR</code>) und Standard (<code>REMOTE_ADDR</code>) löst alle Verbindungen automatisch auf.</p>
4245
- <pre><code><span class="var">$ip</span> = <span class="fn">getClientIp</span>(); <span class="cm">// Örn: 192.168.1.1</span></code></pre>
3986
+ <pre><code><span class="var">$ip</span> = <span class="fn">getClientIp</span>(); <span class="cm">// Beispiel: 192.168.1.1</span></code></pre>
4246
3987
  </section>
4247
-
4248
3988
  <section id="sh-verifyemail">
4249
- <h2>Systemhelfer— <code>verifyEmail()</code> <span class="tag b-api">SystemMethod</span></h2>
3989
+ <h2>Systemhelfer—<code>verifyEmail()</code> <span class="tag b-api">SystemMethode</span></h2>
4250
3990
  <p>Es überprüft anhand von DNS oder Format, ob die angegebene E-Mail-Adresse tatsächlich eine gültige E-Mail-Adresse ist.</p>
4251
3991
  <span class="ret">bool verifyEmail(string $email)</span>
4252
- <pre><code><span class="kw">if</span> (!<span class="fn">verifyEmail</span>(<span class="var">$_POST</span>[<span class="st">'eposta'</span>])) {
4253
- <span class="fn">apiResponse</span>(<span class="st">'error'</span>, <span class="st">'Geçersiz e-posta adresi.'</span>);
3992
+ <pre><code><span class="kw">Wenn</span> (!<span class="fn">überprüfenEmail</span>(<span class="var">$_POST</span>[<span class="st">'E-Mail'</span>])) {
3993
+ <span class="fn">apiResponse</span>(<span class="st">'Fehler'</span>, <span class="st">„Ungültige E-Mail-Adresse.“</span>);
4254
3994
  }</code></pre>
4255
3995
  </section>
4256
3996
  <section id="sh-generatetoken">
4257
- <h2>Systemhelfer— <code>generateToken()</code> <span class="tag b-api">SystemMethod</span></h2>
4258
- <span class="ret">string generateToken(int $length = 32)</span>
4259
- <p>Erzeugt ein kryptografisch sicheres, zufälliges Token (Beispiel: Passwort-Reset, API-Schlüssel). <strong>Hinweis: Jede eingegebene Länge von 1 Byte erzeugt eine Ausgabe von 2 Zeichen (hex).</strong> Die Standardlänge von 32 Byte gibt eine Zeichenfolge zurück, die genau 64 Zeichen lang ist.</p>
4260
- <pre><code><span class="var">$token</span> = <span class="fn">generateToken</span>(<span class="nu">16</span>); <span class="cm">// 32 karakterlik token</span></code></pre>
3997
+ <h2>Systemhelfer—<code>generateToken()</code> <span class="tag b-api">SystemMethode</span></h2>
3998
+ <span class="ret">string genericToken(int $length = 32)</span>
3999
+ <p>Erzeugt ein kryptografisch sicheres, zufälliges Token (Beispiel: Passwort-Reset, API-Schlüssel).<strong>Hinweis: Jede eingegebene Länge von 1 Byte erzeugt eine Ausgabe von 2 Zeichen (hex).</strong>Die Standardlänge von 32 Byte gibt eine Zeichenfolge zurück, die genau 64 Zeichen lang ist.</p>
4000
+ <pre><code><span class="var">$token</span> = <span class="fn">generierenToken</span>(<span class="nu">16</span>); <span class="cm">// 32-Zeichen-Token</span></code></pre>
4261
4001
  </section>
4262
4002
  <section id="sh-hashpassword">
4263
- <h2>Systemhelfer— <code>hashPassword()</code> <span class="tag b-api">SystemMethod</span></h2>
4003
+ <h2>Systemhelfer—<code>hashPassword()</code> <span class="tag b-api">SystemMethode</span></h2>
4264
4004
  <span class="ret">string hashPassword(?string $password)</span>
4265
- <p>PHP ist integriert <code>password_hash</code> Mithilfe dieser Methode werden Passwörter mit dem bcrypt-Algorithmus sicher gehasht. <strong>Nullprüfung:</strong> Wenn der Parameter leer ist oder <code>null</code> Wenn dies der Fall ist, wird eine Ausnahme ausgelöst, um eine Verletzung der Sicherheit zu vermeiden.</p>
4266
- <pre><code><span class="var">$hashed</span> = <span class="fn">hashPassword</span>(<span class="var">$_POST</span>[<span class="st">'sifre'</span>]);</code></pre>
4005
+ <p>PHP ist integriert<code>password_hash</code>Mithilfe dieser Methode werden Passwörter mit dem bcrypt-Algorithmus sicher gehasht.<strong>Nullprüfung:</strong>Wenn der Parameter leer ist oder<code>null</code>Wenn dies der Fall ist, wird eine Ausnahme ausgelöst, um eine Verletzung der Sicherheit zu vermeiden.</p>
4006
+ <pre><code><span class="var">$gehasht</span> = <span class="fn">hashPassword</span>(<span class="var">$_POST</span>[<span class="st">'Passwort'</span>]);</code></pre>
4267
4007
  </section>
4268
4008
  <section id="sh-verifypassword">
4269
- <h2>Systemhelfer— <code>verifyPassword()</code> <span class="tag b-api">SystemMethod</span></h2>
4009
+ <h2>Systemhelfer—<code>verifyPassword()</code> <span class="tag b-api">SystemMethode</span></h2>
4270
4010
  <span class="ret">bool verifyPassword(?string $password, ?string $hash)</span>
4271
- <p>Es vergleicht das vom Benutzer eingegebene Klartext-Passwort mit dem Hash in der Datenbank. <strong>Nullprüfung:</strong> Entweder ist das Passwort oder der Hash leer oder <code>null</code> direkt ohne Aktion <code>false</code> rotierend.</p>
4272
- <pre><code><span class="kw">if</span> (<span class="fn">verifyPassword</span>(<span class="var">$_POST</span>[<span class="st">'sifre'</span>], <span class="var">$user</span>[<span class="st">'password'</span>])) {
4273
- <span class="cm">// Giriş başarılı</span>
4011
+ <p>Es vergleicht das vom Benutzer eingegebene Klartext-Passwort mit dem Hash in der Datenbank.<strong>Nullprüfung:</strong>Entweder ist das Passwort oder der Hash leer oder<code>null</code>direkt ohne Aktion<code>false</code>rotierend.</p>
4012
+ <pre><code><span class="kw">Wenn</span> (<span class="fn">VerifizierenPasswort</span>(<span class="var">$_POST</span>[<span class="st">'Passwort'</span>], <span class="var">$Benutzer</span>[<span class="st">'Passwort'</span>])) {
4013
+ <span class="cm">// Anmeldung erfolgreich</span>
4274
4014
  }</code></pre>
4275
4015
  </section>
4276
4016
  <section id="sh-slugify">
4277
- <h2>Systemhelfer— <code>slugify()</code> <span class="tag b-api">SystemMethod</span></h2>
4017
+ <h2>Systemhelfer—<code>slugify()</code> <span class="tag b-api">SystemMethode</span></h2>
4278
4018
  <p>Bei der Registrierung in der Datenbank auf der Backend-Seite werden automatisch SEO-freundliche URLs/Slugs aus Feldern wie Titel oder Name generiert. Es werden unbegrenzte Parameter benötigt (Variadic).</p>
4279
4019
  <span class="ret">string slugify(string ...$texts)</span>
4280
- <pre><code><span class="var">$slug</span> = <span class="fn">slugify</span>(<span class="var">$_POST</span>[<span class="st">'baslik'</span>]); <span class="cm">// 'benim-guzel-yazim'</span></code></pre>
4020
+ <pre><code><span class="var">$schnecke</span> = <span class="fn">träge machen</span>(<span class="var">$_POST</span>[<span class="st">'Titel'</span>]); <span class="cm">// 'mein-schönes-schreiben'</span></code></pre>
4281
4021
  </section>
4282
4022
  <section id="sh-arrayonly">
4283
- <h2>Systemhelfer— <code>arrayOnly()</code> <span class="tag b-api">SystemMethod</span></h2>
4284
- <p>Ein großer Datensatz (z.B. <code>$_POST</code>) filtert nur die Daten mit den angegebenen Schlüsseln (Whitelist). Es wird unmittelbar vor Datenbankregistrierungsvorgängen verwendet, um Sicherheitslücken bei Massenzuweisungen zu vermeiden.</p>
4285
- <span class="ret">array arrayOnly(array $array, array $keys)</span>
4286
- <pre><code><span class="var">$postData</span> = <span class="fn">arrayOnly</span>(<span class="var">$_POST</span>, [<span class="st">'kullanici_adi'</span>, <span class="st">'sifre'</span>, <span class="st">'email'</span>]);
4287
- <span class="cm">// ID, rol gibi dışarıdan manipüle edilmiş değerler otomatik yok edilir.</span></code></pre>
4023
+ <h2>Systemhelfer—<code>arrayOnly()</code> <span class="tag b-api">SystemMethode</span></h2>
4024
+ <p>Ein großer Datensatz (z.B.<code>$_POST</code>) filtert nur die Daten mit den angegebenen Schlüsseln (Whitelist). Es wird unmittelbar vor Datenbankregistrierungsvorgängen verwendet, um Sicherheitslücken bei Massenzuweisungen zu vermeiden.</p>
4025
+ <span class="ret">Array arrayOnly(array $array, array $keys)</span>
4026
+ <pre><code><span class="var">$postData</span> = <span class="fn">arrayOnly</span>(<span class="var">$_POST</span>, [<span class="st">'Benutzername'</span>, <span class="st">'Passwort'</span>, <span class="st">'E-Mail'</span>]);
4027
+ <span class="cm">// Extern manipulierte Werte wie ID und Rolle werden automatisch zerstört.</span></code></pre>
4288
4028
  </section>
4289
-
4290
-
4291
- <section id="sh-byteid">
4292
- <h2>Systemhelfer - <code>byteId()</code> <span class="tag b-api">SystemMethod</span></h2>
4293
- <div class="info-box">
4294
- Native, leistungsstarke und zeitlich geordnete 16-Byte-Rohdaten <strong>UUIDv7</strong> produziert.
4295
- </div>
4296
- <p>ID-Spalten in der Datenbank <code>BINARY(16)</code> Wenn Sie eine enorme Indizierungs- und JOIN-Leistung erzielen möchten, indem Sie es als beibehalten, erstellen Sie mit dieser Funktion neue Datensätze.</p>
4029
+ <section id="sh-byteid">
4030
+ <h2>Systemhelfer -<code>byteId()</code> <span class="tag b-api">SystemMethode</span></h2>
4031
+ <div class="info-box">Native, leistungsstarke und zeitlich geordnete 16-Byte-Rohdaten<strong>UUIDv7</strong>produziert.</div>
4032
+ <p>ID-Spalten in der Datenbank<code>BINARY(16)</code>Wenn Sie eine enorme Indizierungs- und JOIN-Leistung erzielen möchten, indem Sie es als beibehalten, erstellen Sie mit dieser Funktion neue Datensätze.</p>
4297
4033
  <div class="code-block">
4298
4034
  <div class="code-header">
4299
4035
  <span class="code-lang">PHP</span>
4300
4036
  </div>
4301
- <pre><code><span class="kw">use</span> Bin\SystemMethod;
4302
-
4037
+ <pre><code><span class="kw">verwenden</span> Bin\SystemMethod;
4303
4038
  <span class="var">$rawId</span> = SystemMethod::<span class="fn">byteId</span>();
4304
- <span class="cm">// Veya global helper: byteId();</span>
4305
-
4306
- <span class="var">$db</span>-&gt;<span class="fn">prepare</span>(<span class="st">"INSERT INTO users (id, name) VALUES (?, ?)"</span>)-&gt;<span class="fn">execute</span>([<span class="var">$rawId</span>, <span class="st">'Utku'</span>]);</code></pre>
4307
- </div>
4308
- </section>
4309
-
4310
- <section id="sh-makeid">
4311
- <h2>Systemhelfer - <code>makeId()</code> <span class="tag b-api">SystemMethod</span></h2>
4312
- <div class="info-box">
4313
- Nativ, Standard 36 Zeichen <strong>UUIDv7</strong> erzeugt die Zeichenfolge.
4314
- </div>
4315
- <p>in der Datenbank <code>CHAR(36)</code> oder <code>VARCHAR(36)</code> Wenn Sie es verwenden und sich nicht mit rohen Binärdaten befassen möchten, können Sie mit dieser Funktion UUID direkt im String-Format generieren.</p>
4039
+ <span class="cm">// Oder globaler Helfer: byteId();</span>
4040
+ <span class="var">$db</span>-&gt;<span class="fn">vorbereiten</span>(<span class="st">„INSERT INTO user (id, name) VALUES (?, ?)“</span>)-&gt;<span class="fn">ausführen</span>([<span class="var">$rawId</span>, <span class="st">'Triumph'</span>]);</code></pre>
4041
+ </div>
4042
+ </section>
4043
+ <section id="sh-makeid">
4044
+ <h2>Systemhelfer -<code>makeId()</code> <span class="tag b-api">SystemMethode</span></h2>
4045
+ <div class="info-box">Nativ, Standard 36 Zeichen<strong>UUIDv7</strong>erzeugt die Zeichenfolge.</div>
4046
+ <p>in der Datenbank<code>CHAR(36)</code>oder<code>VARCHAR(36)</code>Wenn Sie es verwenden und sich nicht mit rohen Binärdaten befassen möchten, können Sie mit dieser Funktion UUID direkt im String-Format generieren.</p>
4316
4047
  <div class="code-block">
4317
4048
  <div class="code-header">
4318
4049
  <span class="code-lang">PHP</span>
4319
4050
  </div>
4320
- <pre><code><span class="kw">use</span> Bin\SystemMethod;
4321
-
4051
+ <pre><code><span class="kw">verwenden</span> Bin\SystemMethod;
4322
4052
  <span class="var">$stringId</span> = SystemMethod::<span class="fn">makeId</span>();
4323
- <span class="cm">// Örnek Çıktı: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4324
- </div>
4325
- </section>
4326
-
4327
- <section id="sh-formatid">
4328
- <h2>Systemhelfer - <code>formatId()</code> <span class="tag b-api">SystemMethod</span></h2>
4329
- <div class="info-box">
4330
- Konvertiert rohe 16-Byte-Binär-UUIDs in eine Standardzeichenfolge mit 36 ​​Zeichen.
4331
- </div>
4332
- <p>Was Sie aus der Datenbank entnommen haben <code>BINARY(16)</code> Es bringt die Daten in ein lesbares Format, bevor es sie an die Schnittstelle (API/JSON) sendet.</p>
4053
+ <span class="cm">// Beispielausgabe: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4054
+ </div>
4055
+ </section>
4056
+ <section id="sh-formatid">
4057
+ <h2>Systemhelfer -<code>formatId()</code> <span class="tag b-api">SystemMethode</span></h2>
4058
+ <div class="info-box">Konvertiert rohe 16-Byte-Binär-UUIDs in eine Standardzeichenfolge mit 36 ​​Zeichen.</div>
4059
+ <p>Was Sie aus der Datenbank entnommen haben<code>BINARY(16)</code>Es bringt die Daten in ein lesbares Format, bevor es sie an die Schnittstelle (API/JSON) sendet.</p>
4333
4060
  <div class="code-block">
4334
4061
  <div class="code-header">
4335
4062
  <span class="code-lang">PHP</span>
4336
4063
  </div>
4337
- <pre><code><span class="kw">use</span> Bin\SystemMethod;
4338
-
4339
- <span class="var">$user</span> = <span class="var">$db</span>-&gt;<span class="fn">query</span>(<span class="st">"SELECT id FROM users LIMIT 1"</span>)-&gt;<span class="fn">fetch</span>();
4340
- <span class="var">$readableId</span> = SystemMethod::<span class="fn">formatId</span>(<span class="var">$user</span>[<span class="st">'id'</span>]);
4341
- <span class="cm">// Örnek Çıktı: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4342
- </div>
4343
- </section>
4344
-
4345
- <section id="sh-intid">
4346
- <h2>Systemhelfer - <code>intId()</code> <span class="tag b-api">SystemMethod</span></h2>
4347
- <div class="info-box">
4348
- Sicher, zufällig <code>INT</code> Erzeugt eine ID. (Max. 9 Ziffern)
4349
- </div>
4064
+ <pre><code><span class="kw">verwenden</span> Bin\SystemMethod;
4065
+ <span class="var">$Benutzer</span> = <span class="var">$db</span>-&gt;<span class="fn">Abfrage</span>(<span class="st">„Wählen Sie die ID aus Benutzerlimit 1 aus“</span>)-&gt;<span class="fn">bringen</span>();
4066
+ <span class="var">$readableId</span> = SystemMethod::<span class="fn">formatId</span>(<span class="var">$Benutzer</span>[<span class="st">'AUSWEIS'</span>]);
4067
+ <span class="cm">// Beispielausgabe: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4068
+ </div>
4069
+ </section>
4070
+ <section id="sh-intid">
4071
+ <h2>Systemhelfer -<code>intId()</code> <span class="tag b-api">SystemMethode</span></h2>
4072
+ <div class="info-box">Sicher, zufällig<code>INT</code>Erzeugt eine ID. (Max. 9 Ziffern)</div>
4350
4073
  <p>Es handelt sich um den herkömmlichen Ganzzahlgenerator, den Sie verwenden können, wenn Sie nicht auf die Leistung herkömmlicher Datenbanken verzichten möchten.</p>
4351
4074
  <div class="code-block">
4352
4075
  <div class="code-header">
4353
4076
  <span class="code-lang">PHP</span>
4354
4077
  </div>
4355
4078
  <pre><code><span class="var">$id</span> = <span class="fn">intId</span>(8);
4356
- <span class="cm">// Örnek Çıktı: 49201834</span></code></pre>
4357
- </div>
4358
- </section>
4359
-
4360
- <section id="sh-bigintid">
4361
- <h2>Systemhelfer - <code>bigintId()</code> <span class="tag b-api">SystemMethod</span></h2>
4362
- <div class="info-box">
4363
- Sicher, zufällig <code>BIGINT</code> Erzeugt eine ID. (Standard 15 Ziffern – sichere Grenze für JS)
4364
- </div>
4365
- <p>Wenn Sie große numerische IDs wie Snowflake (Twilio) verwenden, wird diese Funktion Ihr Leben retten. Wenn Sie mehr als 15 Ziffern wünschen, können Sie diese als Zeichenfolge importieren, um Datenverlust zu verhindern.</p>
4079
+ <span class="cm">// Beispielausgabe: 49201834</span></code></pre>
4080
+ </div>
4081
+ </section>
4082
+ <section id="sh-bigintid">
4083
+ <h2>Systemhelfer -<code>bigintId()</code> <span class="tag b-api">SystemMethode</span></h2>
4084
+ <div class="info-box">Sicher, zufällig<code>BIGINT</code>Erzeugt eine ID. (Standard 15 Ziffern – sichere Grenze für JS)</div>
4085
+ <p>Wenn Sie große numerische IDs wie Snowflake (Twitter) verwenden, wird diese Funktion Ihr Leben retten. Wenn Sie mehr als 15 Ziffern wünschen, können Sie diese als Zeichenfolge importieren, um Datenverlust zu verhindern.</p>
4366
4086
  <div class="code-block">
4367
4087
  <div class="code-header">
4368
4088
  <span class="code-lang">PHP</span>
4369
4089
  </div>
4370
- <pre><code><span class="var">$id</span> = <span class="fn">bigintId</span>(); <span class="cm">// 15 haneli INT döner</span>
4371
- <span class="var">$massiveId</span> = <span class="fn">bigintId</span>(18, <span class="kw">true</span>); <span class="cm">// 18 haneli STRING döner (JS için güvenli)</span></code></pre>
4090
+ <pre><code><span class="var">$id</span> = <span class="fn">bigintId</span>(); <span class="cm">// Gibt 15-stelliges INT zurück</span>
4091
+ <span class="var">$massiveId</span> = <span class="fn">bigintId</span>(18, <span class="kw">WAHR</span>); <span class="cm">// gibt 18-stelligen STRING zurück (JS-sicher)</span></code></pre>
4372
4092
  </div>
4373
- </section>
4374
-
4375
- <section id="sh-stringer">
4376
- <h2>Systemhelfer - <code>stringer()</code> <span class="tag b-api">SystemMethod</span></h2>
4377
- <div class="info-box">
4378
- Verpackt Werte in Zeichenfolgen, um sie vor der Unempfindlichkeit gegenüber riesigen Zahlen (BIGINT) von Javascript zu schützen.
4379
- </div>
4093
+ </section>
4094
+ <section id="sh-stringer">
4095
+ <h2>Systemhelfer -<code>stringer()</code> <span class="tag b-api">SystemMethode</span></h2>
4096
+ <div class="info-box">Verpackt Werte in Zeichenfolgen, um sie vor der Unempfindlichkeit gegenüber riesigen Zahlen (BIGINT) von Javascript zu schützen.</div>
4380
4097
  <p>Es schützt numerische Variablen (BigInt usw.), die größer als 15 Ziffern sind, vor den Rundungsfehlern (Präzisionsverlust) von Javascript, wenn sie im DOM in der Ansichtsebene gedruckt werden.</p>
4381
4098
  <div class="code-block">
4382
4099
  <div class="code-header">
4383
4100
  <span class="code-lang">HTML/PHP</span>
4384
4101
  </div>
4385
- <pre><code><span class="cm">&lt;!-- JS'in bozmasını engellemek için stringer ile sarmalıyoruz --&gt;</span>
4386
- &lt;button data-id=<span class="st">"&lt;?=</span> <span class="fn">stringer</span>(<span class="var">$data</span>[<span class="st">'id'</span>]) <span class="st">?&gt;"</span>&gt;Sil&lt;/button&gt;</code></pre>
4387
- </div>
4388
-
4389
-
4390
- <section id="sh-otpcoder">
4391
- <h2>System Helpers - OTP Coder <span class="tag b-api">SystemMethod</span></h2>
4392
- <div class="info-box">Generiert zufällige, kryptografisch sichere Einmalpasswörter (OTP).</div>
4393
- <div class="code-block">
4394
- <pre><code><span class="cm">// 6-stellige Zufallszahl</span>
4395
- <span class="var">$code</span> = <span class="fn">otpInt</span>(<span class="nu">6</span>); <span class="cm">// 482910</span>
4396
-
4397
- <span class="cm">// 8-stellige reine Buchstaben ('c': klein, 'C': groß, 'cC': gemischt)</span>
4398
- <span class="var">$code</span> = <span class="fn">otpStr</span>(<span class="nu">8</span>, <span class="st">'C'</span>); <span class="cm">// PKLMDZRA</span>
4399
-
4400
- <span class="cm">// 6-stellig alphanumerisch</span>
4401
- <span class="var">$code</span> = <span class="fn">otpMix</span>(<span class="nu">6</span>, <span class="st">'C'</span>); <span class="cm">// 9A4X2Z</span></code></pre>
4402
- </div>
4403
- </section>
4404
-
4405
-
4406
- </section>
4407
- <!-- ====== API GÜVENLİĞİ ====== -->
4102
+ <pre><code><span class="cm">&lt;!-- Wir umschließen es mit einem Stringer, um zu verhindern, dass JS es beschädigt --&gt;</span>
4103
+ &lt;button data-id=<span class="st">„&lt;?=</span> <span class="fn">Stringer</span>(<span class="var">$Daten</span>[<span class="st">'AUSWEIS'</span>]) <span class="st">?&gt;"</span>&gt;Sil&lt;/button&gt;</code></pre>
4104
+ </div>
4105
+ <section id="sh-otpcoder">
4106
+ <h2>Systemhelfer - OTP-Codierer<span class="tag b-api">SystemMethode</span></h2>
4107
+ <div class="info-box">Erzeugt zufällige, kryptografisch sichere Authentifizierungscodes (OTP).</div>
4108
+ <div class="code-block">
4109
+ <pre><code><span class="cm">// 6-stellige Zufallszahl</span>
4110
+ <span class="var">$code</span> = <span class="fn">otpInt</span>(<span class="nu">6</span>); <span class="cm">// 482910</span>
4111
+ <span class="cm">// Nur 8-stelliger Buchstabe ('c': Kleinbuchstabe, 'C': Großbuchstabe, 'cC': gemischt)</span>
4112
+ <span class="var">$code</span> = <span class="fn">otpStr</span>(<span class="nu">8</span>, <span class="st">'C'</span>); <span class="cm">// PKLMDZRA</span>
4113
+ <span class="cm">// 6-stelliger Buchstabe+Zahl (alphanumerisch)</span>
4114
+ <span class="var">$code</span> = <span class="fn">otpMix</span>(<span class="nu">6</span>, <span class="st">'C'</span>); <span class="cm">//9A4X2Z</span></code></pre>
4115
+ </div>
4116
+ </section>
4117
+ </section>
4118
+ ====== API-SICHERHEIT ======
4408
4119
  <section id="api-methods">
4409
- <h2>API – HTTP-Methodensteuerung <span class="tag b-sec">ApiControl</span></h2>
4410
- <p><code class="ic">$allowedMethods</code> Array von ApiControl erfordern <strong>vor</strong> muss definiert werden. ApiControl blockiert automatisch Anfragen von unzulässigen Methoden, indem es diese Zeichenfolge liest. <code class="ic">405 Method Not Allowed</code> Er lehnt es mit ab.</p>
4411
- <pre><code><span class="cm">// Sadece GET ve POST kabul eden bir endpoint</span>
4412
- <span class="var">$allowedMethods</span> = [<span class="st">'GET'</span>, <span class="st">'POST'</span>];
4120
+ <h2>API – HTTP-Methodensteuerung<span class="tag b-sec">ApiControl</span></h2>
4121
+ <p><code class="ic">$allowedMethods</code>Array von ApiControl erfordern<strong>vor</strong>muss definiert werden. ApiControl blockiert automatisch Anfragen von unzulässigen Methoden, indem es diese Zeichenfolge liest.<code class="ic">405 Method Not Allowed</code>Er lehnt es mit ab.</p>
4122
+ <pre><code><span class="cm">// Ein Endpunkt, der nur GET und POST akzeptiert</span>
4123
+ <span class="var">$allowedMethods</span> = [<span class="st">'ERHALTEN'</span>, <span class="st">'POST'</span>];
4413
4124
  <span class="fn">require_once</span> ... . <span class="st">'/../app/ApiControl.php'</span>;
4414
-
4415
- <span class="cm">// Sadece DELETE kabul eden bir endpoint</span>
4416
- <span class="var">$allowedMethods</span> = [<span class="st">'DELETE'</span>];
4125
+ <span class="cm">// Ein Endpunkt, der nur DELETE akzeptiert</span>
4126
+ <span class="var">$allowedMethods</span> = [<span class="st">'LÖSCHEN'</span>];
4417
4127
  <span class="fn">require_once</span> ... . <span class="st">'/../app/ApiControl.php'</span>;</code></pre>
4418
- <p>Vorflug <code class="ic">OPTIONS</code> automatische Anfragen für CORS <code class="ic">200</code> kehrt zurück und das Skript wird beendet – kein manueller Eingriff erforderlich.</p>
4128
+ <p>Vorflug<code class="ic">OPTIONS</code>automatische Anfragen für CORS<code class="ic">200</code>kehrt zurück und das Skript wird beendet – kein manueller Eingriff erforderlich.</p>
4419
4129
  </section>
4420
4130
  <section id="api-cors">
4421
- <h2>API – CORS <span class="tag b-api">ApiControl (Yorum Satırı)</span></h2>
4422
- <p>Wenn Sie den API-Zugriff von anderen Domänen oder mobilen Anwendungen zulassen möchten <code class="ic">ApiControl.php</code> Aktivieren Sie darin den CORS-Block.</p>
4423
- <pre><code><span class="cm">// ApiControl.php içinde açıklama kaldırılarak aktifleştirilir</span>
4424
- header(<span class="st">"Access-Control-Allow-Origin: https://sizin-domaininiz.com"</span>);
4425
- header(<span class="st">"Access-Control-Allow-Methods: GET, POST, OPTIONS"</span>);
4426
- header(<span class="st">"Access-Control-Allow-Headers: Content-Type, Authorization"</span>);</code></pre>
4131
+ <h2>API – CORS<span class="tag b-api">ApiControl (Kommentarzeile)</span></h2>
4132
+ <p>Wenn Sie den API-Zugriff von anderen Domänen oder mobilen Anwendungen zulassen möchten<code class="ic">ApiControl.php</code>Aktivieren Sie darin den CORS-Block.</p>
4133
+ <pre><code><span class="cm">// In ApiControl.php aktiviert durch Entfernen des Kommentars</span>
4134
+ header(<span class="st">„Access-Control-Allow-Origin: https://your-domain.com“</span>);
4135
+ header(<span class="st">„Access-Control-Allow-Methoden: GET, POST, OPTIONS“</span>);
4136
+ header(<span class="st">„Access-Control-Allow-Header: Inhaltstyp, Autorisierung“</span>);</code></pre>
4427
4137
  <div class="alert a-warn">
4428
- <strong>⚠️</strong> Im Produktionsumfeld <code class="ic">*</code> Nicht verwenden (alle Domänen). Geben Sie die Domänenadresse deutlich an.
4429
- </div>
4138
+ <strong>⚠️</strong>Im Produktionsumfeld<code class="ic">*</code>Nicht verwenden (alle Domänen). Geben Sie die Domänenadresse deutlich an.</div>
4430
4139
  </section>
4431
4140
  <section id="api-rate">
4432
- <h2>API – Ratenbegrenzung <span class="tag b-api">ApiControl (Yorum Satırı)</span></h2>
4433
- <p>Um zu verhindern, dass böswillige Benutzer oder Bots die API überfluten <code class="ic">ApiControl.php</code> Sie können darin den Rate-Limiting-Block aktivieren. Standardregel: <strong>60 Anfragen/IP in 60 Sekunden</strong>.</p>
4141
+ <h2>API – Ratenbegrenzung<span class="tag b-api">ApiControl (Kommentarzeile)</span></h2>
4142
+ <p>Um zu verhindern, dass böswillige Benutzer oder Bots die API überfluten<code class="ic">ApiControl.php</code>Sie können darin den Rate-Limiting-Block aktivieren. Standardregel:<strong>60 Anfragen/IP in 60 Sekunden</strong>.</p>
4434
4143
  <div class="alert a-warn" style="margin-top: 10px; margin-bottom: 20px;">
4435
- <strong>⚠️ Redis-Server erforderlich:</strong> Ratenbegrenzungsfunktion <code>\Src\Service\RedisService::getInstance()</code> Es funktioniert mit der Redis-Klasse. Stellen Sie vor dem Öffnen dieses Codeblocks sicher, dass Sie in Ihrem Projekt einen Redis-Dienst eingerichtet haben <code>src/Service/</code> Stellen Sie sicher, dass Sie unten eine Verbindungsklasse erstellen
4436
- </div>
4437
- <pre><code><span class="cm">// Aynı IP'den 60 saniyede 60'tan fazla istek gelirse:</span>
4438
- http_response_code(<span class="nu">429</span>); <span class="cm">// Too Many Requests</span>
4439
- echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok fazla istek. Lütfen bekleyin.'</span>]);</code></pre>
4144
+ <strong>⚠️ Redis-Server erforderlich:</strong>Ratenbegrenzungsfunktion<code>\Src\Service\RedisService::getInstance()</code>Es funktioniert mit der Redis-Klasse. Stellen Sie vor dem Öffnen dieses Codeblocks sicher, dass Sie in Ihrem Projekt einen Redis-Dienst eingerichtet haben<code>src/Service/</code>Stellen Sie sicher, dass Sie unten eine Verbindungsklasse erstellen</div>
4145
+ <pre><code><span class="cm">// Wenn in 60 Sekunden mehr als 60 Anfragen von derselben IP kommen:</span>
4146
+ http_response_code(<span class="nu">429</span>); <span class="cm">//Zu viele Anfragen</span>
4147
+ echo json_encode([<span class="st">'Fehler'</span> =&gt; <span class="st">„Zu viele Anfragen. Bitte warten.'</span>]);</code></pre>
4440
4148
  </section>
4441
- <!-- ====== WORKFLOW ====== -->
4149
+ ====== WORKFLOW ======
4442
4150
  <section id="workflow">
4443
4151
  <h2>Vollständiger Workflow: Kontaktformular (End-to-End)</h2>
4444
- <p>Eins <strong>Kontaktformular</strong> Lassen Sie uns Schritt für Schritt untersuchen, wie die Funktion in ArtiFrame-Standards von Anfang bis Ende entwickelt wird.</p>
4152
+ <p>Eins<strong>Kontaktformular</strong>Lassen Sie uns Schritt für Schritt untersuchen, wie die Funktion in ArtiFrame-Standards von Anfang bis Ende entwickelt wird.</p>
4445
4153
  <ol class="steps">
4446
4154
  <li>
4447
4155
  <div>
4448
4156
  <strong>Ansichtsdatei erstellen</strong>
4449
- <pre><code>artiframe&gt; <span class="fn">make:view</span> <span class="st">iletisim.php</span>
4450
- <span class="cm">✔ public/iletisim.php</span>
4451
- <span class="cm">✔ public/assets/css/iletisim.css</span>
4452
- <span class="cm">✔ public/assets/js/iletisim.js</span></code></pre>
4157
+ <pre><code>artiframe&gt; <span class="fn">make:view</span> <span class="st">contact.php</span>
4158
+ <span class="cm">✔ public/contact.php</span>
4159
+ <span class="cm">✔ public/assets/css/contact.css</span>
4160
+ <span class="cm">✔ public/assets/js/contact.js</span></code></pre>
4453
4161
  </div>
4454
4162
  </li>
4455
4163
  <li>
4456
4164
  <div>
4457
4165
  <strong>Erstellen Sie einen API-Endpunkt</strong>
4458
- <pre><code>artiframe&gt; <span class="fn">make:api</span> <span class="st">standart</span> <span class="st">api/iletisim/gonder.php</span></code></pre>
4166
+ <pre><code>artiframe&gt; <span class="fn">make:api</span> <span class="st">Standard</span> <span class="st">api/contact/send.php</span></code></pre>
4459
4167
  </div>
4460
4168
  </li>
4461
4169
  <li>
4462
4170
  <div>
4463
4171
  <strong>Code-HTML-Formular</strong><br/>
4464
- <code class="ic">public/iletisim.php</code> Fügen Sie der Datei das folgende Formular hinzu:
4465
- <pre><code>&lt;form action="/api/iletisim/gonder.php" method="POST"&gt;
4172
+ <code class="ic">public/iletisim.php</code>Fügen Sie der Datei das folgende Formular hinzu:<pre><code>&lt;form action="/api/iletisim/gonder.php" method="POST"&gt;
4466
4173
  &lt;?= <span class="fn">csrfField</span>() ?&gt;
4467
4174
  &lt;input type="text" name="ad" placeholder="Adınız"&gt;
4468
4175
  &lt;input type="email" name="eposta" placeholder="E-posta"&gt;
4469
4176
  &lt;textarea name="mesaj" placeholder="Mesajınız"&gt;&lt;/textarea&gt;
4470
- &lt;button type="submit" data-js="<span class="st">iletisim-gonder</span>"&gt;Gönder&lt;/button&gt;
4177
+ &lt;button type="submit" data-js="<span class="st">Kontakt-senden</span>"&gt;Gönder&lt;/button&gt;
4471
4178
  &lt;/form&gt;</code></pre>
4472
4179
  </div>
4473
4180
  </li>
4474
4181
  <li>
4475
4182
  <div>
4476
4183
  <strong>Verbinden Sie die Fetch-API mit JavaScript</strong><br/>
4477
- <code class="ic">public/assets/js/iletisim.js</code> einreichen:
4478
- <pre><code>document.<span class="fn">querySelector</span>(<span class="st">'[data-js="iletisim-gonder"]'</span>).<span class="fn">addEventListener</span>(<span class="st">'click'</span>, async (e) =&gt; {
4479
- e.<span class="fn">preventDefault</span>();
4480
- <span class="kw">const</span> formData = <span class="kw">new</span> <span class="fn">FormData</span>(e.target.<span class="fn">closest</span>(<span class="st">'form'</span>));
4481
- <span class="kw">const</span> res = <span class="kw">await</span> <span class="fn">fetch</span>(<span class="st">'/api/iletisim/gonder.php'</span>, {
4184
+ <code class="ic">public/assets/js/iletisim.js</code>einreichen:<pre><code>document.<span class="fn">querySelector</span>(<span class="st">'[data-js="contact-send"]'</span>).<span class="fn">addEventListener</span>(<span class="st">'klicken'</span>, async (e) =&gt; {
4185
+ e.<span class="fn">verhindernStandard</span>();
4186
+ <span class="kw">const</span> formData = <span class="kw">neu</span> <span class="fn">FormData</span>(e.target.<span class="fn">am nächsten</span>(<span class="st">'bilden'</span>));
4187
+ <span class="kw">const</span> res = <span class="kw">erwarten</span> <span class="fn">bringen</span>(<span class="st">'/api/contact/sender.php'</span>, {
4482
4188
  method: <span class="st">'POST'</span>,
4483
4189
  body: formData
4484
4190
  });
4485
- <span class="kw">const</span> data = <span class="kw">await</span> res.<span class="fn">json</span>();
4486
- <span class="fn">console</span>.<span class="fn">log</span>(data);
4191
+ <span class="kw">const</span> data = <span class="kw">erwarten</span> res.<span class="fn">json</span>();
4192
+ <span class="fn">Konsole</span>.<span class="fn">Protokoll</span>(data);
4487
4193
  });</code></pre>
4488
4194
  </div>
4489
4195
  </li>
4490
4196
  <li>
4491
4197
  <div>
4492
4198
  <strong>Komplette Serverlogik (Backend)</strong><br/>
4493
- <code class="ic">public/api/iletisim/gonder.php</code> in der Datei:
4494
- <pre><code><span class="kw">&lt;?php</span>
4199
+ <code class="ic">public/api/iletisim/gonder.php</code>in der Datei:<pre><code><span class="kw">&lt;?php</span>
4495
4200
  <span class="var">$allowedMethods</span> = [<span class="st">'POST'</span>];
4496
4201
  <span class="fn">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/../app/ApiControl.php'</span>;
4497
- <span class="kw">use</span> Bin\SystemMethod;
4498
-
4499
- <span class="cm">// 1. CSRF Doğrulama</span>
4500
- <span class="kw">if</span> (!<span class="fn">verifyCsrf</span>(<span class="var">$_POST</span>[<span class="st">'csrf_token'</span>] ?? <span class="st">''</span>)) {
4501
- <span class="fn">jsonResponse</span>([<span class="st">'error'</span> =&gt; <span class="st">'Geçersiz token.'</span>], <span class="nu">403</span>);
4202
+ <span class="kw">verwenden</span> Bin\SystemMethod;
4203
+ <span class="cm">// 1. CSRF-Überprüfung</span>
4204
+ <span class="kw">Wenn</span> (!<span class="fn">überprüfenCsrf</span>(<span class="var">$_POST</span>[<span class="st">'csrf_token'</span>] ?? <span class="st">''</span>)) {
4205
+ <span class="fn">jsonResponse</span>([<span class="st">'Fehler'</span> =&gt; <span class="st">„Ungültiges Token.“</span>], <span class="nu">403</span>);
4502
4206
  }
4503
-
4504
- <span class="cm">// 2. Veriyi Temizle</span>
4505
- <span class="var">$ad</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'ad'</span>] ?? <span class="st">''</span>);
4506
- <span class="var">$eposta</span> = <span class="fn">sanitizeEmail</span>(<span class="var">$_POST</span>[<span class="st">'eposta'</span>] ?? <span class="st">''</span>);
4507
- <span class="var">$mesaj</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'mesaj'</span>] ?? <span class="st">''</span>);
4508
-
4509
- <span class="cm">// 3. İş Mantığı (Mail gönder, DB'ye kaydet vb.)</span>
4510
- <span class="cm">// ...</span>
4511
-
4512
- <span class="cm">// 4. Yanıt Ver</span>
4513
- <span class="fn">jsonResponse</span>([<span class="st">'status'</span> =&gt; <span class="st">'success'</span>, <span class="st">'message'</span> =&gt; <span class="st">'Mesajınız alındı.'</span>], <span class="nu">200</span>);</code></pre>
4207
+ <span class="cm">// 2. Daten löschen</span>
4208
+ <span class="var">$name</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'Name'</span>] ?? <span class="st">''</span>);
4209
+ <span class="var">$E-Mail</span> = <span class="fn">sanitizeEmail</span>(<span class="var">$_POST</span>[<span class="st">'E-Mail'</span>] ?? <span class="st">''</span>);
4210
+ <span class="var">$Nachricht</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'Nachricht'</span>] ?? <span class="st">''</span>);
4211
+ <span class="cm">// 3. Geschäftslogik (E-Mail senden, in der Datenbank speichern usw.)</span>
4212
+ <span class="cm">//......</span>
4213
+ <span class="cm">// 4. Antworten</span>
4214
+ <span class="fn">jsonResponse</span>([<span class="st">'Status'</span> =&gt; <span class="st">'Erfolg'</span>, <span class="st">'Nachricht'</span> =&gt; <span class="st">„Ihre Nachricht wurde empfangen.“</span>], <span class="nu">200</span>);</code></pre>
4514
4215
  </div>
4515
4216
  </li>
4516
4217
  </ol>
4517
4218
  <div class="alert a-success">
4518
- <strong>✅ Abgeschlossen!</strong> Sie haben einen vollständig sicheren und standardkonformen Formularfluss mit XSS-Schutz, CSRF-Validierung, HTTP-Methodenbeschränkung und Data-JS-Architektur erstellt.
4519
- </div>
4219
+ <strong>✅ Abgeschlossen!</strong>Sie haben einen vollständig sicheren und standardkonformen Formularfluss mit XSS-Schutz, CSRF-Validierung, HTTP-Methodenbeschränkung und Data-JS-Architektur erstellt.</div>
4520
4220
  </section>
4521
4221
  </main>
4522
4222
  <script>
4523
4223
  const sections = document.querySelectorAll('section[id], header[id], div.card[id]');
4524
4224
  const links = document.querySelectorAll('.sidebar nav a');
4525
-
4526
4225
  const observer = new IntersectionObserver((entries) => {
4527
4226
  entries.forEach(entry => {
4528
4227
  if (entry.isIntersecting) {
@@ -4532,7 +4231,6 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4532
4231
  }
4533
4232
  });
4534
4233
  }, { rootMargin: '-20% 0px -70% 0px' });
4535
-
4536
4234
  sections.forEach(s => observer.observe(s));
4537
4235
  </script>
4538
4236
  <script>
@@ -4541,7 +4239,6 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4541
4239
  const ctx = canvas.getContext('2d');
4542
4240
  const cw = canvas.width;
4543
4241
  const ch = canvas.height;
4544
-
4545
4242
  function drawRoundedRect(x, y, w, h, r, fill, stroke) {
4546
4243
  ctx.beginPath();
4547
4244
  ctx.moveTo(x + r, y);
@@ -4562,7 +4259,6 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4562
4259
  ctx.stroke();
4563
4260
  }
4564
4261
  }
4565
-
4566
4262
  function drawLine(x1, y1, x2, y2, color) {
4567
4263
  ctx.beginPath();
4568
4264
  ctx.moveTo(x1, y1);
@@ -4578,7 +4274,6 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4578
4274
  ctx.fillStyle = color;
4579
4275
  ctx.fill();
4580
4276
  }
4581
-
4582
4277
  function drawPath(points, color) {
4583
4278
  if(points.length < 2) return;
4584
4279
  ctx.beginPath();
@@ -4599,7 +4294,6 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4599
4294
  ctx.fillStyle = color;
4600
4295
  ctx.fill();
4601
4296
  }
4602
-
4603
4297
  function drawText(text, x, y, color, font = "14px Inter", align = "center") {
4604
4298
  ctx.fillStyle = color;
4605
4299
  ctx.font = font;
@@ -4607,40 +4301,31 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4607
4301
  ctx.textBaseline = "middle";
4608
4302
  ctx.fillText(text, x, y);
4609
4303
  }
4610
-
4611
4304
  const nodes = [
4612
- { id: 'n1', x: 20, y: 220, w: 170, h: 50, text: "Wo wird das Projekt laufen?", bg: "#1c2128", border: "#58a6ff", textColor: "#e6edf3" },
4613
- { id: 'n2_local', x: 250, y: 80, w: 220, h: 50, text: "Nur Localhost / Individuell\n(Kein externes Netzwerk)", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4614
- { id: 'n2_net', x: 250, y: 320, w: 200, h: 50, text: "Offen für Netzwerk / Internet\n(SaaS, Intranet, Web)", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4615
- { id: 'n3_free', x: 550, y: 85, w: 140, h: 40, text: "✅ Du bist frei", bg: "rgba(0,157,108,0.12)", border: "#00c88c", textColor: "#00c88c" },
4616
- { id: 'n4_agpl', x: 510, y: 320, w: 180, h: 50, text: "Wird es als AGPLv3\nOpen Source veröffentlicht?", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4617
- { id: 'n5_yes', x: 760, y: 220, w: 220, h: 50, text: "✅ Du bist frei\n(Name & Github Repo nötig)", bg: "rgba(0,157,108,0.12)", border: "#00c88c", textColor: "#00c88c" },
4618
- { id: 'n6_no', x: 760, y: 400, w: 140, h: 40, text: "Was ist der Zweck?", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4619
- { id: 'n7_sell', x: 960, y: 340, w: 160, h: 50, text: "❌ Unmöglich\n(AGPLv3-Verletzung)", bg: "rgba(248,81,73,0.12)", border: "#f85149", textColor: "#f85149" },
4620
- { id: 'n8_corp', x: 960, y: 440, w: 180, h: 50, text: "💼 Kommerzielle Dual-Lizenz\n(Artilingo Kontakt)", bg: "rgba(227,179,65,0.12)", border: "#e3b341", textColor: "#e3b341" }
4305
+ { id: 'n1', x: 20, y: 220, w: 170, h: 50, text: "Proje Nerede Çalışacak?", bg: "#1c2128", border: "#58a6ff", textColor: "#e6edf3" },
4306
+ { id: 'n2_local', x: 250, y: 80, w: 220, h: 50, text: "Sadece Localhost / Bireysel\n(Dış Bağlantısı Yok)", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4307
+ { id: 'n2_net', x: 250, y: 320, w: 200, h: 50, text: "Ağa / İnternete Açık\n(SaaS, İntranet, Web)", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4308
+ { id: 'n3_free', x: 550, y: 85, w: 140, h: 40, text: "✅ Özgürsün", bg: "rgba(0,157,108,0.12)", border: "#00c88c", textColor: "#00c88c" },
4309
+ { id: 'n4_agpl', x: 510, y: 320, w: 180, h: 50, text: "AGPLv3 Açık Kaynak\nYayınlanacak Mı?", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4310
+ { id: 'n5_yes', x: 760, y: 220, w: 220, h: 50, text: "✅ Özgürsün\n(İsim & Github Reposu Şart)", bg: "rgba(0,157,108,0.12)", border: "#00c88c", textColor: "#00c88c" },
4311
+ { id: 'n6_no', x: 760, y: 400, w: 140, h: 40, text: "Amacı Nedir?", bg: "#1c2128", border: "#30363d", textColor: "#e6edf3" },
4312
+ { id: 'n7_sell', x: 960, y: 340, w: 160, h: 50, text: "❌ İmkansız\n(AGPLv3 İhlali)", bg: "rgba(248,81,73,0.12)", border: "#f85149", textColor: "#f85149" },
4313
+ { id: 'n8_corp', x: 960, y: 440, w: 180, h: 50, text: "💼 Ticari Çift-Lisans\n(Artilingo İletişim)", bg: "rgba(227,179,65,0.12)", border: "#e3b341", textColor: "#e3b341" }
4621
4314
  ];
4622
-
4623
4315
  ctx.fillStyle = "#0d1117";
4624
4316
  ctx.fillRect(0, 0, cw, ch);
4625
-
4626
4317
  drawPath([{x:190, y:245}, {x:220, y:245}, {x:220, y:105}, {x:250, y:105}], "#30363d");
4627
4318
  drawPath([{x:190, y:245}, {x:220, y:245}, {x:220, y:345}, {x:250, y:345}], "#30363d");
4628
-
4629
4319
  drawLine(470, 105, 550, 105, "#30363d");
4630
4320
  drawLine(450, 345, 510, 345, "#30363d");
4631
-
4632
4321
  drawPath([{x:690, y:345}, {x:725, y:345}, {x:725, y:245}, {x:760, y:245}], "#30363d");
4633
- drawText("Ja", 740, 235, "#00c88c", "12px Inter");
4634
-
4322
+ drawText("Evet", 740, 235, "#00c88c", "12px Inter");
4635
4323
  drawPath([{x:690, y:345}, {x:725, y:345}, {x:725, y:420}, {x:760, y:420}], "#30363d");
4636
- drawText("Nein", 740, 410, "#f85149", "12px Inter");
4637
-
4324
+ drawText("Hayır", 740, 410, "#f85149", "12px Inter");
4638
4325
  drawPath([{x:900, y:420}, {x:930, y:420}, {x:930, y:365}, {x:960, y:365}], "#30363d");
4639
- drawText("Verkaufen/Verteilen", 945, 355, "#f85149", "11px Inter");
4640
-
4326
+ drawText("Satmak/Dağıtmak", 945, 355, "#f85149", "11px Inter");
4641
4327
  drawPath([{x:900, y:420}, {x:930, y:420}, {x:930, y:465}, {x:960, y:465}], "#30363d");
4642
- drawText("Eigenes Projekt (SaaS)", 945, 455, "#e3b341", "11px Inter");
4643
-
4328
+ drawText("Kendi Projem (SaaS)", 945, 455, "#e3b341", "11px Inter");
4644
4329
  nodes.forEach(n => {
4645
4330
  drawRoundedRect(n.x, n.y, n.w, n.h, 6, n.bg, n.border);
4646
4331
  const lines = n.text.split('\n');
@@ -4653,14 +4338,10 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4653
4338
  });
4654
4339
  }
4655
4340
  </script>
4656
-
4657
- <a href="../../public/index.html" class="btn-back-home" style="position: fixed; bottom: 20px; left: 20px; z-index: 9999; background: var(--surface, #111); color: var(--text-primary, #fff); border: 1px solid var(--border, #333); padding: 10px 15px; border-radius: 8px; text-decoration: none; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); transition: all 0.2s;">
4658
- <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
4659
- Home
4660
- </a>
4661
- <style>
4341
+ <a class="btn-back-home" href="../../public/index.html" style="position: fixed; bottom: 20px; left: 20px; z-index: 9999; background: var(--surface, #111); color: var(--text-primary, #fff); border: 1px solid var(--border, #333); padding: 10px 15px; border-radius: 8px; text-decoration: none; font-size: 14px; font-weight: 500; display: flex; align-items: center; gap: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.5); transition: all 0.2s;">
4342
+ <svg fill="none" height="16" stroke="currentColor" stroke-width="2" viewbox="0 0 24 24" width="16"><path d="M19 12H5M12 19l-7-7 7-7"></path></svg>Heim</a>
4343
+ <style>
4662
4344
  .btn-back-home:hover { border-color: var(--accent, #00E599) !important; color: var(--accent, #00E599) !important; transform: translateY(-2px); }
4663
4345
  </style>
4664
-
4665
4346
  </body>
4666
4347
  </html>