Technical flow from WordPress post through PVC, consent and REST API to view count

Post Views Counter i WP-Optimize: poprawne zliczanie oraz zgoda Complianz

Dlaczego licznik odpowiadał HTTP 200, a mimo to nie ufałem wynikowi

Ten problem zaczął się jak typowa historia o „cache”. Post Views Counter działał w trybie REST API, endpoint odpowiadał, a mimo to przy testach na aktualnym wpisie licznik nie zachowywał się wiarygodnie. Dopiero rozdzielenie kilku warstw — page cache, minifikacji JavaScriptu, kontekstu bieżącego wpisu i zgody statystycznej — pokazało, co naprawdę się dzieje.

Opisuję dokładnie przypadek z bybrzoza.com z 2 września 2026. To nie jest twierdzenie, że WP-Optimize zawsze psuje Post Views Counter albo że każda strona powinna klasyfikować taki licznik identycznie. To wynik testów konkretnej instalacji, który warto potraktować jako metodę diagnostyczną.

Środowisko, na którym problem został odtworzony

KomponentWersja w czasie testu
WordPress7.1
PHP8.5.7
Post Views Counter1.7.15
WP-Optimize4.6.1
Complianz7.5.4
Polylang3.8.7

Przed kopiowaniem ustawień sprawdź swoje wersje i faktyczną ścieżkę assetu PVC. W tym przypadku używany był post-views-counter/js/frontend.js.

1. Najpierw ustaliłem, kto naprawdę zarządza page cache

Audyt ujawnił realny problem konfiguracyjny: jednocześnie aktywne były Page Cache w WP-Optimize oraz Cache Enabler. WP-Optimize sam ostrzegał o drugim cache pluginie. Wyłączyłem Cache Enabler, zostawiłem WP-Optimize jako jedynego właściciela page cache, wykonałem purge i sprawdziłem anonimowy frontend.

To było potrzebne, żeby usunąć szum z diagnostyki. Nie jest jednak dowodem, że podwójny page cache powodował późniejszy błąd kontekstu Post Views Counter. Page Cache i Minify to dwie różne funkcje.

WP-Optimize ostrzegający o równoczesnym użyciu drugiego page cache
Najpierw usunąłem rzeczywisty konflikt dwóch mechanizmów page cache. Dopiero potem diagnozowałem Minify i PVC.

2. REST API 200 nie wystarcza: trzeba sprawdzić, jaki wpis jest liczony

Post Views Counter ma kilka trybów zliczania. W finalnej konfiguracji użyłem REST API. Podczas debugowania popełniłem też banalny, ale ważny błąd: jeden z testów zrobiłem na zwykłej Page, podczas gdy licznik był skonfigurowany do właściwego scope’u Posts. Taki test niczego nie rozstrzyga.

Na prawdziwym opublikowanym poście endpoint potrafił odpowiadać HTTP 200, ale to nadal nie było wystarczającym dowodem. Sprawdzałem w DevTools, jaki postID znajduje się w konfiguracji pvcArgsFrontend, jaki URL wywołuje request i który plik JavaScript jest initiatorem.

Gdy frontend.js był przetwarzany we wspólnym bundle WP-Optimize, request mógł mieć nieaktualny lub niewłaściwy kontekst wpisu. Sam kod 200 wyglądał więc „zdrowo”, podczas gdy licznik nie odpowiadał temu, czego oczekiwałem na bieżącej stronie.

3. Zamiast wyłączać Minify, wykluczyłem tylko asset PVC

WP-Optimize miał włączoną minifikację i łączenie JavaScriptu. Zamiast wyłączać całą optymalizację, dodałem konkretny asset Post Views Counter w:

WP-Optimize → Minify → JavaScript → Exclude JavaScript from processing

W mojej wersji wystarczyło wykluczenie ścieżki zawierającej:

post-views-counter/js/frontend.js

Oficjalna dokumentacja WP-Optimize nadal opisuje to pole jako wyłączenie wskazanego skryptu zarówno z minifikacji, jak i z merging. Po zapisaniu ustawienia zresetowałem pliki Minify/cache i wykonałem świeży test anonimowy.

Ustawienia JavaScript WP-Optimize z polem wykluczania skryptów z przetwarzania
Wąska zmiana: wykluczenie konkretnego assetu zamiast wyłączania całego Minify.

Po tej zmianie frontend.js ładował się osobno. W DevTools widziałem request inicjowany przez właściwy skrypt, z poprawnym ID aktualnego wpisu. Widoczny licznik i licznik backendowy zaczęły rosnąć zgodnie z oczekiwaniem.

DevTools pokazujący osobno ładowany frontend.js i request dla właściwego wpisu
Kluczowy test nie brzmiał „czy jest 200?”, tylko „czy aktualny Post wysyła właściwy request?”.

