Skip to content
🔒 4 Sposoby programowego cofnięcia publikacji posta w wordpress

🔒 4 Sposoby programowego cofnięcia publikacji posta w wordpress

Strona padła po aktualizacji wtyczki, trzeba pilnie ukryć problematyczny wpis, zanim będzie za późno. A za tydzień przywrócić go z powrotem, gdy błąd zostanie naprawiony. Albo klient prosi o usunięcie nieaktualnego artykułu z wyników wyszukiwania, ale nie chce go kasować na zawsze.

Ręczne przełączanie statusu przez panel administracyjny sprawdza się przy jednym czy dwóch wpisach. Ale gdy są ich dziesiątki lub logika ma działać automatycznie, potrzebne jest podejście programistyczne. WordPress daje cztery sposoby na zdjęcie wpisu z publikacji za pomocą PHP: od bezpiecznej wersji roboczej po całkowite usunięcie.

Poniżej każda metoda z gotowym kodem, wyjaśnieniem i podpowiedzią, kiedy którą stosować.

💡 Szybki przegląd:

  • Przeniósł Pan wpis do wersji roboczej przez wp_update_post ze statusem draft, najbezpieczniejszy i odwracalny sposób
  • Uczynił Pan wpis prywatnym (private), widocznym tylko dla administratorów i redaktorów
  • Wysłał Pan wpis w przyszłość przez post_date, wpis znika z wyników wyszukiwania do nadejścia ustawionej daty
  • Usunął Pan wpis na zawsze przez wp_delete_post, ostateczność z ostrzeżeniami i kopią zapasową

Krok 1. Wersja robocza: zdejmujemy wpis z publikacji bez utraty danych

Najczęstszy scenariusz: trzeba tymczasowo ukryć wpis, ale zachować całą treść, URL i możliwość przywrócenia jednym kliknięciem. Przeniesienie do wersji roboczej to idealna opcja.

Zmienia się tylko pole post_status w tabeli wp_posts. Sam wpis, jego meta pola, załączniki i URL pozostają nietknięte. Gdy zdecyduje się Pan go przywrócić, zmienia Pan status z powrotem na publish.

Kod do zmiany statusu na draft. Proszę dodać go do functions.php motywu potomnego lub przez wtyczkę Code Snippets:

1/**
2 * Переводить пост у чернетку за ID.
3 *
4 * @param int $post_id ID поста, який потрібно зняти з публікації.
5 */
6function sd_unpublish_to_draft( $post_id ) {
7 wp_update_post( array(
8 'ID' => $post_id,
9 'post_status' => 'draft',
10 ) );
11}
12
13// Приклад виклику: знімаємо пост з ID = 42
14sd_unpublish_to_draft( 42 );

wp_update_post() aktualizuje wpis w bazie danych. Przekazujemy tylko ID i nową wartość post_status, całą resztę WordPress obsługuje sam. Żadne inne pola nie są zmieniane.

Kiedy stosować: tymczasowe ukrywanie wpisu do poprawy, automatyczna dezaktywacja wpisów z przeterminowaną datą ważności (na przykład promocje), programowa moderacja treści użytkowników.

Krok 2. Prywatny wpis: ukrywamy przed odwiedzającymi, zostawiamy redaktorom

Status prywatny to środek między publicznym a ukrytym. Wpis nie jest widoczny dla zwykłych odwiedzających, ale jest dostępny dla administratorów i redaktorów w panelu administracyjnym. Wygodny do materiałów wewnętrznych: instrukcji dla zespołu, wersji roboczych treści klienta, zamkniętych stron.

Różnica w stosunku do wersji roboczej: prywatny wpis jest technicznie „opublikowany" i może mieć swój URL, ale WordPress sprawdza uprawnienia użytkownika przed wyświetleniem. Odwiedzający bez roli read_private_posts zobaczy błąd 404.

Kod jest analogiczny do poprzedniego, zmienia się tylko status:

1/**
2 * Робить пост приватним — видимим лише адмінам і редакторам.
3 *
4 * @param int $post_id ID поста.
5 */
6function sd_unpublish_to_private( $post_id ) {
7 wp_update_post( array(
8 'ID' => $post_id,
9 'post_status' => 'private',
10 ) );
11}
12
13// Приклад виклику
14sd_unpublish_to_private( 42 );

