Skip to content

v0.25.0 - Odinstalowanie bez sladu, pilnowane testem

Choose a tag to compare

@mtsle mtsle released this 26 Jul 00:20
· 108 commits to main since this release

v0.25.0 — Odinstalowanie bez sladu, pilnowane testem

Wtyczka sprzatala po sobie od Kroku 18, ale lista kluczy w uninstall.php byla
pisana recznie i po cichu zostawala w tyle za kodem. Wydanie 0.24.0 dolozylo dwie
opcje, ktorych nikt do niej nie dopisal — i zaden test tego nie zauwazyl. To
wydanie zamyka luke w bazie klienta i stawia straznika, ktory nie pozwoli jej
otworzyc ponownie.

Czego brakowalo (uninstall.php)

Dopisane wpisy, kazdy zostawal dotad w bazie po usunieciu wtyczki:

  • aifaq_site_profile — temat witryny wyprowadzony z bazy wiedzy (Seo\SiteProfile)
  • aifaq_public_faq — pary Q&A opublikowane na podstronie (Faq\PublicFaq)
  • aifaq_editor_hint_done — wyciszenie komunikatu edytora; siedzi w metadanych
    UZYTKOWNIKA, nie w opcjach, wiec kasuje je delete_metadata( 'user', 0, …, true )
  • transienty o stalej nazwie: aifaq_indexing_lock, aifaq_cache_flush_lock
  • transienty o zmiennym sufiksie — aifaq_rl_<ip_hash>, aifaq_cooldown_generate_<model>,
    aifaq_cooldown_embed_<model>, aifaq_no_thinking_<model>

Transientow ze zmiennym sufiksem nie da sie wymienic po jednym, wiec kasuje je
jeden DELETE po LIKE na wp_options, dla obu prefiksow (_transient_aifaq_%
i _transient_timeout_aifaq_%), z esc_like(). Jeden wzorzec zamiast trzech —
obejmuje takze kazdy przyszly transient wtyczki i nie dotyka niczego cudzego.

Ograniczenie zapisane wprost w pliku: przy zewnetrznym trwalym object cache
(Redis, Memcached) transienty nie trafiaja do wp_options i ta sciezka ich nie
obejmuje. Wygasaja same po TTL; najdluzszy to godzina.

Multisite

Dotad sprzatany byl wylacznie biezacy blog, a wtyczka trzyma osobny komplet tabel
i opcji w kazdym blogu sieci. Cale sprzatanie siedzi teraz w jednej funkcji
aifaq_uninstall_cleanup_site() (prefiks + oslona function_exists(), bo plik
laduje sie do przestrzeni globalnej obok cudzych uninstall.php), a przy
is_multisite() wykonuje sie w petli switch_to_blog() / restore_current_blog()
po get_sites( array( 'number' => 10000, 'fields' => 'ids' ) ) — limit jawny, bo
domyslne 100 witryn byloby cicha strata.

Nazwy tabel powstaja wewnatrz funkcji: switch_to_blog() podmienia
$wpdb->prefix, wiec policzone raz na starcie wskazywalyby caly czas na blog 1.

Zasada bez zmian: wylacznie literaly stringow, zadnych stalych klas
(PageGuard::OPTION bez autoloadera to Fatal error), kazda funkcja WP spoza
gwarantowanego rdzenia za function_exists().

Podstrona „Generator FAQ" nadal nie jest kasowana — to tresc w witrynie klienta.

Straznik kompletnosci (tests/uninstall-guard-test.php)

