---
phase: 02-admin-panel-upgrade
plan: 03
type: execute
wave: 3
depends_on: ["02-02"]
files_modified:
  - src/Services/WordPressService.php
  - src/Controllers/SiteController.php
  - templates/sites/comments.php
  - config/routes.php
autonomous: true
delegation: off
---

<objective>
## Goal
Dodac "twarde" zamykanie komentarzy dla istniejacych tresci WordPress:
1. Zamkniecie komentarzy i pingow/trackbackow we wszystkich istniejacych wpisach strony.
2. Opcjonalne usuniecie oczekujacych komentarzy spamowych po zamknieciu komentarzy.
3. Pokazanie wyniku operacji w panelu komentarzy BackPRO.

## Purpose
Samo wylaczenie komentowania nowych wpisow nie chroni starych artykulow, ktore maja `comment_status = open`. Boty moga dalej dodawac komentarze pod istniejacymi wpisami. Operator BackPRO potrzebuje jednej akcji, ktora zdalnie domyka cala powierzchnie komentarzy dla wybranego serwisu.

## Output
- Nowa metoda `closeExistingComments()` w `WordPressService`.
- Nowe akcje remote service w `backpro-remote-service.php` generowanym przez `WordPressService`.
- Nowa akcja POST w `SiteController` i trasa w `config/routes.php`.
- Sekcja w `templates/sites/comments.php` z przyciskiem "Zamknij komentarze w istniejacych wpisach" i opcja usuniecia oczekujacych komentarzy.
</objective>

<context>
## Project Context
@.paul/PROJECT.md
@.paul/ROADMAP.md
@.paul/STATE.md

## Prior Work
@.paul/phases/02-admin-panel-upgrade/02-02-SUMMARY.md

## Source Files
@src/Services/WordPressService.php
@src/Controllers/SiteController.php
@templates/sites/comments.php
@config/routes.php
</context>

<acceptance_criteria>

## AC-1: Masowe zamkniecie istniejacych wpisow
```gherkin
Given uzytkownik jest zalogowany w BackPRO i strona ma aktywny plik serwisowy BackPRO
When klika "Zamknij komentarze w istniejacych wpisach"
Then WordPress ustawia comment_status='closed' i ping_status='closed' dla wszystkich opublikowanych wpisow
And BackPRO pokazuje liczbe zaktualizowanych wpisow
```

## AC-2: Opcjonalne czyszczenie oczekujacych komentarzy
```gherkin
Given uzytkownik widzi panel komentarzy danej strony
When zaznacza opcje usuniecia oczekujacych komentarzy i uruchamia operacje
Then WordPress usuwa komentarze ze statusem hold
And BackPRO pokazuje liczbe usunietych komentarzy
```

## AC-3: Bezpieczna obsluga bledow i odswiezenie statusu
```gherkin
Given remote service jest nieaktualny albo niedostepny
When uzytkownik uruchamia masowe zamkniecie komentarzy
Then BackPRO probuje zaktualizowac plik serwisowy i ponawia akcje
And przy niepowodzeniu pokazuje czytelny komunikat bledu bez psucia listy komentarzy
```

</acceptance_criteria>

<tasks>

<task type="auto">
  <name>Task 1: Dodac operacje close_existing_comments do WordPressService i remote service</name>
  <files>src/Services/WordPressService.php</files>
  <action>
    Dodac publiczna metode:
    - closeExistingComments(array $site, bool $deletePendingComments = false): array
      - Wywoluje callRemoteService($site, 'close_existing_comments', ['delete_pending_comments' => '1'/'0']).
      - Jezeli akcja nie dziala przez stary plik serwisowy, wywoluje ensureRemoteService(), odswieza site z bazy i ponawia akcje.
      - Zwraca success, posts_updated, pending_comments_deleted, message.
      - Przy bledzie zwraca success=false i czytelny message.

    Zaktualizowac BACKPRO_REMOTE_SERVICE_VERSION do kolejnej wersji, np. 1.6.0.

    W getBackproRemoteServiceContent() dodac action `close_existing_comments`:
    - Ustawic default_comment_status='closed' i default_ping_status='closed', aby nowe tresci tez byly domyslnie zamkniete.
    - Wykonac bezposredni update przez global `$wpdb`:
      - UPDATE {$wpdb->posts} SET comment_status='closed', ping_status='closed' WHERE post_type IN ('post','page') AND post_status NOT IN ('trash','auto-draft')
    - Zliczyc liczbe zaktualizowanych rekordow z wyniku query.
    - Jesli `delete_pending_comments=1`, usunac komentarze ze statusem `hold` przez wp_delete_comment($commentId, true).
    - Zwracac JSON z posts_updated, pending_comments_deleted i message.

    Nie modyfikowac istniejacych metod listowania/usuwania pojedynczych komentarzy poza ewentualnym wspolnym helperem formatowania wyniku.
  </action>
  <verify>php -l src/Services/WordPressService.php</verify>
  <done>AC-1, AC-2 i AC-3 maja warstwe zdalnej operacji WordPress.</done>
