MHM Rentiva v4.27.2: Settings Testing Kirlilik Hotfix + Duplicate Addon Notice Dedupe
v4.27.1 i18n hotfix'inden sonra kullanıcı üç yeni bug daha bildirdi — hepsi aynı taze-kurulum senaryosundan geliyor ve üçü de Settings Testing sayfasında "Run All Diagnostics" butonuna bir kere basma ile tetikleniyor. v4.27.2 bu zinciri kırıyor.
🐛 Bug 1: Taze Kurulumda Tüm Text Alanları "1"
Senaryo:
- Eklenti taze kurulur.
- Kullanıcı Ayarlar → Settings Testing sekmesine gidip "Run All Diagnostics" butonuna basar.
- General Settings'e döner — Brand Name = "1", Cancellation Deadline = 1, Payment Deadline = 1, Support Email, Brand Logo URL, vs. hep "1".
- Ancak "Reset to Defaults" butonuna basınca düzeliyor.
Kök Neden
SettingsTester::test_settings_save() bir "değişiklik algılanmış save" tetiklemek için boş string'leri '1''e çeviriyordu:
// Fresh install: $current_str == ''
if ( in_array( $current_str, array( '0', '1', '' ) ) ) {
$test_value = ( $current_str === '1' ) ? '0' : '1'; // → '1'
}
Sonra bu '1' payload'u GERÇEK sanitizer'a veriliyordu. Sanitizer hedef tab'ın TÜM alanlarını yeniden yazıyordu (sadece test edilen keyleri değil). Restore mekanizması ise SADECE açıkça test edilen keyleri eski haline getiriyordu → diğer tab alanlarına yapılan collateral yazımlar DB'de kalıyordu.
Vahim nokta: Fresh install'da General test çalıştığında:
brand_name→ '1' (test flip'i, sonra restore edildi) ✓currency→ '1' (flip + restore) ✓dark_mode→ sanitizer yazdı, test hiç dokunmadı → DB'de kaldısupport_email→ sanitizer default olarakadmin@...e yazdı, flip'le '1' oldu, restore edilmedi → DB'de kaldı- ... ve daha fazlası
Çözüm
1. Harness fix — tam snapshot/restore
// YENİ v4.27.2: BÜTÜN option'ı snapshot al, BÜTÜN option'ı restore et.
$option_existed_before = false !== get_option( $option_name, false );
$full_option_snapshot = (array) get_option( $option_name, array() );
// ... test koşar, sanitizer DB'yi kirletir ...
if ( $option_existed_before ) {
update_option( $option_name, $full_option_snapshot );
} else {
delete_option( $option_name );
}
Test artık DB'yi gerçekten read-only bırakıyor. Collateral yazımlar otomatik yok oluyor.
2. Migration — mevcut install'ları temizle
SettingsCore::migrate_clean_test_pollution() flag'li (mhm_rentiva_v4272_test_pollution_cleaned) tek seferlik migrasyon:
$polluted_keys = array(
'mhm_rentiva_brand_name', 'mhm_rentiva_email_from_name',
'mhm_rentiva_email_from_address', 'mhm_rentiva_support_email',
'mhm_rentiva_booking_url', 'mhm_rentiva_login_url',
'mhm_rentiva_currency', /* ... */
);
foreach ($polluted_keys as $key) {
$value = $settings[$key] ?? null;
if ('0' === $value || '1' === $value) {
unset($settings[$key]); // fallback to default
}
}
Sadece kirlilik imzasını ('0' / '1') olan text, email, URL, currency alanlarını temizliyor. Numeric alanlar (deadline'lar) dokunulmadı — kullanıcı gerçekten 1 girmek istemiş olabilir (nadiren). Legitimate string değerler korunuyor.
🐛 Bug 2: Ek Hizmetler Sayfasında Çift Limit Notice
Additional Services admin sayfasında Lite limit uyarısı iki kez görünüyordu — istatistik kartlarının üstünde ve altında.
Kök Neden
AddonMenu::add_addon_page_title() içinde, notice iç içe geçmiş <div class="wrap"> bloğunun içinde emit ediliyordu. WordPress core admin-notice relocator JS'i bu durumda:
- Standart kopyayı
wp-header-endmarker'ından sonra yerleştiriyor - Orijinal kopya iç wrap'in içinde duruyor
- → İki kopya
Çözüm
Notice artık ayrı bir admin_notices callback'i — AddonMenu::render_addon_limit_notice() — priority 20'de. İç wrap kapatıldıktan SONRA emit ediliyor, WordPress tam olarak bir kez yerleştiriyor.
🐛 Bug 3: Settings Testing "Defaults Set" Phantom Key FAIL'leri
Settings Testing sayfası, hiçbir yerde kayıtlı olmayan ayar keyleri için "Defaults Set: FAIL" veriyordu:
mhm_rentiva_timezone(General'de yok)mhm_rentiva_db_auto_optimize(Core'da yok)mhm_rentiva_wp_optimization_enabled(Core'da yok)mhm_rentiva_my_account_url(Frontend'de yok)
Çözüm
Bu phantom keyleri check-list'ten çıkardım. Ayrıca "Email Address Valid" ve "Email Validation Works" FAIL'leri de Bug 1'in alt etkisiydi ('1' → is_email('1') = false) — kirlilik migrasyonu çalıştıktan sonra kendiliğinden geçer.
🧪 Testler
tests/Migration/SettingsTestPollutionMigrationTest.php — 5 yeni test, 19 assertion:
- Text/email/URL/currency kirliliği temizleniyor
- Meşru kullanıcı değerleri korunuyor
- Numeric alanlar (deadlines) dokunulmuyor
- Post-migration meşru "1" rename'i ezilmiyor (idempotent)
- Fresh install'da flag set ediliyor
✅ Doğrulama
| Kontrol | Sonuç |
|---|---|
| PHPCS release | 0 error / 0 warning |
| PHPUnit | 737/737 (+5 yeni, 732→737), 6 skipped, 0 regresyon |
| Plugin Check (PCP) | 0 error, 3 trivial warning (değişmedi) |
⚠️ Upgrade Notu
"Run All Diagnostics"'e basıp Brand Name = 1 gören kullanıcılar: Migrasyon bir sonraki admin page load'da otomatik çalışıyor. "Reset to Defaults"'a basman GEREKMİYOR. Text/email/URL/currency alanları defaults'a geri dönecek.
Sayısal deadline'lar (Cancellation / Payment) dokunulmuyor — migrasyon bunları kullanıcı seçimi olabilir diye ayırt edemiyor. Booking tab'ında deadline'ları 24 saat / 30 dakika (veya tercih ettiğin değer) olarak manuel ayarla.
📦 Kurulum
mhm-rentiva.4.27.2.zip → Eklentiler → Yeni Ekle → Eklenti Yükle, veya Rentiva Pro otomatik güncelleyicisi.
Gereksinimler: PHP 8.1+, WordPress 6.7+.
🎓 Ders
Bu üç bug da — v4.27.1 i18n hotfix gibi — runtime DB-state sınıfında. Ne PHPCS, ne PCP, ne unit test suite bunları yakalayabilir. Sadece gerçek admin UI üzerinden fresh install senaryosu sınanarak görülüyor. feedback_runtime_smoke_test.md memory notu artık "her major release öncesi fresh install UI smoke test zorunlu" diyor — bir sonraki major'da bu pattern'ı checklist'e entegre edeceğim.
Dinamik tablo: Bir günde 3 release çıkardık — v4.27.0 (WPCS submission prep) → v4.27.1 (i18n locale leak) → v4.27.2 (Settings Testing pollution + duplicate Addon notice). Her biri zero-regression + yeni regression testleri ile. Agile patch pipeline çalışıyor.
🔜 Sıradaki
- v4.28.0: Popüler Rotalar shortcode/block/widget (yeni özellik)
- v4.29.0: Vendor Report / Appeal System (yeni alt sistem)
- v4.27.x roadmap'i kapandı — bir sonraki şemsiye v4.28.0 olacak
GitHub Release: v4.27.2