Nowy zestaw skanuje src/** + ai-faq-generator.php czysto statycznie
(token_get_all, zero WordPressa, zero wywolan API), wyciaga klucze przekazywane
do zapisu trwalego (opcje, transienty, user meta, post meta), rozwiazuje stale klas
(self::OPTION'aifaq_site_profile') i klucze sklejane ('aifaq_rl_' . $x)
po prefiksie, po czym wymaga pokrycia dla kazdego klucza aifaq*.

Pokrycie liczy sie dwiema drogami: doslowny literal w uninstall.php albo wzorzec
SQL zadeklarowany znacznikiem GUARD-PATTERN: — ten drugi wylacznie dla
transientow
, bo opcje kasuje delete_option() po nazwie. Straznik sprawdza tez,
ze znacznik ma pokrycie w realnym kodzie (DELETE … LIKE, oba prefiksy,
esc_like), ze sprzatanie obejmuje siec i ze plik nie siega po stale klas.

Lista wyjatkow (klucze budowane ze zmiennej, statycznie nierozwiazywalne) jest
zamknieta i uzasadniona po jednej pozycji: nowe wystapienie czerwieni test,
zamiast przejsc niezauwazone.

Falszywa zielen w samym strazniku — znaleziona i naprawiona przy odbiorze

Asercja multisite sprawdzala poczatkowo strpos( $un_src, 'switch_to_blog' ).
Mutacja pokazala, ze jest slepa: po wycieciu realnego przelaczania blogow nazwa
zostaje w pliku wewnatrz function_exists( 'switch_to_blog' ), wiec test dalej
przechodzil. Stawka byla konkretna — petla przeleciałaby N razy po biezacym blogu,
a pozostale witryny sieci zostalyby zasmiecone, i zaden test by tego nie zglosil.

Asercja liczy teraz REALNE WYWOLANIA na tokenach (literal w function_exists() to
T_CONSTANT_ENCAPSED_STRING i sie nie liczy; wywolanie to T_STRING + (), plus
doszla kontrola symetrii switch_to_blog() / restore_current_blog() — bez niej
uninstall konczylby sie na przelaczonym blogu i psul kontekst kolejnym wtyczkom.

Weryfikacja

  • runner: 41 zestawow, 0 niezaliczonych (nowy segment uninstall-guard-test.php,
    24 asercje) — zmierzone PO naprawie asercji multisite
  • php -l: 4 zmienione pliki PHP, zero bledow skladni
  • mutacje straznika: 8/8 czerwienia (7 od razu, 1 dopiero po naprawie asercji)
    • M1 usuniecie delete_option( 'aifaq_public_faq' )FAIL KAZDY klucz aifaq* ma pokrycie
      (czerwieni takze krok19-migracja-test.php, bo licznik 27 przestaje sie zgadzac)
    • M2 usuniecie delete_metadata() user meta → kotwica aifaq_editor_hint_done
    • M3 usuniecie znacznika GUARD-PATTERN: → brak zadeklarowanego wzorca
    • M4 rozbicie prefiksu _transient_timeout_aifaq_ → wzorzec bez pokrycia w kodzie
    • M5 usuniecie switch_to_blog()PRZESZLA NA ZIELONO przed naprawa asercji
      (patrz „Falszywa zielen" wyzej); po naprawie czerwieni
    • M6 dorzucenie update_option( 'aifaq_nowa_sierota', 1 ) do src/
      BRAK: aifaq_nowa_sierota [option] ← SiteProfile.php.
      Pierwsze podejscie do tej mutacji dalo parse error w mutowanym pliku, wiec
      czerwien nie dowodzila niczego; powtorzone na pliku z czystym php -l
    • M7 usuniecie restore_current_blog() → zlamana symetria switch/restore
    • M8 pusta petla (wyciete aifaq_uninstall_cleanup_site()) → brak wywolania sprzatania
  • galaz multisite wykonana na atrapie $wpdb (3 blogi): 18 DROP TABLE z trzema
    ROZNYMI prefiksami (wp_, wp_2_, wp_7_) — dowod, ze nazwy tabel powstaja po
    switch_to_blog(); 81 delete_option (3 x 27 unikalnych); LIKE poprawnie
    zescapowany: '\_transient\_aifaq\_%'
  • zamrozone kontrakty bez zmian: krok7-rest 15 tras, krok20-capy 15 tras,
    krok18-faqtoolpanel 138 asercji bez regresji
  • podniesiona zamrozona liczba w krok19-migracja-test.php (C24): 2527
    delete_option — test WYKONUJE uninstall.php, wiec dwie nowe opcje musialy
    zmienic licznik
  • zero wywolan API — caly zestaw jest statyczny
  • AIFAQ_DB_VERSION zostaje 4 (schemat bazy bez zmian)