</task>

<task type="auto">
  <name>Task 2: Dodac akcje kontrolera i trase masowego zamkniecia</name>
  <files>src/Controllers/SiteController.php, config/routes.php</files>
  <action>
    Dodac do SiteController metode:
    - closeExistingComments(string $id): void
      - Auth::requireLogin().
      - Pobrac Site::find(), obsluzyc brak strony.
      - Odczytac checkbox/field `delete_pending_comments` jako bool.
      - Wywolac WordPressService::closeExistingComments($site, $deletePendingComments).
      - Flash success z liczba posts_updated i pending_comments_deleted.
      - Flash danger z message przy bledzie.
      - Redirect do `/sites/{id}/comments`.

    Dodac trase:
    - POST `/sites/{id}/comments/close-existing` -> SiteController@closeExistingComments

    Zachowac cienki kontroler: nie wpisywac SQL ani logiki WordPress do kontrolera.
  </action>
  <verify>php -l src/Controllers/SiteController.php oraz php -l config/routes.php</verify>
  <done>AC-1, AC-2 i AC-3 sa dostepne z panelu przez POST route.</done>
</task>

<task type="auto">
  <name>Task 3: Dodac UI hard-close w panelu komentarzy</name>
  <files>templates/sites/comments.php</files>
  <action>
    W `templates/sites/comments.php` dodac karte/sekcje pod ustawieniem "Komentowanie nowych wpisow":
    - Tytul: "Istniejace wpisy".
    - Krotkie wyjasnienie: operacja zamyka komentarze i pingi/trackbacki w juz opublikowanych tresciach.
    - Formularz POST do `/sites/{id}/comments/close-existing`.
    - Checkbox `delete_pending_comments` opisany jako "Usun oczekujace komentarze przy tej operacji".
    - Przycisk w stylu ostrzegawczym, np. `btn-outline-danger`, z data-confirm zawierajacym ostrzezenie, ze operacja dotyczy wszystkich wpisow tej strony.
    - Po flashu sukcesu/bledu istniejacy layout ma normalnie pokazac komunikat.

    Nie ukrywac listy komentarzy ani istniejacych filtrow statusu.
  </action>
  <verify>php -l templates/sites/comments.php</verify>
  <done>AC-1 i AC-2 maja widoczny, potwierdzany interfejs uzytkownika.</done>
</task>

</tasks>

<boundaries>

## DO NOT CHANGE
- src/Services/PublisherService.php
- src/Models/Article.php
- src/Models/Topic.php
- migrations/* (brak zmian schematu bazy)
- templates/articles/*
- cron/*

## SCOPE LIMITS
- Nie dodawac globalnej operacji dla wszystkich stron naraz; zakres to pojedyncza strona.
- Nie dodawac moderacji approve/spam/unspam w tym planie.
- Nie usuwac zatwierdzonych komentarzy, chyba ze uzytkownik usunie je osobno istniejaca funkcja.
- Nie dodawac nowych zaleznosci Composer.
- Nie modyfikowac bazy lokalnej BackPRO.

</boundaries>

<verification>
Before declaring plan complete:
- [ ] php -l src/Services/WordPressService.php
- [ ] php -l src/Controllers/SiteController.php
- [ ] php -l config/routes.php
- [ ] php -l templates/sites/comments.php
- [ ] /sites/{id}/comments pokazuje sekcje "Istniejace wpisy"
- [ ] POST /sites/{id}/comments/close-existing wywoluje remote service i pokazuje wynik
- [ ] Remote service version wzrosla, aby wymusic aktualizacje pliku na serwerze
</verification>

<success_criteria>
- Operator moze jednym kliknieciem zamknac komentarze i pingi w istniejacych wpisach wybranej strony.
- Operator moze przy tej operacji usunac komentarze oczekujace na moderacje.
- Wynik operacji pokazuje liczby zaktualizowanych wpisow i usunietych komentarzy.
- Brak regresji w istniejacym widoku listy komentarzy i usuwaniu pojedynczego komentarza.
</success_criteria>

<output>
After completion, create `.paul/phases/02-admin-panel-upgrade/02-03-SUMMARY.md`
</output>
