Skip to content
🔒 4 Способи програмно зняти пост з публікації в wordpress

🔒 4 Способи програмно зняти пост з публікації в wordpress

Сайт упав після оновлення плагіна, потрібно терміново приховати проблемний пост, поки не пізно. А через тиждень повернути назад, коли баг полагодять. Або клієнт просить прибрати застарілу статтю з видачі, але не видаляти назавжди.

Ручне перемикання статусу через адмінку працює для одного-двох постів. Але коли таких десятки або логіка має спрацьовувати автоматично, потрібен програмний підхід. WordPress дає чотири способи зняти пост із публікації через PHP: від безпечної чернетки до повного видалення.

Нижче, кожен метод із готовим кодом, поясненням і підказкою, коли який застосовувати.

💡 Швидкий огляд:

  • Перевели пост у чернетку через wp_update_post зі статусом draft, найбезпечніший і оборотний спосіб
  • Зробили пост приватним (private), видно лише адміністраторам і редакторам
  • Відправили пост у майбутнє через post_date, пост зникає з видачі до настання заданої дати
  • Видалили пост назавжди через wp_delete_post, крайній захід із попередженнями та бекапом

Крок 1. Чернетка: знімаємо пост із публікації без втрати даних

Найчастіший сценарій: потрібно тимчасово приховати пост, але зберегти весь контент, URL і можливість повернути назад одним кліком. Переведення в чернетку, ідеальний варіант.

Змінюється лише поле post_status у таблиці wp_posts. Сам пост, його мета-поля, вкладення та URL залишаються недоторканими. Коли вирішите повернути, змінюєте статус назад на publish.

Код для зміни статусу на draft. Додайте в functions.php дочірньої теми або через плагін 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() оновлює запис у БД. Ми передаємо лише ID і нове значення post_status, усе інше WordPress підхоплює сам. Жодні інші поля не змінюються.

Коли застосовувати: тимчасове приховування поста на доопрацювання, автоматична деактивація постів із простроченим терміном актуальності (наприклад, акції), програмна модерація користувацького контенту.

Крок 2. Приватний пост: приховуємо від відвідувачів, залишаємо редакторам

Приватний статус — це середина між публічним і прихованим. Пост не видно звичайним відвідувачам, але доступний адміністраторам і редакторам в адмінці. Зручно для внутрішніх матеріалів: інструкцій для команди, чернеток клієнтського контенту, закритих сторінок.

Відмінність від чернетки: приватний пост технічно «опублікований» і може мати свій URL, але WordPress перевіряє права користувача перед показом. Відвідувач без ролі read_private_posts побачить 404.

Код аналогічний попередньому, змінюється лише статус:

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 );

Зверніть увагу: якщо на сайті є користувацькі ролі з кастомними правами, перевірте capabilities перед масовим використанням. За замовчуванням приватні пости бачать ролі editor і administrator.

Коли застосовувати: преміум-контент за підпискою (у зв'язці з membership-плагінами), внутрішня документація команди, приховування постів для переузгодження з клієнтом перед повторною публікацією.

Крок 3. Майбутня дата: відкладене зняття з публікації

Цікавий прийом: замість зміни статусу можна «відправити пост у майбутнє», задати дату публікації на 2050 рік. Пост миттєво зникає з видачі, тому що WordPress показує лише пости з датою ≤ поточному моменту.

Цей метод не змінює post_status: пост залишається publish. Він просто «ще не настав» із погляду WordPress. Плюс, за потреби можна повернути реальну дату, і пост знову з'явиться.

Код використовує поля post_date і 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() конвертує локальний час у GMT, WordPress зберігає обидві версії дати. Не нехтуйте GMT-полем: без нього поведінка при зміні часового поясу сайту стане непередбачуваною.

Коли застосовувати: «відкладена» публікація контенту за розкладом, тимчасове приховування новин без зміни статусу, сценарії, де post_status має залишитися publish для зворотної сумісності з іншими плагінами.

Крок 4. Видалення: коли пост не потрібен зовсім

wp_delete_post(), необоротна операція. Пост видаляється з бази, а разом із ним, усі мета-поля, зв'язки з таксономіями та (опціонально) вкладення.

Це не «зняття з публікації» в строгому сенсі. Але в контексті програмного управління контентом видалення, четвертий, найжорсткіший інструмент. І він вимагає запобіжників.

Перед запуском зробіть повний бекап бази даних. Скрипт нижче спочатку виводить список того, що буде видалено, і лише потім, бойовий варіант.

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 );

