Ligase 2.4.9 — batch 2: 16 P1/P2 fixes from multi-agent audit
Continuation of v2.4.8 audit cleanup. Po pierwszej rundzie 14 krytycznych fixów (P0), tutaj idzie kolejne 16 fixów P1/P2 — wszystkie z raportów docs/audit-2025-06-01-*.md.
Po 2.4.9 audyt jest w 30 z 35+ findings naprawione (~85%). Reszta to architektoniczne refactory (GSC encryption, Logger PII redaction) wymagające osobnego planu.
Co zostało naprawione
Wydruk JSON
array_values()wraps w BlogPosting (about / mentions / isBasedOn / citation / hasPart).array_filter()zachowuje klucze numeryczne → JSON enkodował jako{"0":..,"2":..}zamiast[..,..]. Google rejects.
Cache invalidation
invalidate_post_and_related()— przy zapisie postu busts także archive/term/author/home caches w bieżącym locale + WPML/Polylang +en_USfallback. Wcześniej: edytujesz post, kategoria/strona główna pokazują stary JSON-LD do 12h.
Defensive guards (12 miejsc asymetrycznych)
class_exists('Ligase_Schema_Rules')dodane przed każdym::is_enabled_for_post(). Wcześniej fatal jeśli klasa nie załadowana wczesnym hookiem.
Type classes
- Service — wymagał TYLKO
_ligase_enable_service, inne typy sprawdzały ALSOSchema_Rules. Wyrównane. - SoftwareApplication — defaultował
ratingCount = '1'gdy brakowało. Fake-rating risk (Google manual action). Teraz: omitaggregateRatingjeśli brak realnych ratingów. - Event —
startDatebez ISO 8601 walidacji (free-text typu "tomorrow at 6pm" docierał do Google). Teraz: regex check, drop node jeśli invalid. - Review —
itemReviewedopcjonalny → emitował Review do niczego. Teraz: required gate. - DiscussionForumPosting —
gmdate('c', strtotime(''))=1970-01-01dla legacy importowanych komentarzy. Teraz: skip comment if no valid date. - ItemList —
current_url()produkowałhttps:///pathgdy$_SERVER['HTTP_HOST']puste (CLI/cron/REST). Teraz: fallback dohome_url()host.
AJAX & admin (security/safety)
wp_send_json_error+return;dodane w 20+ miejscach class-ajax.php. Aktualnie safe via wp_die, ale fragile.bulk_set_flags _ligase_paywalled— sprawdza tylkomanage_optionsraz. Dodane per-postcurrent_user_can('edit_post', $pid)w pętli._ligase_overridetype whitelist —save_meta_boxakceptował dowolny$typeklucz. Teraz walidacja przeciwkoLigase_Field_Contract::types().save_meta_box—$post_type_objmógł być null jeśli post_type unregistered. Dodany guard.javascript:URL filter wligase_credentials+ligase_extra_sameas+member_of—wp_strip_all_tagsnie filtruje schemat'ów. Dodanyesc_url_raw()na URL-like tokens.
Feature decisions
lb_service_area— wired read-side.LocalBusiness::is_configured()teraz akceptuje service-area mode bez street+city (wymagalb_area_served).build()omitujeaddresslub limit doaddressLocality/addressCountry. Google supports service-area businesses od 2018.Auditor::intercept()— never wired, deprecated as no-op. Use the batch AJAX scan flow (admin → Audytor page).
Stats
- 23 files modified, +339 / -67 lines
- Commit:
0308701 - Lint: all clean
- Drop-in z 2.4.8, bez migracji
Co jeszcze w backlogu (P2/P3, 2.5.0+)
- Logger PII redaction (post content + user emails w log files)
- GSC AES-256-CBC → AES-256-GCM upgrade z key rotation
- WPML/Polylang full schema translation parity
- WC cache invalidation debounce per-request
apply_audit_replacementsmode confirm dialog
SPRAWDŹ PO INSTALACJI: edytuj jeden post → wejdź na kategorię tego postu → schema powinno odzwierciedlać zmianę natychmiast (nie 12h później). Plus jeśli masz Event/SoftwareApplication z fake ratingCount → po update zniknie aggregateRating.