Proszę zwrócić uwagę: jeśli na stronie są niestandardowe role użytkowników z własnymi uprawnieniami, proszę sprawdzić capabilities przed masowym użyciem. Domyślnie prywatne wpisy widzą role editor i administrator.

Kiedy stosować: treści premium w subskrypcji (w połączeniu z wtyczkami membership), wewnętrzna dokumentacja zespołu, ukrywanie wpisów do ponownego uzgodnienia z klientem przed ponowną publikacją.

Krok 3. Przyszła data: opóźnione zdjęcie z publikacji

Ciekawy trik: zamiast zmiany statusu można „wysłać wpis w przyszłość", ustawić datę publikacji na rok 2050. Wpis natychmiast znika z wyników wyszukiwania, ponieważ WordPress pokazuje tylko wpisy z datą ≤ bieżącemu momentowi.

Ta metoda nie zmienia post_status: wpis pozostaje publish. Z punktu widzenia WordPressa po prostu „jeszcze nie nadszedł". Plusem jest to, że w razie potrzeby można przywrócić rzeczywistą datę i wpis pojawi się ponownie.

Kod wykorzystuje pola post_date i post_date_gmt:

1/**
2 * Приховує пост, встановлюючи дату публікації у далеке майбутнє.
3 *
4 * @param int $post_id ID поста.
5 */
6function sd_unpublish_to_future( $post_id ) {
7 $future_date = '2050-12-31 23:59:59';
8
9 wp_update_post( array(
10 'ID' => $post_id,
11 'post_date' => $future_date,
12 'post_date_gmt' => get_gmt_from_date( $future_date ),
13 ) );
14}
15
16// Приклад виклику
17sd_unpublish_to_future( 42 );

get_gmt_from_date() konwertuje czas lokalny na GMT, WordPress przechowuje obie wersje daty. Proszę nie pomijać pola GMT: bez niego zachowanie przy zmianie strefy czasowej strony stanie się nieprzewidywalne.

Kiedy stosować: „opóźniona" publikacja treści zgodnie z harmonogramem, tymczasowe ukrywanie wiadomości bez zmiany statusu, scenariusze, gdzie post_status musi pozostać publish dla kompatybilności wstecznej z innymi wtyczkami.

Krok 4. Usunięcie: gdy wpis nie jest już w ogóle potrzebny

wp_delete_post() to operacja nieodwracalna. Wpis jest usuwany z bazy danych, a wraz z nim wszystkie meta pola, powiązania z taksonomiami i (opcjonalnie) załączniki.

Nie jest to „zdjęcie z publikacji" w ścisłym sensie. Ale w kontekście programowego zarządzania treścią usunięcie to czwarte, najbardziej drastyczne narzędzie. I wymaga ono zabezpieczeń.

Przed uruchomieniem proszę wykonać pełną kopię zapasową bazy danych. Poniższy skrypt najpierw wyświetla listę tego, co zostanie usunięte, a dopiero potem wariant bojowy.

1/**
2 * Видаляє пост. Спочатку — dry-run з виводом інформації, потім — бойове видалення.
3 *
4 * УВАГА: необоротна операція. Зробіть бекап перед запуском.
5 *
6 * @param int $post_id ID поста.
7 * @param bool $force_delete true — видалити назавжди (минаючи корзину), false — у корзину.
8 */
9function sd_delete_post_safe( $post_id, $force_delete = false ) {
10 $post = get_post( $post_id );
11
12 if ( ! $post ) {
13 error_log( "Post with ID {$post_id} not found." );
14 return;
15 }
16
17 // Dry-run: виводимо інформацію без видалення
18 error_log( sprintf(
19 'READY TO DELETE: ID=%d, title="%s", status=%s, attachments=%d',
20 $post->ID,
21 $post->post_title,
22 $post->post_status,
23 count( get_attached_media( '', $post_id ) )
24 ) );
25
26 // Розкоментуйте наступний рядок для реального видалення:
27 // wp_delete_post( $post_id, $force_delete );
28}
29
30// Dry-run: тільки виводить інформацію
31sd_delete_post_safe( 12341, false );

Flaga $force_delete:

  • false, wpis trafia do kosza (Trash), można go przywrócić w ciągu 30 dni.
  • true, usunięcie na zawsze, nie można przywrócić nawet przez bazę danych (bez kopii zapasowej).