Прапорець $force_delete:

  • false, пост потрапляє в кошик (Trash), його можна відновити протягом 30 днів.
  • true, видалення назавжди, відновити не можна навіть через базу (без бекапу).

Функція логує через error_log(), повідомлення з'являться у wp-content/debug.log при ввімкненому WP_DEBUG. У продакшені замініть на свій механізм сповіщень.

Коли застосовувати: автоматичне очищення спам-постів, видалення простроченого контенту (вакансії, заходи), програмна ротація контенту з повним видаленням старих записів.

Порівняння чотирьох методів

Метод

Статус поста

Оборотність

Видимість для читачів

Видимість в адмінці

Коли застосовувати

Чернетка

draft

Повна

Приховано

Усім ролям із доступом до постів

Тимчасове приховування, доопрацювання

Приватний

private

Повна

Приховано

Адмінам і редакторам

Внутрішній контент, преміум

Майбутня дата

publish

Повна

Приховано до дати

Усім

Відкладена публікація, розклад

Видалення

-

Тільки з кошика (30 днів)

-

Тільки адмінам

Повне видалення, очищення

⁉️🤔 Часті запитання

Чим відрізняється зняття з публікації від видалення?

Зняття з публікації (draft/private/future) зберігає пост у базі: контент, URL, вкладення та SEO-історія залишаються. Видалення (wp_delete_post) стирає запис повністю. Для тимчасового приховування завжди використовуйте чернетку — це безпечно й оборотно за секунду.

Який метод не вимагає зміни post_status?

Відправка в майбутнє через post_date. Пост залишається publish, але WordPress вважає його «ще не насталим» і не показує відвідувачам. Це може бути важливо, якщо інші плагіни або сніпети зав'язані на статус publish.

Чи можна зняти з публікації одразу кілька постів?

Так, обгорніть виклик функції в цикл по масиву ID. Додайте wp_die() або обмеження на кількість постів за раз, щоб не покласти сайт при масовій операції: array_slice($post_ids, 0, 50) для батча по 50.

Чи потрібно очищати кеш після програмної зміни статусу?

Обов'язково. WordPress скидає внутрішній кеш поста при виклику wp_update_post(), але зовнішній кеш (плагіни на кшталт WP Rocket, серверний кеш, CDN) потрібно скидати окремо. Додайте виклик wp_cache_flush() або хук clean_post_cache після зміни статусу.

Чи безпечно запускати wp_delete_post у продакшені?

Тільки із запобіжниками. Перед викликом: (1) перевірте current_user_can('delete_posts'), (2) запитайте підтвердження через окремий nonce-токен, (3) логуйте ID і заголовок поста, що видаляється. І головне, бекап. Навіть у кошику пост живе 30 днів, після чого WordPress видаляє його автоматично.

Що використовувати у вашому випадку: підсумковий розклад

Чотири методи закривають майже будь-який сценарій програмного управління публікаціями. Вибір зводиться до одного запитання: чи потрібно зберегти пост?

  • Якщо пост тимчасово приховати на доопрацювання, беріть чернетку (draft). Пара рядків, нуль ризику.
  • Якщо контент для обмеженого кола осіб, приватний статус (private). Редактори бачать, відвідувачі, ні.
  • Якщо потрібно приховати пост без зміни статусу, майбутня дата (post_date у 2050 рік). Хитрий, але робочий прийом.
  • Якщо пост точно не знадобиться, видалення (wp_delete_post). Але спочатку dry-run і повний бекап.

Почніть з обгортки в functions.php для одного методу, наприклад, чернетки. Коли зрозумієте логіку wp_update_post(), решта трьох способів зберуться за п'ять хвилин.

А яким методом ви користуєтеся для програмного управління постами? Напишіть у коментарях, цікаво порівняти підходи.