@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.
- package/LICENSE +660 -660
- package/bin/artiframe.js +0 -0
- package/bin/artiframe.php +0 -0
- package/core-stubs/app/ApiAuthControl.php +76 -0
- package/core-stubs/app/ApiControl.php +81 -35
- package/core-stubs/app/AuthControl.php +39 -0
- package/core-stubs/app/Database.php +36 -35
- package/core-stubs/app/DotEnv.php +19 -1
- package/core-stubs/app/ViewControl.php +47 -1
- package/core-stubs/bin/SQLMethod.php +261 -0
- package/core-stubs/bin/SystemMethod.php +115 -74
- package/core-stubs/bin/ViewMethod.php +19 -5
- package/core-stubs/docs/de.html +4325 -4347
- package/core-stubs/docs/en.html +4325 -4347
- package/core-stubs/docs/es.html +4325 -4347
- package/core-stubs/docs/fr.html +4325 -4347
- package/core-stubs/docs/tr.html +117 -46
- package/core-stubs/public/403.php +52 -0
- package/core-stubs/public/assets/css/components/header.css +174 -0
- package/core-stubs/public/assets/css/components/mobilenav.css +198 -0
- package/core-stubs/public/assets/css/components/sidebar.css +184 -0
- package/core-stubs/public/assets/css/root/app.css +975 -38
- package/core-stubs/public/assets/css/root/root.css +64 -0
- package/core-stubs/public/assets/js/components/header.js +380 -0
- package/core-stubs/public/assets/js/components/mobilenav.js +97 -0
- package/core-stubs/public/assets/js/components/theme-modal.js +74 -0
- package/core-stubs/public/assets/js/root/app.js +1870 -0
- package/core-stubs/public/includes/footer.php +4 -5
- package/core-stubs/public/includes/head-auth.php +65 -0
- package/core-stubs/public/includes/head.php +56 -17
- package/core-stubs/public/includes/header.php +135 -1
- package/core-stubs/public/includes/mobilenav.php +75 -3
- package/core-stubs/public/includes/sidebar.php +186 -1
- package/core-stubs/public/includes/theme-modal.php +1 -0
- package/db-studio/debug.log +3 -0
- package/db-studio/index.html +1755 -0
- package/db-studio/launcher.html +102 -0
- package/db-studio/launcher.js +180 -0
- package/db-studio/logo.svg +22 -0
- package/db-studio/main.js +568 -0
- package/db-studio/package-lock.json +1034 -0
- package/db-studio/package.json +16 -0
- package/db-studio/preload.js +29 -0
- package/devops-studio/api-inspector.js +222 -0
- package/devops-studio/index.html +1892 -0
- package/devops-studio/logo.svg +22 -0
- package/devops-studio/main.js +67 -0
- package/devops-studio/make-wizard.js +635 -0
- package/devops-studio/package-lock.json +871 -0
- package/devops-studio/package.json +12 -0
- package/package.json +5 -2
- package/scripts/postinstall.js +44 -8
- package/server-studio/.json-404-guard +1 -0
- package/server-studio/index.html +283 -0
- package/server-studio/logo.svg +22 -0
- package/server-studio/main.js +133 -0
- package/server-studio/package-lock.json +1179 -0
- package/server-studio/package.json +15 -0
- package/server-studio/router.php +99 -0
- package/src/App.php +29 -0
- package/src/Commands/AddCommand.php +26 -9
- package/src/Commands/DbExportCommand.php +131 -0
- package/src/Commands/DbStartCommand.php +46 -0
- package/src/Commands/DevopsCommand.php +35 -0
- package/src/Commands/GoCommand.php +48 -48
- package/src/Commands/ListCommand.php +68 -68
- package/src/Commands/MakeApiCommand.php +6 -1
- package/src/Commands/MakeViewCommand.php +25 -2
- package/src/Commands/NewProjectCommand.php +16 -11
- package/src/Commands/OptimizeCommand.php +61 -0
- package/src/Commands/RemoveCommand.php +35 -7
- package/src/Commands/ServeCommand.php +46 -91
- package/src/Commands/ShowCommand.php +24 -24
- package/src/Commands/UpgradeCommand.php +39 -10
- package/stubs/make/api-switch-case.stub +1 -1
- package/stubs/make/auth-api-standart.stub +20 -0
- package/stubs/make/auth-api-switch-case.stub +38 -0
- package/stubs/make/auth-view.stub +26 -0
- package/stubs/make/class.stub +10 -2
- package/stubs/make/view.stub +3 -0
- package/stubs/service/image.stub +334 -334
- package/stubs/service/iyzico.stub +637 -637
- package/stubs/service/jwt.stub +312 -312
- package/stubs/service/phpmailer.stub +143 -143
- package/stubs/service/pusher.stub +232 -232
- package/stubs/service/qrcode.stub +169 -169
- package/stubs/service/redis.stub +361 -361
- package/stubs/service/s3.stub +377 -377
- package/stubs/service/stripe.stub +526 -526
- package/stubs/service/twilio.stub +361 -361
package/bin/artiframe.js
CHANGED
|
File without changes
|
package/bin/artiframe.php
CHANGED
|
File without changes
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* ArtiFrame Core Engine
|
|
4
|
+
*
|
|
5
|
+
* @package ArtiFrame
|
|
6
|
+
* @author Artilingo
|
|
7
|
+
* @license AGPLv3 (Attribution-ShareAlike Required)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
require_once __DIR__ . '/../vendor/autoload.php';
|
|
11
|
+
|
|
12
|
+
// 1. Ortam değişkenlerini yükle (.env)
|
|
13
|
+
\App\DotEnv::load(__DIR__ . '/../.env');
|
|
14
|
+
|
|
15
|
+
// 2. Uygulama sabitlerini yükle (APP_ENV, APP_VERSION)
|
|
16
|
+
require_once __DIR__ . '/../config/app-version.php';
|
|
17
|
+
|
|
18
|
+
// 3. Sadece API'ye özgü metodları yükle
|
|
19
|
+
require_once __DIR__ . '/../bin/SystemMethod.php';
|
|
20
|
+
|
|
21
|
+
// 4. API Konfigürasyonları (JSON Response Header vs.)
|
|
22
|
+
header('Content-Type: application/json; charset=utf-8');
|
|
23
|
+
|
|
24
|
+
// 5. İzin Verilen HTTP Metodlarının Kontrolü
|
|
25
|
+
$allowed = isset($allowedMethods) && is_array($allowedMethods) ? $allowedMethods : ['POST'];
|
|
26
|
+
$requestMethod = $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN';
|
|
27
|
+
|
|
28
|
+
if ($requestMethod === 'OPTIONS') {
|
|
29
|
+
http_response_code(200);
|
|
30
|
+
exit;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!in_array($requestMethod, $allowed)) {
|
|
34
|
+
http_response_code(405);
|
|
35
|
+
echo json_encode([
|
|
36
|
+
'status' => 'error',
|
|
37
|
+
'message' => "Geçersiz istek metodu. Sadece " . implode(', ', $allowed) . " kabul edilir."
|
|
38
|
+
]);
|
|
39
|
+
exit;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// NOT: Bu dosya (ApiAuthControl), sadece Auth (Giriş/Kayıt) işlemleri içindir.
|
|
43
|
+
// İleride ApiControl.php dosyasına RBAC veya Oturum kontrolleri eklense bile,
|
|
44
|
+
// buraya giriş yapmamış (guest) kullanıcıların istek atabilmesi için
|
|
45
|
+
// oturum engeli KOYULMAMALIDIR.
|
|
46
|
+
|
|
47
|
+
// 6. Rate Limiting (Kaba Kuvvet ve Spam Koruması)
|
|
48
|
+
// Aynı IP'den saniyede maksimum 1 istek atılmasına izin verilir.
|
|
49
|
+
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
|
50
|
+
$rateKey = 'auth_rate_limit:' . $ip;
|
|
51
|
+
$limit = 1;
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
$redis = \Src\Service\RedisService::getInstance();
|
|
55
|
+
$currentCount = $redis->get($rateKey);
|
|
56
|
+
|
|
57
|
+
if ($currentCount !== false && $currentCount >= $limit) {
|
|
58
|
+
http_response_code(429); // Too Many Requests
|
|
59
|
+
echo json_encode([
|
|
60
|
+
'status' => 'error',
|
|
61
|
+
'message' => 'Lütfen yavaşlayın. Çok sık istek gönderiyorsunuz.'
|
|
62
|
+
]);
|
|
63
|
+
exit;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
$redis->incr($rateKey);
|
|
67
|
+
|
|
68
|
+
// Eğer anahtar ilk defa oluşturuluyorsa ömrünü 1 saniye olarak belirle
|
|
69
|
+
if ($currentCount === false || $currentCount == 0) {
|
|
70
|
+
$redis->expire($rateKey, 1);
|
|
71
|
+
}
|
|
72
|
+
} catch (\Exception $e) {
|
|
73
|
+
// Redis'e ulaşılamazsa (sunucu çökmesi vs.) kayıt olma akışını tamamen durdurmak yerine
|
|
74
|
+
// loglanabilir veya sessizce pas geçilebilir.
|
|
75
|
+
error_log("Redis Bağlantı Hatası (Rate Limit Aşıldı): " . $e->getMessage());
|
|
76
|
+
}
|
|
@@ -18,15 +18,26 @@ require_once __DIR__ . '/../config/app-version.php';
|
|
|
18
18
|
// 3. Sadece API'ye özgü metodları yükle
|
|
19
19
|
require_once __DIR__ . '/../bin/SystemMethod.php';
|
|
20
20
|
|
|
21
|
-
// 4.
|
|
21
|
+
// 4. Oturum (Session) Konfigürasyonları
|
|
22
|
+
if (session_status() === PHP_SESSION_NONE) {
|
|
23
|
+
session_start();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Beni Hatırla Kontrolü
|
|
27
|
+
if (empty($_SESSION['kullaniciId']) && !empty($_COOKIE['remember_me'])) {
|
|
28
|
+
$rememberedIdHex = \Bin\SystemMethod::validateRememberMeCookie();
|
|
29
|
+
if ($rememberedIdHex) {
|
|
30
|
+
$_SESSION['kullaniciId'] = hex2bin($rememberedIdHex);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 5. API Konfigürasyonları (JSON Response Header vs.)
|
|
22
35
|
header('Content-Type: application/json; charset=utf-8');
|
|
23
36
|
|
|
24
|
-
//
|
|
25
|
-
// API uç noktalarında tanımlanan $allowedMethods dizisini baz alır. Tanımsızsa sadece POST kabul eder.
|
|
37
|
+
// 6. İzin Verilen HTTP Metodlarının Kontrolü
|
|
26
38
|
$allowed = isset($allowedMethods) && is_array($allowedMethods) ? $allowedMethods : ['POST'];
|
|
27
39
|
$requestMethod = $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN';
|
|
28
40
|
|
|
29
|
-
// Preflight istekleri (OPTIONS) CORS için hayati öneme sahiptir, her halükarda 200 dönüp çıkış yapmasını sağlarız.
|
|
30
41
|
if ($requestMethod === 'OPTIONS') {
|
|
31
42
|
http_response_code(200);
|
|
32
43
|
exit;
|
|
@@ -34,48 +45,83 @@ if ($requestMethod === 'OPTIONS') {
|
|
|
34
45
|
|
|
35
46
|
if (!in_array($requestMethod, $allowed)) {
|
|
36
47
|
http_response_code(405);
|
|
37
|
-
echo json_encode([
|
|
38
|
-
'status' => 'error',
|
|
39
|
-
'message' => "Geçersiz istek metodu. Sadece " . implode(', ', $allowed) . " kabul edilir."
|
|
40
|
-
]);
|
|
48
|
+
echo json_encode(['status' => 'error', 'message' => "Geçersiz istek metodu. Sadece " . implode(', ', $allowed) . " kabul edilir."]);
|
|
41
49
|
exit;
|
|
42
50
|
}
|
|
43
51
|
|
|
44
|
-
|
|
52
|
+
// 7. Global CSRF Duvarı
|
|
53
|
+
if (in_array($requestMethod, ['POST', 'PUT', 'DELETE'])) {
|
|
54
|
+
// 1. Header'dan kontrol et (Fetch/Axios SPA uyumu)
|
|
55
|
+
$token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
|
|
56
|
+
|
|
57
|
+
// 2. Eğer Header'da yoksa, JSON Body'den kontrol et
|
|
58
|
+
if (empty($token)) {
|
|
59
|
+
$input = json_decode(file_get_contents('php://input'), true);
|
|
60
|
+
if (is_array($input) && !empty($input['csrf_token'])) {
|
|
61
|
+
$token = $input['csrf_token'];
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 3. Eğer JSON'da da yoksa standart POST datasından kontrol et (Eski usül form)
|
|
66
|
+
if (empty($token)) {
|
|
67
|
+
$token = $_POST['csrf_token'] ?? '';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (!\Bin\SystemMethod::verifyCsrf($token)) {
|
|
71
|
+
http_response_code(403);
|
|
72
|
+
echo json_encode([
|
|
73
|
+
'status' => 'error',
|
|
74
|
+
'message' => 'CSRF doğrulaması başarısız. Lütfen sayfayı yenileyip tekrar deneyin.'
|
|
75
|
+
]);
|
|
76
|
+
exit;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 8. CORS (Cross-Origin Resource Sharing) Kuralları
|
|
81
|
+
// Geliştirme aşamasında her yerden gelen isteklere izin ver
|
|
82
|
+
if ($_ENV['APP_ENV'] === 'development') {
|
|
83
|
+
header('Access-Control-Allow-Origin: *');
|
|
84
|
+
} else {
|
|
85
|
+
// Canlı ortamda sadece belirlenen adreslere izin ver
|
|
86
|
+
header('Access-Control-Allow-Origin: https://senindomainin.com');
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/*
|
|
45
90
|
// -------------------------------------------------------------------------
|
|
46
|
-
//
|
|
91
|
+
// 8. Auth Guard (Oturum Kalkanı - API İçin)
|
|
47
92
|
// -------------------------------------------------------------------------
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
//
|
|
93
|
+
// Eğer bu API uç noktasının (endpoint) ZORUNLU olarak giriş yapmış üyelere
|
|
94
|
+
// açık olmasını istiyorsanız aşağıdaki bloğu kullanabilirsiniz.
|
|
95
|
+
// Not: Auth. işlem yapmayan tüm özel (private) API'ler için önerilir.
|
|
51
96
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
97
|
+
if (empty($_SESSION['kullaniciId']) && empty($_SESSION['kullanici_id'])) {
|
|
98
|
+
http_response_code(401);
|
|
99
|
+
echo json_encode([
|
|
100
|
+
'status' => 'error',
|
|
101
|
+
'message' => 'Bu işlemi yapabilmek için giriş yapmalısınız.'
|
|
102
|
+
]);
|
|
103
|
+
exit;
|
|
104
|
+
}
|
|
55
105
|
*/
|
|
56
106
|
|
|
57
107
|
/*
|
|
58
108
|
// -------------------------------------------------------------------------
|
|
59
|
-
//
|
|
109
|
+
// 9. RBAC (Rol Bazlı Erişim Kontrolü - API İçin)
|
|
60
110
|
// -------------------------------------------------------------------------
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
|
|
66
|
-
$rateKey = 'rate_limit:' . $ip;
|
|
67
|
-
$limit = 60; // 1 dakikadaki maksimum istek sayısı
|
|
68
|
-
$redis = \Src\Service\RedisService::getInstance();
|
|
69
|
-
|
|
70
|
-
$currentCount = $redis->get($rateKey);
|
|
71
|
-
if ($currentCount !== null && $currentCount >= $limit) {
|
|
72
|
-
http_response_code(429); // 429 Too Many Requests
|
|
73
|
-
echo json_encode(['status' => 'error', 'message' => 'Çok fazla istek gönderdiniz. Lütfen daha sonra tekrar deneyin.']);
|
|
74
|
-
exit;
|
|
75
|
-
}
|
|
111
|
+
// Belirli bir API işleminin (örn: ürün silme) sadece Admin veya yetkili
|
|
112
|
+
// roller tarafından yapılmasını sağlamak için.
|
|
113
|
+
// API dosyanızın en tepesinde $allowedRoles = [1]; şeklinde tanımlayabilirsiniz.
|
|
76
114
|
|
|
77
|
-
$
|
|
78
|
-
|
|
79
|
-
|
|
115
|
+
if (isset($allowedRoles) && is_array($allowedRoles)) {
|
|
116
|
+
$userRole = $_SESSION['rol'] ?? 3; // Örn: 1=Admin, 2=Mod, 3=User
|
|
117
|
+
|
|
118
|
+
if (!in_array($userRole, $allowedRoles)) {
|
|
119
|
+
http_response_code(403);
|
|
120
|
+
echo json_encode([
|
|
121
|
+
'status' => 'error',
|
|
122
|
+
'message' => 'Bu işlem için yeterli yetkiniz bulunmuyor.'
|
|
123
|
+
]);
|
|
124
|
+
exit;
|
|
125
|
+
}
|
|
80
126
|
}
|
|
81
127
|
*/
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* ArtiFrame Auth Engine (Guest Only)
|
|
4
|
+
*
|
|
5
|
+
* @package ArtiFrame
|
|
6
|
+
* @author Artilingo
|
|
7
|
+
* @license AGPLv3 (Attribution-ShareAlike Required)
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
require_once __DIR__ . '/../vendor/autoload.php';
|
|
11
|
+
|
|
12
|
+
// 1. Ortam değişkenlerini yükle (.env)
|
|
13
|
+
\App\DotEnv::load(__DIR__ . '/../.env');
|
|
14
|
+
|
|
15
|
+
// 2. Uygulama sabitlerini yükle (APP_ENV, APP_VERSION)
|
|
16
|
+
require_once __DIR__ . '/../config/app-version.php';
|
|
17
|
+
|
|
18
|
+
// 3. Sadece View'a özgü metodları yükle
|
|
19
|
+
require_once __DIR__ . '/../bin/ViewMethod.php';
|
|
20
|
+
|
|
21
|
+
// 4. Oturum (Session) Başlatma
|
|
22
|
+
if (session_status() === PHP_SESSION_NONE) {
|
|
23
|
+
session_start();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Beni Hatırla Kontrolü
|
|
27
|
+
if (empty($_SESSION['kullaniciId']) && !empty($_COOKIE['remember_me'])) {
|
|
28
|
+
$rememberedIdHex = \Bin\SystemMethod::validateRememberMeCookie();
|
|
29
|
+
if ($rememberedIdHex) {
|
|
30
|
+
$_SESSION['kullaniciId'] = hex2bin($rememberedIdHex);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 5. Ziyaretçi (Guest) Kontrolü
|
|
35
|
+
// Kullanıcı zaten giriş yapmışsa Auth sayfalarına (kayıt, giriş) giremez, yönlendirilir.
|
|
36
|
+
if (isset($_SESSION['kullaniciId']) || isset($_SESSION['kullanici_id'])) {
|
|
37
|
+
header("Location: /");
|
|
38
|
+
exit;
|
|
39
|
+
}
|
|
@@ -5,11 +5,6 @@
|
|
|
5
5
|
* @package ArtiFrame
|
|
6
6
|
* @author Artilingo
|
|
7
7
|
* @license AGPLv3 (Attribution-ShareAlike Required)
|
|
8
|
-
* @link https://artiframe.artilingo.com
|
|
9
|
-
*
|
|
10
|
-
* NOTICE: This file is part of the ArtiFrame ecosystem.
|
|
11
|
-
* Any derivative works or patches MUST retain this original copyright notice
|
|
12
|
-
* and remain open-source under the AGPLv3 license.
|
|
13
8
|
*/
|
|
14
9
|
|
|
15
10
|
namespace App;
|
|
@@ -22,48 +17,54 @@ class Database
|
|
|
22
17
|
private static ?PDO $instance = null;
|
|
23
18
|
|
|
24
19
|
private function __construct() {}
|
|
20
|
+
|
|
25
21
|
private function __clone() {}
|
|
26
22
|
|
|
27
23
|
public static function getInstance(): PDO
|
|
28
24
|
{
|
|
29
25
|
if (self::$instance === null) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
$host = $_ENV['DB_HOST'] ?? '127.0.0.1';
|
|
27
|
+
$name = $_ENV['DB_NAME'] ?? 'artiframe';
|
|
28
|
+
$user = $_ENV['DB_USER'] ?? 'root';
|
|
29
|
+
$pass = $_ENV['DB_PASSWORD'] ?? '';
|
|
30
|
+
$port = $_ENV['DB_PORT'] ?? 3306;
|
|
31
|
+
|
|
32
|
+
// Eğer veritabanı adı veya kullanıcı boşsa, veritabanı henüz kurulmamış olabilir.
|
|
33
|
+
if (empty($name) || empty($user)) {
|
|
34
|
+
die("Veritabanı bağlantı bilgileri eksik. Lütfen .env dosyasını kontrol edin.");
|
|
36
35
|
}
|
|
37
36
|
|
|
38
|
-
$host = $_ENV['DB_HOST'] ?? 'localhost';
|
|
39
|
-
$dbname = $_ENV['DB_NAME'] ?? 'portfobase';
|
|
40
|
-
$user = $_ENV['DB_USER'] ?? 'root';
|
|
41
|
-
$pass = $_ENV['DB_PASS'] ?? '';
|
|
42
|
-
|
|
43
|
-
$dsn = sprintf("mysql:host=%s;dbname=%s;charset=utf8mb4", $host, $dbname);
|
|
44
|
-
|
|
45
|
-
$options = [
|
|
46
|
-
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
47
|
-
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
48
|
-
PDO::ATTR_EMULATE_PREPARES => false,
|
|
49
|
-
];
|
|
50
|
-
|
|
51
37
|
try {
|
|
52
|
-
|
|
38
|
+
$dsn = "mysql:host={$host};port={$port};dbname={$name};charset=utf8mb4";
|
|
39
|
+
self::$instance = new PDO($dsn, $user, $pass, [
|
|
40
|
+
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
41
|
+
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
42
|
+
PDO::ATTR_EMULATE_PREPARES => false,
|
|
43
|
+
]);
|
|
53
44
|
} catch (PDOException $e) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
$msg = !$isDev
|
|
57
|
-
? 'Veritabanı bağlantı hatası. Sistem yöneticisi ile görüşün.'
|
|
58
|
-
: 'Veritabanı Hatası (Dev Mod): ' . $e->getMessage();
|
|
59
|
-
|
|
60
|
-
header('Content-Type: application/json; charset=utf-8');
|
|
61
|
-
http_response_code(500);
|
|
62
|
-
echo json_encode(['success' => false, 'message' => $msg]);
|
|
63
|
-
exit;
|
|
45
|
+
die("Veritabanı bağlantı hatası: " . $e->getMessage());
|
|
64
46
|
}
|
|
65
47
|
}
|
|
66
48
|
|
|
67
49
|
return self::$instance;
|
|
68
50
|
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Long-running worker'lar için veritabanı bağlantısının
|
|
54
|
+
* düşüp düşmediğini kontrol eder, düşmüşse yeniden bağlanır.
|
|
55
|
+
*/
|
|
56
|
+
public static function ping(): void
|
|
57
|
+
{
|
|
58
|
+
if (self::$instance !== null) {
|
|
59
|
+
try {
|
|
60
|
+
self::$instance->query('SELECT 1');
|
|
61
|
+
} catch (PDOException $e) {
|
|
62
|
+
$msg = strtolower($e->getMessage());
|
|
63
|
+
if (strpos($msg, 'gone away') !== false || strpos($msg, 'lost connection') !== false) {
|
|
64
|
+
self::$instance = null;
|
|
65
|
+
self::getInstance();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
69
70
|
}
|
|
@@ -21,7 +21,25 @@ class DotEnv
|
|
|
21
21
|
*/
|
|
22
22
|
public static function load(string $path): void
|
|
23
23
|
{
|
|
24
|
-
// 1.
|
|
24
|
+
// 1. Önce Hızlı Cache Dosyası Var Mı Kontrol Et (Performans Modu)
|
|
25
|
+
$dir = dirname($path);
|
|
26
|
+
$cachePath = $dir . '/config/env-cache.php';
|
|
27
|
+
|
|
28
|
+
if (file_exists($cachePath) && is_readable($cachePath)) {
|
|
29
|
+
$cachedEnv = require $cachePath;
|
|
30
|
+
if (is_array($cachedEnv)) {
|
|
31
|
+
foreach ($cachedEnv as $name => $value) {
|
|
32
|
+
if (!array_key_exists($name, $_SERVER) && !array_key_exists($name, $_ENV)) {
|
|
33
|
+
putenv(sprintf('%s=%s', $name, $value));
|
|
34
|
+
$_ENV[$name] = $value;
|
|
35
|
+
$_SERVER[$name] = $value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return; // Cache bulunduysa .env okumadan direkt dön!
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 2. Cache Yoksa Klasik Yavaş Dosya Okuma (Geliştirici Modu)
|
|
25
43
|
$realPath = realpath($path);
|
|
26
44
|
$targetPath = $realPath !== false ? $realPath : $path;
|
|
27
45
|
|
|
@@ -18,7 +18,53 @@ require_once __DIR__ . '/../config/app-version.php';
|
|
|
18
18
|
// 3. Sadece View'a özgü metodları yükle
|
|
19
19
|
require_once __DIR__ . '/../bin/ViewMethod.php';
|
|
20
20
|
|
|
21
|
-
// 4. Oturum (Session)
|
|
21
|
+
// 4. Oturum (Session) Başlatma
|
|
22
22
|
if (session_status() === PHP_SESSION_NONE) {
|
|
23
23
|
session_start();
|
|
24
24
|
}
|
|
25
|
+
|
|
26
|
+
// Beni Hatırla Kontrolü
|
|
27
|
+
if (empty($_SESSION['kullaniciId']) && !empty($_COOKIE['remember_me'])) {
|
|
28
|
+
$rememberedIdHex = \Bin\SystemMethod::validateRememberMeCookie();
|
|
29
|
+
if ($rememberedIdHex) {
|
|
30
|
+
$_SESSION['kullaniciId'] = hex2bin($rememberedIdHex);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
// -------------------------------------------------------------------------
|
|
36
|
+
// 5. Auth Guard (Oturum Kalkanı)
|
|
37
|
+
// -------------------------------------------------------------------------
|
|
38
|
+
// Tüm sistemi varsayılan olarak "sadece giriş yapmış üyelere açık" hale
|
|
39
|
+
// getirmek isterseniz aşağıdaki bloğun yorumunu kaldırın.
|
|
40
|
+
// Dışarıya açık olmasını istediğiniz sayfaların (örn: landing.php)
|
|
41
|
+
// en tepesine define('ALLOW_PUBLIC_VIEW', true); ekleyerek kalkanı delebilirsiniz.
|
|
42
|
+
|
|
43
|
+
if (!defined('ALLOW_PUBLIC_VIEW') || ALLOW_PUBLIC_VIEW !== true) {
|
|
44
|
+
if (empty($_SESSION['kullaniciId']) && empty($_SESSION['kullanici_id'])) {
|
|
45
|
+
header("Location: /auth/giris");
|
|
46
|
+
exit;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
// -------------------------------------------------------------------------
|
|
53
|
+
// 6. RBAC (Rol Bazlı Erişim Kontrolü) Örneği
|
|
54
|
+
// -------------------------------------------------------------------------
|
|
55
|
+
// Kullanıcıların yetkilerine göre sayfalara erişimini denetlemek isterseniz:
|
|
56
|
+
// Varsayalım ki roller: 1 = Admin, 2 = Moderatör, 3 = Standart Kullanıcı
|
|
57
|
+
|
|
58
|
+
// Bu sayfanın sadece belirli rollere açık olduğunu belirtmek için sayfanın
|
|
59
|
+
// en başına $allowedRoles = [1, 2]; tanımlayabilirsiniz.
|
|
60
|
+
|
|
61
|
+
if (isset($allowedRoles) && is_array($allowedRoles)) {
|
|
62
|
+
$userRole = $_SESSION['rol'] ?? 3; // Session'da rol yoksa standart kabul et
|
|
63
|
+
|
|
64
|
+
if (!in_array($userRole, $allowedRoles)) {
|
|
65
|
+
// Yetkisiz erişim! 403 sayfasına veya ana sayfaya yönlendir:
|
|
66
|
+
header("Location: /yetkisiz-erisim");
|
|
67
|
+
exit;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
*/
|