Как вручную удалить запись из базы данных без конфликтов?
По какой-то причине у меня есть запись и страница с одинаковым ярлыком (slug), что вызывает зависание базы данных. Я не могу изменить ярлык ни у одной из них, поэтому мне нужно вручную удалить записи из базы данных и начать заново.
Я готов получить ID записи из wp_posts и wp_postmeta и вручную удалить каждую запись. Не нарушит ли это что-либо еще в базе данных, если у меня нет комментариев ни к записи, ни к странице?
РЕДАКТИРОВАНО
Я нашел этот скрипт и думаю, что он подходит, но я не уверен, удаляет ли он ревизии или что-то еще, что может остаться после ручного удаления записи
DELETE a,b,c
FROM wp_posts a
LEFT JOIN wp_term_relationships b ON ( a.ID = b.object_id )
LEFT JOIN wp_postmeta c ON ( a.ID = c.post_id )
WHERE a.ID = xxx;

Поместите этот код в файл в директории вашего плагина, и вы сможете удалять записи прямо из вашей установки WordPress, используя строку запроса.
/*
Plugin Name: Delete Specific Post
Description: Удалить запись навсегда!
Version: 0.1
Author: WPSE
License: GPL2
*/
add_filter('query_vars', 'delete_post_query_var');
function delete_post_query_var($vars){
$vars[] = 'delete_post';
return $vars;
}
add_action('admin_init', 'manually_delete_post', 0);
function manually_delete_post(){
if(!is_user_logged_in())
return;
if(!current_user_can('manage_options'))
return;
if(get_query_var('delete_post')){
$id = esc_attr(get_query_var('delete_post'));
$delete = wp_delete_post($id, true); //Параметр true принудительно удаляет запись, не помещая её в корзину
if($delete)
echo "Запись $id успешно удалена!";
else
echo "Запись $id не была удалена.";
exit;
}
}
Всё, что вам нужно сделать - убедиться, что вы авторизованы под учётной записью администратора, затем перейти по ссылке: http://yourdomain.com/wp-admin/?delete_post=POSTID

Отлично! Это альтернатива, с которой я могу работать. Мне говорили, что слишком много плагинов замедляет сайт... Но я все же склоняюсь к SQL-запросу.

@AlxVallejo WordPress по сути представляет собой набор плагинов, которые подключаются к другим функциям и предоставляют дополнительные хуки. При этом наличие сторонних скриптов в папке плагинов не замедлит ваш сайт — это полный миф. Плагин может замедлить систему только в том случае, если он активен. Активируйте его, когда он нужен, и деактивируйте, когда не нужен.

Я отдаю вам должное, но все же считаю, что ручное удаление записей в базе данных WP — это важный навык, о котором стоит рассказывать на случай, если запись вызывает проблемы. Не понимаю, почему все против написания SQL — активация плагина только для удаления записи из БД кажется, по моему мнению, глупой. Спасибо за инструкцию, я действительно могу использовать этот формат для других функций, используя параметр query_var.

@AlxVallejo Я не против использования MYSQL для этого. http://3-3.me/6DUn Я использовал это в прошлом, но для меня вход в mysql (через клиент или командную строку и выполнение этого запроса — это такая же работа, как активация плагина в моей директории и ввод строки запроса.)

@AlxVallejo сегодня кто-то еще прокомментировал мой ответ по поводу того, зачем использовать плагин, когда можно обойтись строкой кода или SQL. Моя точка зрения в том, что МНОГИЕ люди хотят беспроблемный вариант, как в фразе "разве ты не знаешь, что для этого есть плагин (приложение)", и это те же люди, которые любят использовать WordPress (в отличие от Drupal или многих других CMS).

Смотрите ниже https://wordpress.stackexchange.com/a/344090/99080 плагин с административной страницей для удаления нескольких записей одновременно

Недавно я столкнулся с проблемой при удалении произвольного типа записей (post-type) — повсюду были связи, а в базе данных не было каскадного удаления с помощью внешних ключей.
/* УДАЛЕНИЕ РЕВИЗИЙ */
DELETE posts
FROM
`prefix_posts` AS posts
INNER JOIN `prefix_posts` AS parents ON posts.post_parent = parents.ID
WHERE
parents.post_type = "myposttype"; /*ЗАМЕНИТЕ НА parents.ID = "yourID"*/
/* УДАЛЕНИЕ ЗАПИСЕЙ */
DELETE
FROM
`prefix_posts`
WHERE
post_type = "myposttype"; /*ЗАМЕНИТЕ НА ID = "yourID"*/
/* УДАЛЕНИЕ ОСТАВШИХСЯ МЕТАДАННЫХ */
DELETE
FROM
`prefix_postmeta`
WHERE
`prefix_postmeta`.`post_id` NOT IN(
SELECT
`prefix_posts`.`ID`
FROM
`prefix_posts`
);
Используете ли вы плагины, создающие дополнительные таблицы? (например, post-2-post)
/* ОРФАННЫЕ СВЯЗИ POST2POST */
DELETE
FROM
`prefix_p2p`
WHERE
`prefix_p2p`.`p2p_from` NOT IN(
SELECT
`prefix_posts`.`ID`
FROM
`prefix_posts`
);
DELETE
FROM
`prefix_p2p`
WHERE
`prefix_p2p`.`p2p_to` NOT IN(
SELECT
`prefix_posts`.`ID`
FROM
`prefix_posts`
);
Возможно, проще использовать встроенные функции WordPress... но если вам нужны SQL-запросы, смотрите выше.