Funkcja loguje przez error_log(), komunikaty pojawią się w wp-content/debug.log przy włączonym WP_DEBUG. W środowisku produkcyjnym proszę zastąpić to własnym mechanizmem powiadomień.

Kiedy stosować: automatyczne czyszczenie wpisów spamowych, usuwanie przeterminowanych treści (oferty pracy, wydarzenia), programowa rotacja treści z całkowitym usunięciem starych wpisów.

Porównanie czterech metod

Metoda

Status wpisu

Odwracalność

Widoczność dla czytelników

Widoczność w panelu administracyjnym

Kiedy stosować

Wersja robocza

draft

Pełna

Ukryty

Dla wszystkich ról z dostępem do wpisów

Tymczasowe ukrywanie, poprawki

Prywatny

private

Pełna

Ukryty

Dla administratorów i redaktorów

Treści wewnętrzne, premium

Przyszła data

publish

Pełna

Ukryty do daty

Dla wszystkich

Opóźniona publikacja, harmonogram

Usunięcie

-

Tylko z kosza (30 dni)

-

Tylko dla administratorów

Całkowite usunięcie, czyszczenie

⁉️🤔 Często zadawane pytania

Czym różni się zdjęcie z publikacji od usunięcia?

Zdjęcie z publikacji (draft/private/future) zachowuje wpis w bazie danych: treść, URL, załączniki i historia SEO pozostają. Usunięcie (wp_delete_post) całkowicie kasuje wpis. Do tymczasowego ukrywania proszę zawsze używać wersji roboczej, to bezpieczne i odwracalne w sekundę.

Która metoda nie wymaga zmiany post_status?

Wysłanie w przyszłość przez post_date. Wpis pozostaje publish, ale WordPress uważa go za „jeszcze nie nadszedł" i nie pokazuje go odwiedzającym. Może to być ważne, jeśli inne wtyczki lub snippet'y są powiązane ze statusem publish.

Czy można zdjąć z publikacji kilka wpisów jednocześnie?

Tak, proszę opakować wywołanie funkcji w pętlę po tablicy ID. Proszę dodać wp_die() lub ograniczenie liczby wpisów na raz, aby nie położyć strony przy masowej operacji: array_slice($post_ids, 0, 50) dla partii po 50.

Czy trzeba czyścić cache po programowej zmianie statusu?

Obowiązkowo. WordPress resetuje wewnętrzny cache wpisu przy wywołaniu wp_update_post(), ale zewnętrzny cache (wtyczki typu WP Rocket, cache serwerowy, CDN) trzeba resetować osobno. Proszę dodać wywołanie wp_cache_flush() lub hook clean_post_cache po zmianie statusu.

Czy bezpiecznie jest uruchamiać wp_delete_post w środowisku produkcyjnym?

Tylko z zabezpieczeniami. Przed wywołaniem: (1) proszę sprawdzić current_user_can('delete_posts'), (2) poprosić o potwierdzenie przez osobny nonce-token, (3) logować ID i tytuł usuwanego wpisu. I najważniejsze, kopia zapasowa. Nawet w koszu wpis żyje 30 dni, po czym WordPress usuwa go automatycznie.

Co stosować w Państwa przypadku: podsumowujący rozkład jazdy

Cztery metody pokrywają prawie każdy scenariusz programowego zarządzania publikacjami. Wybór sprowadza się do jednego pytania: czy trzeba zachować wpis?

  • Jeśli wpis ma być tymczasowo ukryty do poprawy, proszę brać wersję roboczą (draft). Kilka linijek, zero ryzyka.
  • Jeśli treść jest dla ograniczonego kręgu osób, status prywatny (private). Redaktorzy widzą, odwiedzający nie.
  • Jeśli trzeba ukryć wpis bez zmiany statusu, przyszła data (post_date na rok 2050). Sprytny, ale działający trik.
  • Jeśli wpis na pewno nie będzie potrzebny, usunięcie (wp_delete_post). Ale najpierw sucha próba i pełna kopia zapasowa.

Proszę zacząć od wrappera w functions.php dla jednej metody, na przykład wersji roboczej. Gdy zrozumie Pan logikę wp_update_post(), pozostałe trzy sposoby złoży Pan w pięć minut.

A jaką metodą Pan/Pani posługuje się do programowego zarządzania wpisami? Proszę napisać w komentarzach, ciekawie jest porównać podejścia.