4. Dopiero działający licznik podpiąłem pod zgodę Statistics

Na tej instalacji PVC potraktowałem jako mechanizm statystyczny. To decyzja konfiguracyjna wynikająca z mojego sposobu użycia; nie jest to uniwersalna porada prawna.

W Complianz → Integrations → Script Center dodałem regułę blokującą frontend PVC przed zgodą:

  • Name: Post Views Counter
  • Action: Block a script, iframe or plugin
  • URL/script: post-views-counter/js/frontend.js
  • Category: Statistics

Oficjalna dokumentacja Complianz zaleca przy takich regułach użycie możliwie charakterystycznego identyfikatora/URL. Zbyt szeroki wzorzec może zablokować także inne skrypty.

Complianz Script Center z regułą Post Views Counter przypisaną do Statistics
Reguła Script Center blokuje frontend licznika do czasu zgody statystycznej.

5. Test zgody: przed wyborem, Deny i Accept

Najważniejszy test zrobiłem w świeżej prywatnej sesji na realnym opublikowanym wpisie. Nie opierałem się na samym stanie backendu Complianz.

StanRequest PVCpvc_visits[0]Licznik
Przed wyborembrakbrakbrak inkrementu PVC
Denybrakbrakbrak inkrementu PVC
Acceptjestjestinkrement potwierdzony
DevTools przed zgodą bez cookie Post Views Counter
Przed wyborem zgody nie ma cookie PVC ani requestu zliczającego.
DevTools po zgodzie z widocznym i zredagowanym cookie pvc_visits
Po Accept pojawia się pvc_visits[0]; jego wartość na zrzucie została trwale zredagowana.

6. Ręczna dokumentacja usługi i cookie w Complianz

Sam Script Center steruje uruchomieniem skryptu, ale chciałem też, aby Cookie Policy opisywała to, co faktycznie widziałem w runtime. Utworzyłem więc własną usługę i własny wpis cookie.

PoleWartość
ServicePost Views Counter
Service typewebsite statistics
Data sharedNo
Cookiepvc_visits[0]
Expiration1 day
PurposeStatistics
CookieDatabase syncOff — custom entry

Polski opis funkcji ustawiłem jako: „Przechowuje informacje o odwiedzonych wpisach i sesji, aby zapobiec wielokrotnemu zliczaniu odsłon.” Analogiczne opisy utrzymałem ręcznie po niemiecku i angielsku.

7. Drugi problem: customowe „Usage” nadal było po angielsku

Tu łatwo pomylić dwie różne usterki. Wcześniej opisałem osobny problem, w którym zsynchronizowany dokument Complianz był budowany za wcześnie względem trybu Polylang „The language is set from content”. Ten artykuł jest dostępny osobno: Complianz + Polylang: Cookie Policy po angielsku – fix.

W obecnym przypadku główny dokument był już poprawny. Nie lokalizowało się tylko zdanie generowane dla własnej usługi PVC:

  • PL: Używamy Post Views Counter dla website statistics.
  • DE: Wir verwenden Post Views Counter für website statistics.

Ręczne Service Type i Polylang String Translations nie zmieniły tego fragmentu. To był osobny, bardzo wąski przypadek.

Polska i niemiecka Cookie Policy przed poprawką z angielskim website statistics
Przed poprawką tylko fragment Usage własnej usługi pozostawał po angielsku.

8. Wąski workaround przez cmplz_document_html

Nie edytowałem plików Complianz. Istniejący MU-plugin 0.1.0 został rozszerzony do 0.2.0 o osobny filtr finalnego HTML dokumentu. Kod działa tylko na zsynchronizowanym EU Cookie Policy, tylko dla PL/DE, tylko w oknie Complianz >=7.5.4 i <8.0.0, a angielskiej wersji nie dotyka.

Najważniejsza część dodatkowego fixu wygląda tak:

