@artilingo/artiframe-cli 2.0.4 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/LICENSE +660 -660
  2. package/bin/artiframe.js +0 -0
  3. package/bin/artiframe.php +0 -0
  4. package/core-stubs/app/ApiAuthControl.php +76 -0
  5. package/core-stubs/app/ApiControl.php +81 -35
  6. package/core-stubs/app/AuthControl.php +39 -0
  7. package/core-stubs/app/Database.php +36 -35
  8. package/core-stubs/app/DotEnv.php +19 -1
  9. package/core-stubs/app/ViewControl.php +47 -1
  10. package/core-stubs/bin/SQLMethod.php +261 -0
  11. package/core-stubs/bin/SystemMethod.php +115 -74
  12. package/core-stubs/bin/ViewMethod.php +19 -5
  13. package/core-stubs/docs/de.html +4325 -4347
  14. package/core-stubs/docs/en.html +4325 -4347
  15. package/core-stubs/docs/es.html +4325 -4347
  16. package/core-stubs/docs/fr.html +4325 -4347
  17. package/core-stubs/docs/tr.html +117 -46
  18. package/core-stubs/public/403.php +52 -0
  19. package/core-stubs/public/assets/css/components/header.css +174 -0
  20. package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
  21. package/core-stubs/public/assets/css/components/sidebar.css +184 -0
  22. package/core-stubs/public/assets/css/root/app.css +975 -38
  23. package/core-stubs/public/assets/css/root/root.css +64 -0
  24. package/core-stubs/public/assets/js/components/header.js +380 -0
  25. package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
  26. package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
  27. package/core-stubs/public/assets/js/root/app.js +1870 -0
  28. package/core-stubs/public/includes/footer.php +4 -5
  29. package/core-stubs/public/includes/head-auth.php +65 -0
  30. package/core-stubs/public/includes/head.php +56 -17
  31. package/core-stubs/public/includes/header.php +135 -1
  32. package/core-stubs/public/includes/mobilenav.php +75 -3
  33. package/core-stubs/public/includes/sidebar.php +186 -1
  34. package/core-stubs/public/includes/theme-modal.php +1 -0
  35. package/db-studio/debug.log +3 -0
  36. package/db-studio/index.html +1755 -0
  37. package/db-studio/launcher.html +102 -0
  38. package/db-studio/launcher.js +180 -0
  39. package/db-studio/logo.svg +22 -0
  40. package/db-studio/main.js +568 -0
  41. package/db-studio/package-lock.json +1034 -0
  42. package/db-studio/package.json +16 -0
  43. package/db-studio/preload.js +29 -0
  44. package/devops-studio/api-inspector.js +222 -0
  45. package/devops-studio/index.html +1892 -0
  46. package/devops-studio/logo.svg +22 -0
  47. package/devops-studio/main.js +67 -0
  48. package/devops-studio/make-wizard.js +635 -0
  49. package/devops-studio/package-lock.json +871 -0
  50. package/devops-studio/package.json +12 -0
  51. package/package.json +5 -2
  52. package/scripts/postinstall.js +44 -8
  53. package/server-studio/.json-404-guard +1 -0
  54. package/server-studio/index.html +283 -0
  55. package/server-studio/logo.svg +22 -0
  56. package/server-studio/main.js +133 -0
  57. package/server-studio/package-lock.json +1179 -0
  58. package/server-studio/package.json +15 -0
  59. package/server-studio/router.php +99 -0
  60. package/src/App.php +29 -0
  61. package/src/Commands/AddCommand.php +26 -9
  62. package/src/Commands/DbExportCommand.php +131 -0
  63. package/src/Commands/DbStartCommand.php +46 -0
  64. package/src/Commands/DevopsCommand.php +35 -0
  65. package/src/Commands/GoCommand.php +48 -48
  66. package/src/Commands/ListCommand.php +68 -68
  67. package/src/Commands/MakeApiCommand.php +6 -1
  68. package/src/Commands/MakeViewCommand.php +25 -2
  69. package/src/Commands/NewProjectCommand.php +16 -11
  70. package/src/Commands/OptimizeCommand.php +61 -0
  71. package/src/Commands/RemoveCommand.php +35 -7
  72. package/src/Commands/ServeCommand.php +46 -91
  73. package/src/Commands/ShowCommand.php +24 -24
  74. package/src/Commands/UpgradeCommand.php +39 -10
  75. package/stubs/make/api-switch-case.stub +1 -1
  76. package/stubs/make/auth-api-standart.stub +20 -0
  77. package/stubs/make/auth-api-switch-case.stub +38 -0
  78. package/stubs/make/auth-view.stub +26 -0
  79. package/stubs/make/class.stub +10 -2
  80. package/stubs/make/view.stub +3 -0
  81. package/stubs/service/image.stub +334 -334
  82. package/stubs/service/iyzico.stub +637 -637
  83. package/stubs/service/jwt.stub +312 -312
  84. package/stubs/service/phpmailer.stub +143 -143
  85. package/stubs/service/pusher.stub +232 -232
  86. package/stubs/service/qrcode.stub +169 -169
  87. package/stubs/service/redis.stub +361 -361
  88. package/stubs/service/s3.stub +377 -377
  89. package/stubs/service/stripe.stub +526 -526
  90. package/stubs/service/twilio.stub +361 -361
