Core/System/Storage — Dosya tabanlı depolama (önbellek, oturum, günlük, trafik…)
Doğrulanan kod tabanı:
d508f5e1(dalfeat/fw-license-master) · Tarih: 2026-10-05 · Yayın: 0.9.7 = bu commit + sonrası; belge yalnız doğrulama anındaki kodu anlatır
Kaynak klasör:Core/System/Storage/— 16*.php(StorageManager1,Base/1,Constants/3,Drivers/1,Providers/10).
Envanter: 16 dosyanın 16'sı aşağıda anlatıldı.
1. Ne işe yarar, kim kullanır
Projenin Storage/ klasörü (ve çalışma alanı .cache/ klasörü) altında dosya okuma/yazmayı tek bir sürücü (UniversalFileDriver) ve konu başına bir sağlayıcı (CacheProvider, LogProvider, SessionProvider, TrafficProvider…) üzerinden yapar. Çağıran service('storage')->cache()->get(...) ya da ->logs()->error(...) der; StorageManager doğru sağlayıcıyı bulur.
Kimler çağırır: Kernel/Stages/SessionSandboxStage (oturum işleyicisi), Discovery önbellekleri (ProjectDataMapper → BootCacheProvider), depolar/servisler (getTtl, cache()->remember), günlükleme (logs()), yönetim paneli (günlük/oturum/önbellek ekranları), Routes/Engine/Providers/RouteManager ve CronJobsRepository (BootCacheProvider).
2. Klasör/dosya envanteri
2.1 Kök ve taban
| Dosya | Görev | Önemli public yöntemler |
|---|---|---|
StorageManager.php |
BaseService'ten türeyen sağlayıcı fabrikası; __call ile <ad>Provider sınıfını bulur ve örnekler. |
driver(): UniversalFileDriver, __call(string $name, array $arguments), hasProvider(string $name): bool, cache(), logs(), sessions(), traffic(), backups(), uploads(), exports(), view(), temp(), purgeAll(): array |
Base/BaseStorageProvider.php |
Sağlayıcıların atası: set/get/delete/clearAll/getStats/getFileContent, güvenli yol çözümü. |
withId(string), withProject(?string), set($key,$value,array $options=[]), get($key,$default=null), delete($key), clearAll(), getStats(), getFileContent($filename); soyut getStorageDir() |
2.2 Constants/
| Dosya | İçerik |
|---|---|
CacheConstants.php |
DEFAULT_TTL=300, TTL_SHORT=60, TTL_MEDIUM=600, TTL_LONG=1800, TTL_DAY=86400; SYSTEM_KEYS (settings_all, settings_shield, sidebar_%s); READABLE_PREFIXES (11 önek: settings_, comm_, api_, sidebar_, users_, sitemap_xml, robots_txt, rss_feed, llms_txt, cron_, content_); DISCOVERY_PREFIX_PROJECT='project_', …_DOMAIN='domain_', …_GROUP='group_'. |
LogConstant.php |
CATEGORIES (9 kategori: auth, email, error, ajax, application, cli, traffic, other, total; her biri başlık/anahtar sözcük/ikon/CSS sınıfı); getConfig(string $type): array. |
TrafficConstants.php |
DETECTABLE_BOTS (10 giriş: googlebot, bingbot, yandexbot, baiduspider, ahrefsbot, semrushbot, mj12bot, genel bot/spider/crawl) ve BLOCKED_BOTS (10 giriş). |
2.3 Drivers/
| Dosya | Görev | Yöntemler |
|---|---|---|
UniversalFileDriver.php |
Tek dosya G/Ç: biçim (raw, json, jsonl, serialized), isteğe bağlı crypto yardımcısıyla şifreleme, mkdir 0755, LOCK_EX. |
write(string $path, mixed $content, string $format='raw', bool $append=false, bool $encrypt=false): bool, read(string $path, string $format='raw', bool $decrypt=false): mixed, delete(string $path): bool |
2.4 Providers/
| Dosya | Depo klasörü | Biçim / şifre | Özel yöntemler |
|---|---|---|---|
CacheProvider.php |
<proje>/Storage/cache |
serialized, şifreli, uzantı .cache |
set/get/delete/forget/remember(string $key, callable $cb, ?int $ttl), isAllowedKey(), clearRelated(string $type), getTtl(string $type='default'): int, deleteByPrefix(), clearAll(?string $projectKey) |
LogProvider.php |
<proje>/Storage/logs/<kanal>/<tarih>_<proje>.jsonl |
jsonl, şifresiz |
channel(), file(), targetAll(), old(int $days), toPath(), workspace(), log($level,$msg,$ctx,$channel), emergency/alert/critical/error/warning/notice/info/debug(), logException(), all(), details(), clearAll(), getCategorizedLogs(), getConfigs(), parseLogContent() |
SessionProvider.php |
<proje>/Storage/sessions (sess_<id>) |
raw, şifresiz; SessionHandlerInterface |
getName(), open/close/read/write/destroy/gc, get/has/set/delete ($_SESSION üstünde), end(), regenerate(), clearAll(), getFileContent() |
TrafficProvider.php |
<proje>/Storage/logs/traffic/pulse_<YYYY-MM>_<proje>.json |
json, şifresiz |
record(array $data=[]), getMonthlyData(), saveMonthlyData(), getMonthlyFilePath(), get('date_<tarih>'), listDates(), purgeOldLogs(int $keepMonths=12) |
BootCacheProvider.php |
<çalışma alanı>/.cache/<önek><anahtar>.json |
json, şifresiz; tümü statik, BaseStorageProvider'dan türemez |
getCacheDir(), getFilePath(), get(), set(), delete(), clearProjectCache(string $projectKey) |
ViewProvider.php |
<proje>/Storage/framework/views |
raw |
clearAll() (yalnız <proje>_*.php) |
BackupProvider.php |
<proje>/Storage/backups/<proje> |
raw |
— |
ExportProvider.php |
<proje>/Storage/exports/<proje> |
raw |
— |
TempProvider.php |
<proje>/Storage/temp/<proje> |
raw |
— |
UploadProvider.php |
Paths::project()->uploads(<proje>) |
raw |
— |
3. Akış
3.1 Sağlayıcı bulma (StorageManager::__call, StorageManager.php:39)
- Bellekte varsa döner.
- Sınıf adı
ucfirst($ad).'Provider'; yoksa ve adsile bitiyorsa tekil (logs→LogProvider,sessions→SessionProvider,exports→ExportProvider,backups→BackupProvider,uploads→UploadProvider). - Sınıf varsa
new $fullClass($this->driver()); yoksaservice($className)ya daservice('<Ad>Manager'). purgeAll()yalnızcache,logs,sessionssağlayıcılarınınclearAll()'ını çalıştırır (:158-171).
3.2 Önbellek (CacheProvider)
set($key,$value,['ttl'=>…])yalnız izinli anahtarlarda yazar (isAllowedKey:SYSTEM_KEYSkalıpları ya daREADABLE_PREFIXES'ten biriyle başlayan anahtarlar); izinsiz anahtardafalsedöner ve hiçbir şey yazılmaz (:31-47).- Dosya adı:
<proje>_<anahtar>.cache; anahtarREADABLE_PREFIXES'ten biriyle başlıyorsa okunabilir ad, aksi haldemd5(<proje>_<anahtar>)(formatKey,:186-197). Kayıt{data, expires_at, created_at}serileştirilip şifrelenir. get()süresi dolmuşsa dosyayı siler ve varsayılanı döner;remember()önbellektenullolmayan değer varsa onu, yoksa callback sonucunu yazar; callbackExceptionfırlatırsanulldöner.getTtl('short'|'medium'|'long'|'day'|'week'|'month'|'year'|varsayılan)= 60 / 600 / 1800 / 86400 / 604800 / 2592000 / 31536000 / 300 sn (:169-180).clearRelated($tür):SYSTEM_KEYSadı/değeri eşleşenleri siler,READABLE_PREFIXESkategorisine uyanlarıdeleteByPrefixile siler;discovery/alliseBaseService::get()->discovery->clear()çağırır.
3.3 Önyükleme önbelleği (BootCacheProvider, ProjectDataMapper)
set($anahtar,$veri,$publicPath,$önek) <workspace>/.cache/<önek><anahtar>.json dosyasına JSON_PRETTY_PRINT ile yazar; dizin yoksa mkdir(…, 0777, true) (:56-61). get() dosya yoksa/boşsa/geçersiz JSON ise null. Süre (TTL) kavramı yoktur; silme yalnız delete() / clearProjectCache() iledir (proje önbelleği silinince domain_<alan> ve group_<grup> kayıtları da silinir). Yazan: ProjectDataMapper::build() (anahtarlar project_<proje>, domain_<alan>, group_<grup>), RouteManager, CronJobsRepository.
3.4 Günlük (LogProvider::log, :122-152)
Kanal adı [A-Za-z0-9_-] dışı karakterlerden arındırılır (boşsa app). Yol: <depo>/<kanal>/<YYYY-MM-DD>_<proje>.jsonl. Satır: timestamp (ISO 8601), level (büyük harf), message, ip (REMOTE_ADDR), uri, method, context. Yazım UniversalFileDriver::write($path,$entry,'json',append=true).
3.5 Oturum (SessionProvider)
Çerez adı RBN_<PROJE>_<çalışma alanı SHA-256'sının ilk 8 hanesi>_SESS (getName, :33-38). Dosya sess_<id> (resolvePath yalnız [a-zA-Z0-9_\-./] karakterlerine izin verir, diğerleri _ olur). destroy() idempotenttir: olmayan dosya başarı sayılır (aksi halde session_regenerate_id(true) ilk girişte reddediliyordu, SessionProvider.php docblock'u). gc() en az 86400 sn kullanır: max($max_lifetime, 86400) (:107). SessionSandboxStage ayrıca %10 olasılıkla gc(86400) çağırır (Kernel §3.4).
3.6 Trafik (TrafficProvider::record, :103-238)
Atlanan istekler: ilk yol bölümü panel öneki (Definition::get('route','DASHBOARD_PREFIX') = RouteBlueprint::DASHBOARD_PREFIX = dashboard; sabit okunamazsa kod yedeği rbn), api ya da AUTH_ROOTS içindeyse; robotsResolver->isPathRestricted() doğruysa. Aksi halde aylık JSON dosyası okunur, gün kaydı güncellenir, geri yazılır. IP başına gün kaydı (ip_log): saat, son saat, URL, konum, bot mu, bot adı, User-Agent, Referer, sayfa görüntüleme sayısı, gezilen sayfalar. Konum: bot ise Bot (<ad>); is_local()/127.0.0.1/::1 ise Localhost; değilse geoIP işleyicisi, yoksa XX.
4. Yapılandırma ve varsayılanlar
| Ayar | Değer | Kaynak |
|---|---|---|
| Önbellek varsayılan TTL | 300 sn | CacheConstants.php:8 |
| Trafik saklama süresi | 12 ay (purgeOldLogs($keepMonths = 12)) |
TrafficProvider.php:335 |
| Oturum çöp toplama alt sınırı | 86400 sn | SessionProvider.php:107 |
| Dizin izni (sürücü) | 0755 |
UniversalFileDriver.php:36 |
| Dizin izni (önyükleme önbelleği) | 0777 |
BootCacheProvider.php:58 |
| Önyükleme önbelleği klasörü | <workspace>/.cache |
BootCacheProvider.php:22 |
| Önbellek şifreleme | açık ($encrypted = true), anahtar CryptoHelper |
CacheProvider.php:19 |
5. Tuzaklar ve kurallar
CacheConstantsTTL'leri yalnızCacheProvider::getTtl()içinde kullanılır (kod taraması,Core/Bundles/Packages): çağıranlarBaseChannel,ContactRepository,NotificationRepository,CrawlerController(getTtl('short'|'long'|'medium')). Keşif/önyükleme önbelleği (BootCacheProvider) bu TTL'leri kullanmaz; onun süresi yoktur. (Eskiacik-sorular.md§2.7 — kodla çözüldü.)- Önbellek izin listesi (allow-list) vardır:
READABLE_PREFIXES/SYSTEM_KEYSdışında bir anahtarlacache()->set()sessizcefalsedöner veremember()her seferinde callback'i çalıştırır (CacheProvider.php:43,97-98). Yeni önbellek ailesi eklerken önceCacheConstants::READABLE_PREFIXES'e önek yazılmalıdır. BootCacheProviderdüz metin JSON yazar ve proje verisinin tamamını taşır (assemble()sonucu:domain,custom_path,options,cron_tasks,api_keys— yalnızbot_activityaçıkken). Dosyalar<workspace>/.cache/içindedir; bu klasörpublicdışındadır ama0777ile oluşturulur. Yerel Windows'ta izin modeli farklıdır; Linux üretiminde gerçek izin, umask'a bağlıdır (mkdirmodu umask ile kısılır). Üretimde izin değeri ölçülmedi.SessionProvideroturumu şifrelemez verawyazar ($encrypted=false); korumaStorage/klasörüne yazılan.htaccess'e (PermissionDoctor::secureFolder, Apache) bağlıdır — nginx'te bu dosya yok sayılır (Kernel §5).- Trafik sayacı "ziyaretçi sayar", "istek" saymaz: aynı IP aynı gün tekrar gelirse
page_viewsartar amatotal_hits/human_hits/bot_hits/cihaz/konum sayaçları artmaz; fonksiyon bu noktada erkenreturneder (TrafficProvider.php:187). Yani "total_hits" gün başına tekil IP sayısıdır. - Trafik dosyası okunur-değiştirilir-yazılır: her istek aylık JSON'u baştan okuyup geri yazar; yazma
LOCK_EXkullanır ama okuma-yazma arası kilit yoktur → eşzamanlı isteklerde güncelleme kaybı olabilir ve dosya ay içinde IP sayısıyla büyür. LogProvider::details($dosya)yolu<depo>/<$dosya>olarak birleştirir ve yalnızbasename($dosya)içinde_<proje>.jsonlgeçmesini şart koşar;..segmentleri süzülmez (LogProvider.php:259). Çağıranın (panel) dosya adınıall()çıktısından almasına güvenilir.UniversalFileDriverserializedbiçimiunserialize()ile okur (allowed_classeskısıtı yok,:135); dosyaların yalnız uygulama tarafından yazıldığı varsayımı vardır. Önbellek şifreli olduğundan geçersiz içeriknulldöner (decryptbaşarısızsanull).- Hatalar sessizdir:
writeherThrowable'dafalse,readnulldöner; üst katman yazmanın başarısını mutlaka denetlemelidir. SessionProvider::get/set$_SESSIONüzerindedir, sağlayıcının dosya anahtar-değer deposu değildir;ensureStarted()başlık gönderilmişse oturum başlatmaz.- Konfigürasyon yolu tutarsızlığı:
TrafficProvider::getStorageDir()custom_pathverisi varsa<workspace>/projects/<custom_path>/Storage/logs/traffickullanır, aksi haldePaths::project()->logs('traffic');LogProviderbenzer biçimderesolveProjectPath()kullanır. İkisi de aktif olmayan bir projenin dizinine yazabilir (proje anahtarı verildiğinde). LogThrottleStorage'da değildir: gerçek konumCore/Support/Bridges/Helpers/Library/LogThrottle.php'dir (kısıt kapısısecrets.phpapp.log_throttle).
6. Örnek (gerçek koddan)
// Core/System/Kernel/Stages/SessionSandboxStage.php:37-44
$handler = $services->service('storage') ? $services->service('storage')->sessions() : null;
if (is_object($handler) && method_exists($handler, 'getName')) {
session_name($handler->getName());
session_set_save_handler($handler, true);
}
// Core/Database/Repositories/Common/ContactRepository.php:61
$ttl = $this->storage->cache()->getTtl('short');
7. İlgili belgeler
- Core/System genel bakış · Kernel · Discovery (
ProjectDataMapper) · Paths - Support/Bridges (
CryptoHelper,LogThrottle) - Açık sorular