Дополняя ответ @Brian Fegter выше, вы можете использовать приведенный ниже плагин для массового удаления записей. Он создает страницу в админке WordPress с текстовым полем для ввода ID страниц/записей, которые нужно удалить.
<?php
/*
Plugin Name: Delete Posts By ID
Description: Удаляет записи и страницы по ID
Version: 0.1
Author: WPSE
License: GPL2
*/
add_action( 'admin_menu', 'deletePostsMenu' );
function deletePostsMenu() {
add_menu_page(
'Удаление записей',
'Удаление записей',
'manage_options',
'delete-posts/delete-posts-admin-page.php',
'delete_posts_admin_page',
'dashicons-trash',
6
);
}
function delete_posts_admin_page() {
?>
<div class="wrap">
<h2>Удаление записей по ID</h2>
<p>Добавьте ID записей/страниц, разделяя их переносом строки</p>
<form action="" method="post">
<label for="deletePostsByID"></label>
<textarea name="deletePostsByID" id="ids" cols="30" rows="10"></textarea>
<input type="submit">
</form>
</div>
<?php
if (isset($_POST['deletePostsByID'])) {
delete_posts($_POST['deletePostsByID']);
return;
}
}
//add_action('admin_init', 'manually_delete_post', 0);
function delete_posts($submittedIDs){
if(!is_user_logged_in())
return;
if(!current_user_can('manage_options'))
return;
/* // Удаление пробелов
$stripped = str_replace(' ', '', $submittedIDs);*/
// Преобразование в массив
$idsArray = explode("\r\n",$submittedIDs);
echo '<ol>';
// Удаление записей по ID
foreach ($idsArray as $id){
$delete = wp_delete_post($id, false); //True принудительно удаляет запись, минуя корзину
if($delete)
echo "<li>Запись $id успешно удалена!</li>";
else
echo "<li>Запись $id не была удалена.</li>";
}
echo '</ol>';
exit;
}

Почему бы просто не использовать wp_delete_post()?
Когда запись или страница удаляется, всё, что связано с ней, также удаляется. Это включает комментарии, мета-поля записи и связи между записью и терминами таксономий.

Это фактически потребует от меня создания пользовательского меню и какого-то поля для ввода ID записи. Прямое обращение к phpmyadmin кажется быстрее, если я попаду в нужные области. Если только у вас нет лучшего места для этой функции?

вам нужен только список (массив) post_id для удаления. как вы формируете этот список (запросом, вручную,...) - это ваше дело... и затем делаете foreach для удаления записей

Ну, вам также понадобится шаблон страницы для выполнения функции... как иначе вы собираетесь выполнить функцию?

В WordPress есть множество способов вызвать вашу функцию... но это не относится к конкретному вопросу.
Как сказал Brian Fegter: WPSE предназначен для вопросов, а не для того, чтобы другие делали работу за вас. Если вам нужен разработчик, вам стоит нанять кого-то.

Хорошо, но это не отвечает на мой вопрос. Использование wp_delete_post неполно, так как вы не объясняете, как его использовать и почему это лучше, чем прямой SQL-запрос. Вы можете выполнить SQL-команду в SQL-окне phpmyadmin; С wp_delete_post вы можете... Другими словами, вашему ответу не хватает контекста.

Когда запись или страница удаляется, все, что с ними связано, также удаляется. Это включает комментарии, мета-поля записи и связи между записью и терминами таксономий. Разве этого недостаточно, чтобы вы подумали, что лучше использовать функцию WordPress? Если нет, я больше ничего не могу сделать для вас, извините... идите и делайте кучу SQL-запросов, совершайте ошибки и учитесь :)

@AlxVallejo В качестве жеста доброй воли я создал плагин, который не требует панели администратора и позволяет удалять конкретную запись через строку запроса. Смотри мой ответ на этот вопрос.

Хорошо, если вы хотите полностью удалить запись, вам нужно удалить пост/страницу из таблицы wp_term_relationships
. Но если проблема только в слаге (URL-адресе), вы можете обновить соответствующую запись в базе данных, и ваши слаги будут исправлены. Чтобы обновить слаг, выполните следующий запрос:
UPDATE wp_posts SET post_name = 'my-new-slug' WHERE ID = /*ваш ID поста здесь*/

В таблице wp_term_relationships есть поле object_id. Это post_id? Я думал, что посты должны быть отделены от связей с таксономиями и терминами.

Два вопроса: Можешь помочь написать скрипт для ручного удаления поста, включая post_meta и связи (wp_term_relationships) для заданного ID поста? И второй: Оптимизация базы данных очищает потерянные метаданные удалённых постов?

@AlxVallejo Дружеское замечание: WPSE предназначен для вопросов, а не для того, чтобы другие делали работу за вас. Если вам нужен разработчик, вам стоит нанять кого-то.

@BrianFegter Здесь и на SE люди постоянно рекомендуют SQL-скрипты, я не вижу ничего плохого в таком запросе... Ответ выше тоже не отвечает на вопрос, если только я не спрашивал, как изменить название слага.

@AlxVallejo Просить советы или подсказки — это одно. А явно просить кого-то сделать работу за вас, например: "Можете ли вы помочь написать скрипт для ручного удаления записи?" — не для этого форум.