function bybrzoza_cmplz_localize_pvc_usage( string $html, string $type, int $post_id ): string {
    if ( $html === '' || is_admin() || wp_doing_ajax() || wp_doing_cron() ||
        ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) {
        return $html;
    }

    if ( ! function_exists( 'pll_current_language' ) || ! class_exists( 'COMPLIANZ' ) ) {
        return $html;
    }

    if ( ! defined( 'CMPLZ_VERSION' ) || ! isset( COMPLIANZ::$document ) ||
        ! method_exists( COMPLIANZ::$document, 'get_document_data' ) ) {
        return $html;
    }

    $cmplz_version = strtok( (string) CMPLZ_VERSION, '#' );
    if ( version_compare( $cmplz_version, '7.5.4', '<' ) ||
        version_compare( $cmplz_version, '8.0.0', '>=' ) ) {
        return $html;
    }

    $pll_locale = pll_current_language( 'locale' );
    $wp_locale  = get_locale();
    if ( ! is_string( $pll_locale ) || $pll_locale === '' || $pll_locale !== $wp_locale ) {
        return $html;
    }

    if ( ! in_array( $wp_locale, array( 'pl_PL', 'de_DE' ), true ) ) {
        return $html;
    }

    $document_data = COMPLIANZ::$document->get_document_data( $post_id );
    if ( ! is_array( $document_data ) || ( $document_data['type'] ?? '' ) !== 'cookie-statement' ) {
        return $html;
    }

    $region = $document_data['region'] ?? false;
    if ( ! $region && function_exists( 'cmplz_get_region_from_legacy_type' ) ) {
        $region = cmplz_get_region_from_legacy_type( 'cookie-statement' );
    }
    if ( $region !== 'eu' ) {
        return $html;
    }

    $replacements = array(
        'de_DE' => array(
            'old' => 'Wir verwenden Post Views Counter für website statistics',
            'new' => 'Wir verwenden Post Views Counter für Website-Statistiken',
        ),
        'pl_PL' => array(
            'old' => 'Używamy Post Views Counter dla website statistics',
            'new' => 'Używamy Post Views Counter dla statystyk witryny',
        ),
    );

    $replacement = $replacements[ $wp_locale ] ?? null;
    if ( ! is_array( $replacement ) ) {
        return $html;
    }

    return str_replace( $replacement['old'], $replacement['new'], $html );
}

add_filter( 'cmplz_document_html', 'bybrzoza_cmplz_localize_pvc_usage', 20, 3 );

To celowo nie jest „tłumacz wszystko przez str_replace”. Replacement jest dokładny i związany tylko z nazwą Post Views Counter. Jeśli przyszła wersja Complianz zacznie generować poprawne zdanie, stary fragment nie wystąpi i ten kawałek kodu stanie się no-op. Przy Complianz 8.x fix również automatycznie się wyłącza i wymaga nowego audytu.

9. Finalny wynik PL / DE / EN

Po wdrożeniu 0.2.0 i purge sprawdziłem publiczny dokument we wszystkich trzech językach. Wynik:

  • PL: „Używamy Post Views Counter dla statystyk witryny.” + „1 dzień” + polski opis funkcji;
  • DE: „Wir verwenden Post Views Counter für Website-Statistiken.” + „1 Tag” + niemiecki opis funkcji;
  • EN: „We use Post Views Counter for website statistics.” + „1 day” + angielski opis funkcji.
Finalna sekcja Post Views Counter w Cookie Policy po polsku niemiecku i angielsku
Końcowy publiczny QA: PL, DE i EN są spójne, a EN pozostał nietknięty.

Co było fałszywym tropem

  • Website Scan na 50%. Raz doszedł do 100% i wykrył 18 cookies, później znów stanął na 50%. Nie był udowodnioną przyczyną problemu PVC i nie użyłem go jako completion gate.
  • Test na Page. Przy scope ustawionym na Posts taki test prowadzi w złą stronę.
  • HTTP 200. Sukces transportu nie oznacza jeszcze, że liczony jest właściwy wpis.
  • Sam purge. Czyszczenie cache bez sprawdzenia initiatora i postID nie pokazuje, czy problem zniknął.
  • Polylang String Translations. Pomagają w wielu miejscach, ale w tym konkretnym customowym zdaniu Usage nie zmieniły outputu.

Rollback i test po aktualizacjach

Ta konfiguracja ma dwa niezależne punkty rollbacku. Jeśli exclusion PVC w WP-Optimize spowoduje nieoczekiwany efekt, usuń wpis z listy exclusion, zapisz ustawienia i zresetuj pliki Minify/cache. Jeśli problem dotyczy MU-pluginu, rollback to przywrócenie poprzedniej wersji pliku 0.1.0 albo usunięcie dodatkowej funkcji 0.2.0, a następnie purge i ponowny test dokumentu.

Po aktualizacji PVC sprawdź ponownie rzeczywistą ścieżkę frontend.js. Po aktualizacji WP-Optimize sprawdź, czy exclusion nadal jest respektowane. Po aktualizacji Complianz lub Polylang wykonaj krótki test PL → DE → EN; przy Complianz 8.x nie omijaj guardraila wersji bez świeżego source audytu.

Wnioski

Najwięcej czasu oszczędziło mi rozdzielenie warstw. Najpierw jeden właściciel page cache. Potem właściwy Post i właściwy request. Następnie pojedynczy asset wykluczony z Minify zamiast wyłączania całej optymalizacji. Dopiero na stabilnym liczniku warto budować consent i dokumentację cookie. Dzięki temu każdy krok ma własny test i własny rollback.

Źródła i dalsze czytanie

Pomogła Ci ta instrukcja?
Jeśli zaoszczędziła Ci trochę czasu albo nerwów, możesz postawić mi kawę.