@@ -313,7 +313,7 @@
313
313
  <div class="sb-subcat">Sanitize & Validate</div>
314
314
  <a href="#sh-sanitizeint">sanitizeInt()</a>
315
315
  <a href="#sh-sanitizefloat">sanitizeFloat()</a>
316
- <a href="#sh-sanitizestring">sanitizeString()</a>
316
+ <a href="#sh-sanitizestring">stripHtml()</a>
317
317
  <a href="#sh-sanitizeemail">sanitizeEmail()</a>
318
318
  <a href="#sh-verifyemail">verifyEmail()</a>
319
319
  <div class="sb-subcat">HTTP Request</div>
@@ -331,13 +331,16 @@
331
331
  <a href="#sh-slugify">slugify()</a>
332
332
  <a href="#sh-arrayonly">arrayOnly()</a>
333
333
  <div class="sb-subcat">ID Generation & Utilities</div>
334
- <a href="#sh-byteid">byteId()</a>
335
- <a href="#sh-makeid">makeId()</a>
334
+ <a href="#sh-byteid">generateBinaryId()</a>
335
+ <a href="#sh-makeid">generateStringId()</a>
336
336
  <a href="#sh-formatid">formatId()</a>
337
337
  <a href="#sh-intid">intId()</a>
338
338
  <a href="#sh-bigintid">bigintId()</a>
339
- <a href="#sh-stringer">stringer()</a>
339
+
340
340
  <a href="#sh-otpcoder">OTP Coder</a>
341
+
342
+ <div class="sb-cat">Veritabanı</div>
343
+ <a href="#sh-sqlmethod">Mini-ORM & SQL</a>
341
344
  <div class="sb-cat">API Güvenliği</div>
342
345
  <a href="#api-methods">HTTP Metod Kontrolü</a>
343
346
  <a href="#api-cors">CORS</a>
@@ -485,8 +488,10 @@ artiframe&gt; </code></pre>
485
488
  <div class="tree">
486
489
  <span class="dir">proje-adi/</span>
487
490
  ├── <span class="dir">app/</span> <span class="note"># Altyapı katmanı</span>
488
- │ ├── <span class="file">ViewControl.php</span> <span class="note"># View (HTML sayfa) bootstrapper'ı</span>
489
- │ ├── <span class="file">ApiControl.php</span> <span class="note"># API endpoint bootstrapper'ı</span>
491
+ │ ├── <span class="file">ViewControl.php</span> <span class="note"># Standart View bootstrapper'ı</span>
492
+ │ ├── <span class="file">AuthControl.php</span> <span class="note"># Auth/Giriş View bootstrapper'ı</span>
493
+ │ ├── <span class="file">ApiControl.php</span> <span class="note"># Standart API endpoint bootstrapper'ı</span>
494
+ │ ├── <span class="file">ApiAuthControl.php</span> <span class="note"># Auth API endpoint bootstrapper'ı</span>
490
495
  │ ├── <span class="file">Database.php</span> <span class="note"># PDO tabanlı veritabanı bağlantısı</span>
491
496
  │ └── <span class="file">DotEnv.php</span> <span class="note"># .env okuyucu</span>
492
497
 
@@ -561,7 +566,7 @@ $_GET['param2'] = '15';</code></pre>
561
566
  <p>Yukarıdaki yeni yapıda ilgili sayfada verilere erişmek oldukça basittir:</p>
562
567
  <pre><code><span class="cm">// public/user.php içerisinde:</span>
563
568
  $userId = sanitizeInt($_GET['param1']); <span class="cm">// 123456 (veya $_GET['id'])</span>
564
- $token = sanitizeString($_GET['param2']); <span class="cm">// 123j54m23k</span></code></pre>
569
+ $token = stripHtml($_GET['param2']); <span class="cm">// 123j54m23k</span></code></pre>
565
570
  </div>
566
571
 
567
572
  <h3>2. Global Yardımcı Fonksiyonlar (Helpers)</h3>
@@ -615,7 +620,8 @@ axios.get('/api/user/get').catch(error => {
615
620
  <p>ArtiFrame, iki tamamen bağımsız bootstrapper kullanır. Bu mimari, <strong>HTML header sorunlarını ve güvenlik açıklarını</strong> kökten önler.</p>
616
621
  <div class="grid-2">
617
622
  <div class="card highlight">
618
- <h3><span class="badge b-view">View</span> ViewControl.php</h3>
623
+ <h3><span class="badge b-view">View</span> ViewControl.php / AuthControl.php</h3>
624
+ <p><strong>Zeka Eklentisi:</strong> CLI aracı `auth/` klasörü altına bir View oluşturduğunuzda otomatik olarak `AuthControl.php` (misafir kalkanı) çağırır.</p>
619
625
  <p>HTML sayfaları (view dosyaları) için kullanılır. Session başlatır, <code class="ic">ViewMethod</code>'u yükler.</p>
620
626
  <pre><code><span class="cm">// public/profil.php — EN ÜSTE, HTML basmadan önce</span>
621
627
  <span class="kw">&lt;?php</span>
@@ -627,7 +633,8 @@ axios.get('/api/user/get').catch(error => {
627
633
  ...</code></pre>
628
634
  </div>
629
635
  <div class="card highlight">
630
- <h3><span class="badge b-api">API</span> ApiControl.php</h3>
636
+ <h3><span class="badge b-api">API</span> ApiControl.php / ApiAuthControl.php</h3>
637
+ <p><strong>Zeka Eklentisi:</strong> `auth/` klasörü altına bir API oluşturduğunuzda, oturum duvarı olmayan ancak kaba kuvvet (Rate Limit) korumalı `ApiAuthControl.php` kalkanı otomatik entegre edilir.</p>
631
638
  <p>API endpoint dosyaları için kullanılır. JSON header'ı ayarlar, HTTP metod kontrolü yapar, <code class="ic">SystemMethod</code>'u yükler.</p>
632
639
  <pre><code><span class="cm">// public/api/kullanici/getir.php</span>
633
640
  <span class="kw">&lt;?php</span>
@@ -672,7 +679,7 @@ html[data-theme="default"][data-mode="light"] {
672
679
  </div>
673
680
  <div class="card">
674
681
  <h3>Kural 3: Güvenli Veri Akışı</h3>
675
- <p>Veritabanından gelen her veri, DOM'a basılmadan önce <code class="ic">display()</code> ile sarılır. API'ye gelen her veri, işlenmeden önce <code class="ic">sanitizeString()</code> veya <code class="ic">sanitizeInt()</code> ile temizlenir.</p>
682
+ <p>Veritabanından gelen her veri, DOM'a basılmadan önce <code class="ic">display()</code> ile sarılır. API'ye gelen her veri, işlenmeden önce <code class="ic">stripHtml()</code> veya <code class="ic">sanitizeInt()</code> ile temizlenir.</p>
676
683
  </div>
677
684
  <div class="card">
678
685
  <h3>Kural 4: APP_ENV ile Hata Yönetimi</h3>
@@ -810,7 +817,7 @@ proje-adi/
810
817
  <span class="var">$allowedMethods</span> = [<span class="st">'POST'</span>];
811
818
  <span class="fn">require_once</span> <span class="var">$_SERVER</span>[<span class="st">'DOCUMENT_ROOT'</span>] . <span class="st">'/../app/ApiControl.php'</span>;
812
819
  <span class="kw">use</span> Bin\SystemMethod;
813
- <span class="var">$action</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'action'</span>] ?? <span class="st">''</span>);
820
+ <span class="var">$action</span> = <span class="fn">stripHtml</span>(<span class="var">$_POST</span>[<span class="st">'action'</span>] ?? <span class="st">''</span>);
814
821
  <span class="kw">switch</span> (<span class="var">$action</span>) {
815
822
  <span class="kw">case</span> <span class="st">'create'</span>:
816
823
  <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>);
@@ -3977,10 +3984,10 @@ if ($response['status'] === 'success') {
3977
3984
  <pre><code><span class="var">$fiyat</span> = <span class="fn">sanitizeFloat</span>(<span class="var">$_POST</span>[<span class="st">'fiyat'</span>]);</code></pre>
3978
3985
  </section>
3979
3986
  <section id="sh-sanitizestring">
3980
- <h2>System Helpers — <code>sanitizeString()</code> <span class="tag b-api">SystemMethod</span></h2>
3981
- <span class="ret">string sanitizeString(string $value)</span>
3987
+ <h2>System Helpers — <code>stripHtml()</code> <span class="tag b-api">SystemMethod</span></h2>
3988
+ <span class="ret">string stripHtml(string $value)</span>
3982
3989
  <p>XSS ve türevi saldırıları engellemek için tüm <strong>HTML ve PHP etiketlerini (<code>&lt;script&gt;</code>, <code>&lt;iframe&gt;</code> vb.) yok eder</strong>. Veritabanına String kaydetmeden önce mutlaka kullanılmalıdır.</p>
3983
- <pre><code><span class="var">$isim</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'isim'</span>]);</code></pre>
3990
+ <pre><code><span class="var">$isim</span> = <span class="fn">stripHtml</span>(<span class="var">$_POST</span>[<span class="st">'isim'</span>]);</code></pre>
3984
3991
  </section>
3985
3992
  <section id="sh-sanitizeemail">
3986
3993
  <h2>System Helpers — <code>sanitizeEmail()</code> <span class="tag b-api">SystemMethod</span></h2>
@@ -4076,7 +4083,7 @@ if ($response['status'] === 'success') {
4076
4083
  <span class="cm">// ID, rol gibi dışarıdan manipüle edilmiş değerler otomatik yok edilir.</span></code></pre>
4077
4084
  </section>
4078
4085
  <section id="sh-byteid">
4079
- <h2>System Helpers - <code>byteId()</code> <span class="tag b-api">SystemMethod</span></h2>
4086
+ <h2>System Helpers - <code>generateBinaryId()</code> <span class="tag b-api">SystemMethod</span></h2>
4080
4087
  <div class="info-box">
4081
4088
  Native, yüksek performanslı ve sıralı (Time-ordered) raw 16-byte <strong>UUIDv7</strong> üretir.
4082
4089
  </div>
@@ -4086,13 +4093,13 @@ if ($response['status'] === 'success') {
4086
4093
  <span class="code-lang">PHP</span>
4087
4094
  </div>
4088
4095
  <pre><code><span class="kw">use</span> Bin\SystemMethod;
4089
- <span class="var">$rawId</span> = SystemMethod::<span class="fn">byteId</span>();
4090
- <span class="cm">// Veya global helper: byteId();</span>
4096
+ <span class="var">$rawId</span> = SystemMethod::<span class="fn">generateBinaryId</span>();
4097
+ <span class="cm">// Veya global helper: generateBinaryId();</span>
4091
4098
  <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>
4092
4099
  </div>
4093
4100
  </section>
4094
4101
  <section id="sh-makeid">
4095
- <h2>System Helpers - <code>makeId()</code> <span class="tag b-api">SystemMethod</span></h2>
4102
+ <h2>System Helpers - <code>generateStringId()</code> <span class="tag b-api">SystemMethod</span></h2>
4096
4103
  <div class="info-box">
4097
4104
  Native, standart 36 karakterlik <strong>UUIDv7</strong> string'i üretir.
4098
4105
  </div>
@@ -4102,7 +4109,7 @@ if ($response['status'] === 'success') {
4102
4109
  <span class="code-lang">PHP</span>
4103
4110
  </div>
4104
4111
  <pre><code><span class="kw">use</span> Bin\SystemMethod;
4105
- <span class="var">$stringId</span> = SystemMethod::<span class="fn">makeId</span>();
4112
+ <span class="var">$stringId</span> = SystemMethod::<span class="fn">generateStringId</span>();
4106
4113
  <span class="cm">// Örnek Çıktı: 0190ed84-3f12-7a91-8bc4-91823741abcd</span></code></pre>
4107
4114
  </div>
4108
4115
  </section>
@@ -4150,31 +4157,7 @@ if ($response['status'] === 'success') {
4150
4157
  <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>
4151
4158
  </div>
4152
4159
  </section>
4153
- <section id="sh-stringer">
4154
- <h2>System Helpers - <code>stringer()</code> <span class="tag b-api">SystemMethod</span></h2>
4155
- <div class="info-box">
4156
- Değerleri Javascript'in devasa sayı (BIGINT) duyarsızlığına karşı güvenli bir şekilde string'e sarmalar.
4157
- </div>
4158
- <p>15 haneden büyük sayısal (BigInt vb.) değişkenleri View katmanında DOM'a basarken Javascript'in yuvarlama hatalarından (Precision Loss) korur.</p>
4159
- <div class="code-block">
4160
- <div class="code-header">
4161
- <span class="code-lang">HTML / PHP</span>
4162
- </div>
4163
- <pre><code><span class="cm">&lt;!-- JS'in bozmasını engellemek için stringer ile sarmalıyoruz --&gt;</span>
4164
- &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>
4165
- </div>
4166
- <section id="sh-otpcoder">
4167
- <h2>System Helpers - OTP Coder <span class="tag b-api">SystemMethod</span></h2>
4168
- <div class="info-box">Rastgele, kriptografik olarak güvenli Doğrulama Kodları (OTP) üretir.</div>
4169
- <div class="code-block">
4170
- <pre><code><span class="cm">// 6 haneli rastgele sayı</span>
4171
- <span class="var">$code</span> = <span class="fn">otpInt</span>(<span class="nu">6</span>); <span class="cm">// 482910</span>
4172
- <span class="cm">// 8 haneli sadece harf ('c': küçük, 'C': büyük, 'cC': karışık)</span>
4173
- <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>
4174
- <span class="cm">// 6 haneli harf+sayı (Alphanumeric)</span>
4175
- <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>
4176
- </div>
4177
- </section>
4160
+
4178
4161
  </section>
4179
4162
  <!-- ====== API GÜVENLİĞİ ====== -->
4180
4163
  <section id="api-methods">
@@ -4271,9 +4254,9 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4271
4254
  <span class="fn">jsonResponse</span>([<span class="st">'error'</span> =&gt; <span class="st">'Geçersiz token.'</span>], <span class="nu">403</span>);
4272
4255
  }
4273
4256
  <span class="cm">// 2. Veriyi Temizle</span>
4274
- <span class="var">$ad</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'ad'</span>] ?? <span class="st">''</span>);
4257
+ <span class="var">$ad</span> = <span class="fn">stripHtml</span>(<span class="var">$_POST</span>[<span class="st">'ad'</span>] ?? <span class="st">''</span>);
4275
4258
  <span class="var">$eposta</span> = <span class="fn">sanitizeEmail</span>(<span class="var">$_POST</span>[<span class="st">'eposta'</span>] ?? <span class="st">''</span>);
4276
- <span class="var">$mesaj</span> = <span class="fn">sanitizeString</span>(<span class="var">$_POST</span>[<span class="st">'mesaj'</span>] ?? <span class="st">''</span>);
4259
+ <span class="var">$mesaj</span> = <span class="fn">stripHtml</span>(<span class="var">$_POST</span>[<span class="st">'mesaj'</span>] ?? <span class="st">''</span>);
4277
4260
  <span class="cm">// 3. İş Mantığı (Mail gönder, DB'ye kaydet vb.)</span>
4278
4261
  <span class="cm">// ...</span>
4279
4262
  <span class="cm">// 4. Yanıt Ver</span>
@@ -4284,6 +4267,94 @@ echo json_encode([<span class="st">'error'</span> =&gt; <span class="st">'Çok f
4284
4267
  <div class="alert a-success">
4285
4268
  <strong>✅ Tamamlandı!</strong> XSS koruması, CSRF doğrulama, HTTP metod kısıtlaması ve data-js mimarisi ile tam güvenli ve standart uyumlu bir form akışı oluşturdunuz.
4286
4269
  </div>
4270
+ </section>
4271
+ <section id="sh-sqlmethod">
4272
+ <h2>Mini-ORM (Veritabanı Kısayolları) <span class="tag b-api">SQLMethod</span></h2>
4273
+ <p>Geliştiricilerin saatlerce SQL sorgusu yazmasını engelleyen, güvenlik odaklı (PDO Bind) Düz-Parametre mimarisidir. SQL Injection riski <strong>tamamen sıfırlanmıştır</strong>.</p>
4274
+ <p>Aşağıda "Bunu nasıl kullanırım?" sorunuza cevap verecek, her senaryo için pratik kod parçacıklarını bulabilirsiniz.</p>
4275
+
4276
+ <br>
4277
+ <h4>1. Veri Çekme İşlemleri (Select)</h4>
4278
+
4279
+ <h5><span class="badge b-view">dbGet()</span> Sadece Bir Kayıt Çekmek</h5>
4280
+ <p>Sadece bir üyeyi veya yazıyı okumak istediğinizde kullanılır. Arka planda sorguya otomatik olarak <code>LIMIT 1</code> eklenir.</p>
4281
+ <pre><code><span class="cm">// Sadece ID'ye göre çekmek</span>
4282
+ <span class="var">$uye</span> = <span class="fn">dbGet</span>(<span class="st">'uyeler'</span>, [<span class="st">'id'</span> => <span class="var">$id</span>]);
4283
+ <span class="keyword">echo</span> <span class="var">$uye</span>[<span class="st">'ad'</span>];
4284
+
4285
+ <span class="cm">// En son kayıt olan aktif üyeyi getirmek</span>
4286
+ <span class="var">$sonUye</span> = <span class="fn">dbGet</span>(<span class="st">'uyeler'</span>, [<span class="st">'durum'</span> => <span class="nu">1</span>], <span class="st">'id DESC'</span>);</code></pre>
4287
+
4288
+ <h5><span class="badge b-view">dbList()</span> Birden Fazla Kayıt Çekmek (Dizi Döner)</h5>
4289
+ <p>Listeleme, döngü (foreach) kurma işlemleri içindir. Dizi parametresi (Array) sayesinde "Eşittir", "Büyüktür", "LIKE" gibi tüm operatörleri destekler.</p>
4290
+ <pre><code><span class="cm">// Tablodaki tüm veriyi çek (Koşulsuz)</span>
4291
+ <span class="var">$herkes</span> = <span class="fn">dbList</span>(<span class="st">'uyeler'</span>);
4292
+
4293
+ <span class="cm">// Belirli koşullara uyanları çek (Örn: Durumu 1 olan ilk 20 kişi)</span>
4294
+ <span class="var">$aktifler</span> = <span class="fn">dbList</span>(<span class="st">'uyeler'</span>, [<span class="st">'durum'</span> => <span class="nu">1</span>], <span class="st">'tarih DESC'</span>, <span class="nu">20</span>);
4295
+
4296
+ <span class="cm">// ÖZEL OPERATÖRLERLE ARAMA (Boşluktan sonrasına operatörü yazın)</span>
4297
+ <span class="cm">// Örn: Yaşı 18'den büyük ve adı 'Ali' ile başlayanlar</span>
4298
+ <span class="var">$yetiskinler</span> = <span class="fn">dbList</span>(<span class="st">'uyeler'</span>, [
4299
+ <span class="st">'yas >'</span> => <span class="nu">18</span>,
4300
+ <span class="st">'isim LIKE'</span> => <span class="st">'%Ali%'</span>
4301
+ ]);</code></pre>
4302
+
4303
+ <h5><span class="badge b-view">dbCount()</span> Sadece Sayı Döndürmek</h5>
4304
+ <p>Tabloda kaç adet kayıt olduğunu, Integer (Tam Sayı) olarak döner.</p>
4305
+ <pre><code><span class="var">$toplam</span> = <span class="fn">dbCount</span>(<span class="st">'uyeler'</span>, [<span class="st">'durum'</span> => <span class="nu">1</span>, <span class="st">'rol'</span> => <span class="st">'mezun'</span>]);
4306
+ <span class="keyword">echo</span> <span class="st">"Toplam Mezun: "</span> . <span class="var">$toplam</span>;</code></pre>
4307
+
4308
+
4309
+ <br>
4310
+ <h4>2. Veri İşleme (Insert, Update, Delete)</h4>
4311
+
4312
+ <h5><span class="badge b-view">dbInsert()</span> Yeni Kayıt Eklemek</h5>
4313
+ <p>Gelen dizi anahtarlarını sütun adı, değerlerini ise güvenlikli parametre olarak kullanır ve <strong>son eklenen ID'yi</strong> döner.</p>
4314
+ <pre><code><span class="cm">// Formdan gelenleri direkt içeri atma</span>
4315
+ <span class="var">$yeniId</span> = <span class="fn">dbInsert</span>(<span class="st">'uyeler'</span>, [
4316
+ <span class="st">'ad'</span> => <span class="fn">stripHtml</span>(<span class="var">$_POST</span>[<span class="st">'ad'</span>]),
4317
+ <span class="st">'email'</span> => <span class="fn">sanitizeEmail</span>(<span class="var">$_POST</span>[<span class="st">'email'</span>]),
4318
+ <span class="st">'yas'</span> => <span class="fn">sanitizeInt</span>(<span class="var">$_POST</span>[<span class="st">'yas'</span>])
4319
+ ]);
4320
+ <span class="keyword">echo</span> <span class="st">"Yeni Kayıt ID'si: "</span> . <span class="var">$yeniId</span>;</code></pre>
4321
+
4322
+ <h5><span class="badge b-view">dbUpdate()</span> Kayıt Güncellemek</h5>
4323
+ <p>2. Parametre güncellenecek verilerdir, 3. Parametre ise WHERE şartıdır. Kaç satırın güncellendiğini döner.</p>
4324
+ <pre><code><span class="cm">// ID'si $id olan kullanıcının durumunu 2 yap.</span>
4325
+ <span class="var">$etkilenenSatir</span> = <span class="fn">dbUpdate</span>(<span class="st">'uyeler'</span>,
4326
+ [<span class="st">'durum'</span> => <span class="nu">2</span>, <span class="st">'son_giris'</span> => <span class="fn">time</span>()], <span class="cm">// Ne değişecek?</span>
4327
+ [<span class="st">'id'</span> => <span class="var">$id</span>] <span class="cm">// Kime uygulanacak? (ŞART)</span>
4328
+ );</code></pre>
4329
+
4330
+ <h5><span class="badge b-view">dbDelete()</span> Kayıt Silmek</h5>
4331
+ <p>Tablo adı ve silinecek şartı yazmanız yeterlidir. Kaç satırın silindiğini döner.</p>
4332
+ <pre><code><span class="cm">// ID'si 5 olan üyeyi sil</span>
4333
+ <span class="fn">dbDelete</span>(<span class="st">'uyeler'</span>, [<span class="st">'id'</span> => <span class="nu">5</span>]);
4334
+
4335
+ <span class="cm">// Durumu 0 olan bütün yorumları sil</span>
4336
+ <span class="fn">dbDelete</span>(<span class="st">'yorumlar'</span>, [<span class="st">'durum'</span> => <span class="nu">0</span>]);</code></pre>
4337
+
4338
+ <div class="alert a-danger">
4339
+ <strong>💣 Bomba Koruması:</strong> Yanlışlıkla tüm veritabanını güncellemeyi veya silmeyi engellemek için, <code>dbUpdate</code> ve <code>dbDelete</code> fonksiyonlarında <strong>WHERE dizisi zorunludur!</strong> Eğer şart dizisini <code>[]</code> boş bırakırsanız sistem <code>InvalidArgumentException</code> fırlatarak çöker ve işlemi reddeder. Tüm tabloyu sıfırlamak istiyorsanız, bilinçli olarak <code>dbExecute()</code> ile ham SQL yazmalısınız.
4340
+ </div>
4341
+
4342
+ <br>
4343
+ <h4>3. Gelişmiş Raw (Ham) Sorgular</h4>
4344
+
4345
+ <h5><span class="badge b-view">dbExecute() & dbRows()</span> JOIN ve Kompleks Sorgular</h5>
4346
+ <p>Düz-Parametre mimarisine (Mini-ORM'e) sığmayan, birden fazla tablonun (JOIN) birleştiği, karmaşık AND/OR gruplarının olduğu veya Sub-Query (Alt Sorgu) barındıran tüm ham sorgularınız için tasarlanmıştır. Parametreleri <code>?</code> ile bind edip ikinci değişkende dizersiniz.</p>
4347
+ <pre><code><span class="cm">// SELECT işlemleri için dbRows (çoklu) veya dbRow (tekli) kullanın</span>
4348
+ <span class="var">$ozelListe</span> = <span class="fn">dbRows</span>(<span class="st">"
4349
+ SELECT g.*, u.ad
4350
+ FROM gonderiler g
4351
+ LEFT JOIN uyeler u ON u.id = g.yazar_id
4352
+ WHERE g.durum = ? AND u.yas > ?
4353
+ "</span>, [<span class="nu">1</span>, <span class="nu">18</span>]);
4354
+
4355
+ <span class="cm">// INSERT, UPDATE, DELETE veya Tablo işlemleri için dbExecute kullanın</span>
4356
+ <span class="fn">dbExecute</span>(<span class="st">"UPDATE ayarlar SET tema = ? WHERE user_id IN (SELECT id FROM uyeler)"</span>, [<span class="st">'dark'</span>]);</code></pre>
4357
+
4287
4358
  </section>
4288
4359
  </main>
4289
4360
  <script>
@@ -0,0 +1,52 @@
1
+ <!DOCTYPE html>
2
+ <html lang="tr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>403 Yetkisiz Erişim</title>
7
+ <style>
8
+ body, html {
9
+ margin: 0;
10
+ padding: 0;
11
+ width: 100%;
12
+ height: 100%;
13
+ display: flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+ background-color: #0f172a;
17
+ color: #e2e8f0;
18
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
19
+ }
20
+ .content {
21
+ text-align: center;
22
+ background: rgba(30, 41, 59, 0.7);
23
+ padding: 40px;
24
+ border-radius: 12px;
25
+ border: 1px solid rgba(255, 255, 255, 0.1);
26
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
27
+ max-width: 500px;
28
+ width: 90%;
29
+ }
30
+ h1 { font-size: 3rem; margin: 0 0 10px 0; color: #f87171; }
31
+ p { font-size: 1.1rem; line-height: 1.5; margin-bottom: 25px; }
32
+ .btn-home {
33
+ display: inline-block;
34
+ padding: 12px 24px;
35
+ background: #3b82f6;
36
+ color: #fff;
37
+ text-decoration: none;
38
+ font-weight: 600;
39
+ border-radius: 6px;
40
+ transition: background 0.3s ease;
41
+ }
42
+ .btn-home:hover { background: #2563eb; }
43
+ </style>
44
+ </head>
45
+ <body>
46
+ <div class="content">
47
+ <h1>403</h1>
48
+ <p>Bu sayfaya erişim yetkiniz bulunmamaktadır.<br>Lütfen yöneticinizle iletişime geçin.</p>
49
+ <a href="/" class="btn-home">Anasayfaya Dön</a>
50
+ </div>
51
+ </body>
52
+ </html>
@@ -0,0 +1,174 @@
1
+ /* ==========================================================================
2
+ Header Component (Glassmorphism Floating Top-Right Bar)
3
+ ========================================================================== */
4
+
5
+ .app-header {
6
+ position: sticky;
7
+ top: 0;
8
+ width: 100%;
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: flex-end;
12
+ gap: 1rem;
13
+ padding: 0.75rem 2rem;
14
+ background: rgba(255, 255, 255, 0.4);
15
+ backdrop-filter: blur(24px);
16
+ -webkit-backdrop-filter: blur(24px);
17
+ border-bottom: 1px solid rgba(255, 255, 255, 0.6);
18
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.02);
19
+ z-index: 90;
20
+ }
21
+
22
+ [data-mode="dark"] .app-header {
23
+ background: rgba(255, 255, 255, 0.05);
24
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
25
+ box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
26
+ }
27
+
28
+ .header-action {
29
+ display: flex;
30
+ align-items: center;
31
+ justify-content: center;
32
+ width: 36px;
33
+ height: 36px;
34
+ border-radius: 50%;
35
+ color: var(--text-muted);
36
+ background: transparent;
37
+ border: none;
38
+ cursor: pointer;
39
+ transition: all 0.2s ease;
40
+ position: relative;
41
+ }
42
+
43
+ .header-action i {
44
+ font-size: 1.15rem;
45
+ color: currentColor;
46
+ }
47
+
48
+ .header-action:hover {
49
+ color: var(--brand-primary);
50
+ background: rgba(255, 255, 255, 0.5);
51
+ }
52
+ [data-mode="dark"] .header-action:hover {
53
+ background: rgba(255, 255, 255, 0.1);
54
+ }
55
+
56
+ .header-action .badge {
57
+ position: absolute;
58
+ top: -2px;
59
+ right: -2px;
60
+ width: 8px;
61
+ height: 8px;
62
+ background-color: var(--danger);
63
+ border-radius: 50%;
64
+ border: 2px solid var(--canvas-bg);
65
+ }
66
+
67
+ .header-avatar {
68
+ width: 36px;
69
+ height: 36px;
70
+ border-radius: 50%;
71
+ overflow: hidden;
72
+ cursor: pointer;
73
+ border: 2px solid transparent;
74
+ transition: border-color 0.2s ease;
75
+ }
76
+
77
+ .header-avatar img {
78
+ width: 100%;
79
+ height: 100%;
80
+ object-fit: cover;
81
+ }
82
+
83
+ .header-avatar:hover {
84
+ border-color: var(--brand-primary);
85
+ }
86
+
87
+ @media (max-width: 992px) {
88
+ .app-header {
89
+ padding: 0.75rem 1rem;
90
+ }
91
+ }
92
+
93
+ /* ==========================================================================
94
+ Header Avatar Dropdown (Sadece Mobil)
95
+ ========================================================================== */
96
+
97
+
98
+
99
+ .header-avatar-container {
100
+ position: relative;
101
+ display: flex;
102
+ align-items: center;
103
+ }
104
+
105
+ .profile-dropdown-menu {
106
+ position: absolute;
107
+ top: 130%;
108
+ right: 0;
109
+ width: 220px;
110
+ background: var(--card-bg);
111
+ border: 1px solid rgba(255,255,255,0.1);
112
+ border-radius: 16px;
113
+ box-shadow: 0 10px 30px rgba(0,0,0,0.15);
114
+ padding: 0.5rem 0;
115
+ opacity: 0;
116
+ visibility: hidden;
117
+ transform: translateY(10px);
118
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
119
+ z-index: 100;
120
+ }
121
+
122
+ [data-mode="dark"] .profile-dropdown-menu {
123
+ border: 1px solid rgba(255,255,255,0.05);
124
+ box-shadow: 0 10px 30px rgba(0,0,0,0.3);
125
+ }
126
+
127
+ .profile-dropdown-menu.show {
128
+ opacity: 1;
129
+ visibility: visible;
130
+ transform: translateY(0);
131
+ }
132
+
133
+ .profile-dropdown-menu .dropdown-item {
134
+ display: flex;
135
+ align-items: center;
136
+ gap: 12px;
137
+ padding: 0.75rem 1.5rem;
138
+ color: var(--text-main);
139
+ text-decoration: none;
140
+ transition: background 0.2s, color 0.2s;
141
+ font-weight: 500;
142
+ }
143
+
144
+ .profile-dropdown-menu .dropdown-item:hover {
145
+ background: rgba(169, 140, 250, 0.05);
146
+ color: var(--brand-primary);
147
+ }
148
+
149
+ .profile-dropdown-menu .dropdown-item i {
150
+ width: 20px;
151
+ text-align: center;
152
+ color: var(--text-muted);
153
+ transition: color 0.2s;
154
+ }
155
+
156
+ .profile-dropdown-menu .dropdown-item:hover i {
157
+ color: var(--brand-primary);
158
+ }
159
+
160
+ .profile-dropdown-menu .dropdown-divider {
161
+ margin: 0.5rem 0;
162
+ border: 0;
163
+ border-top: 1px solid rgba(128,128,128,0.1);
164
+ }
165
+
166
+ .profile-dropdown-menu .dropdown-item.text-danger {
167
+ color: var(--danger, #ff4d4f);
168
+ }
169
+ .profile-dropdown-menu .dropdown-item.text-danger:hover {
170
+ background: rgba(255, 77, 79, 0.05);
171
+ }
172
+ .profile-dropdown-menu .dropdown-item.text-danger i {
173
+ color: var(--danger, #ff4d4f);
174
+ }