Как удалить «Без категории» из сообщений с более чем одной категорией?

9

Так недавно я перевел клиента из Blogger в Wordpress.

Когда сообщения импортировались из блоггера, он сохранял «метки» блоггера как «теги» в Wordpress. Поскольку вместо этого я хотел бы использовать их в качестве категорий, я использовал плагин для преобразования всех тегов в категории.

Это работало отлично и денди, но оно оставило Uncategorized на всех моих сообщениях. Так что теперь у меня есть около 900 сообщений, которые имеют свои правильные категории, а также «Без рубрики».

Поэтому моя цель состоит в том, чтобы удалить «Без рубрики» из всех 900 сообщений, но я изо всех сил пытаюсь найти быстрый способ сделать это.

Кто-нибудь знает, как я мог бы сделать это массовым методом?

Corey
источник
Как выглядит код, отображающий категории?
SarahCoding
Там нет кода, это в админке.
Кори
Я думаю, вам просто нужно удалить Uncategorizedкатегорию.
SarahCoding
1
@ Dan9, мы не можем просто удалить Uncategorizedкатегорию, это категория сообщений по умолчанию, назначаемая сообщениям, когда они не назначены, но мы можем сделать это по умолчанию, перейдя по Settings-->Writing
адресу
Вам нужна категория по умолчанию в WordPress. «Без рубрики» - это категория WordPress по умолчанию. Что бы я ни предложил, вы можете либо изменить категорию по умолчанию с «Без категории» на другую, либо изменить имя категории по умолчанию.
волынщик

Ответы:

8

С установленным wp-cli вы можете запустить скрипт bash, подобный этому, чтобы удалить категорию «без категории» из всех сообщений с более чем одной категорией.

#!/bin/bash

for post in $(wp post list --field=ID)
do
  count=$(wp post term list $post 'category' --fields='name' --format="count")
  if [ "$count" -gt "1" ]
  then
    wp post term remove $post category 'uncategorized'
  fi
done

Сохраните это как-то так, delete_uncategorized.bashа затем запустите bash delete_uncategorized.bashиз командной строки.

Симон Коссар
источник
WP Cli является хорошим подходом.
JMau
Требуется ли SSH-доступ к серверу, на котором размещен сайт? У меня есть только доступ к SFTP, насколько я знаю на WP Engine. Я знаю, что они были бета-тестированием WP CLI в прошлом, но не уверен в статусе.
Кори
Но в принципе я мог бы просто преобразовать этот метод в сценарий PHP.
Кори
Вы можете загрузить базу данных на свой локальный компьютер и запустить там скрипт.
Симон Коссар
4

Вот плагин, который после активации перебирает все сообщения, которые находятся в категории без категории. Если это в другой категории, он удаляет без категории. Далее, когда сообщение сохранено, оно выполняет ту же проверку.

<?php
/**
 * Plugin Name: Remove Uncategorized
 * Description: Removes the uncategorized category if there's another category.
 * Author: Nathan Johnson
 * Licence: GPL2+
 * Licence URI: https://www.gnu.org/licenses/gpl-2.0.en.html
 */

//* Don't access this file directly
defined( 'ABSPATH' ) or die();

register_activation_hook( __FILE__ , 'wpse_106269_activation' );

function wpse_106269_activation() {
  $args = array(
    'posts_per_page'   => -1,
    'offset'           =>  0,
    'category'         => get_option( 'default_category' ),
    'post_status'      => 'any',
    'suppress_filters' => true,
  );
  $posts = get_posts( $args );
  foreach( $posts as $post ) {
    wpse_106269_maybe_remove_uncategorized_category( $post->ID );
  }
}

add_action( 'save_post', 'wpse_106269_save_post', 10, 3 );

function wpse_106269_save_post( $id, $post, $update ) {
  remove_action( 'save_post', 'wpse_106269_save_post', 10, 3 );
  wpse_106269_maybe_remove_uncategorized_category( $id );
  add_action( 'save_post', 'wpse_106269_save_post', 10, 3 );
}

function wpse_106269_maybe_remove_uncategorized_category( $id ) {
  $categories = get_the_category( $id );
  $default = get_cat_name( get_option( 'default_category' ) );
  if( count( $categories ) >= 2 && in_category( $default, $id ) ) {
    wp_remove_object_terms( $id, $default, 'category' );
  }
}
Натан Джонсон
источник
2

Немного опоздал на вечеринку, ребята, но мне просто нужно было сделать это самому. Обходной путь будет через SQL-запросы в phpmyadmin, что-то вроде:

SELECT *
FROM `wp_term_relationships`
WHERE `term_taxonomy_id`
IN ( SELECT `term_taxonomy_id`
FROM `wp_term_taxonomy`
WHERE `taxonomy` = 'category' )
GROUP BY `object_id`
HAVING ( COUNT( `object_id` ) >1 )

(замените префикс wp_ вашим префиксом) Обычно «uncategorized» имеет term_taxonomy_id = 1. Приведенный выше запрос группирует все идентификаторы сообщений, если существует более одной категории, поэтому, естественно, «uncategorized» отображается первым в группе. Поэтому выберите все те строки, которые имеют term_taxonomy_id = 1, и удалите их. И это все!

Теперь все, что вам нужно сделать, это отредактировать поле count "uncategorized" ( term_taxonomy_id = 1) в таблице wp_term_taxonomy . Подсчет количества - это количество статей, перечисленных в этой категории, но конкретное поле не обновляется автоматически.

Если вы зайдете в панель администрирования wp, раздел категорий, старый (неправильный) номер счета по-прежнему будет отображаться, но если вы нажмете этот номер и перейдете к списку сообщений «некатегоризовано», WordPress обычно пересчитывает сообщения, связанные с этим. категория. Правильный счетчик будет отображаться в правом верхнем углу, поэтому перейдите в свою базу данных и отредактируйте поле количества соответствующим образом :)

Изменить: На самом деле, счет в конечном итоге обновляется, но не сразу, так что вы можете пропустить обновление счетчика вручную.

TechSmurfy
источник
0

Основываясь на ответе @ TechSmurfy, я придумал это:

create temporary table tr_to_delete (object_id INT);
insert into tr_to_delete SELECT object_id FROM wp_term_relationships tr, wp_term_taxonomy tt WHERE tr.term_taxonomy_id=tt.term_taxonomy_id and tt.taxonomy='category' GROUP BY object_id HAVING COUNT(*) >1;
delete from wp_term_relationships where term_taxonomy_id=1 and object_id in (select object_id from tr_to_delete);
drop temporary table tr_to_delete;
Джейми Чонг
источник
0

Что ж, самый простой способ, не связываясь с базой данных, - это создать новую категорию, установить ее по умолчанию, а затем перейти в список сообщений и отсортировать по категории «без категории». Отредактируйте эти сообщения и удалите тег категории «без категории».

После этого вы можете удалить категорию. Категория не может быть удалена, если какой-либо пост использует эту категорию.

Рик Хеллуэлл
источник
0

Поработав и попробовав все подходы, описанные выше, я обнаружил, что этот sql-запрос является самым быстрым способом удаления сообщений из категории «Без категории», в которых имеется более одного кота.

Использование WP-CLI было бы лучшим вариантом, если бы он не был медленным, как ад.

В моем случае мне пришлось удалить более 50 000 срочных отношений, так что это просто НЕУДАЧИЛО.

DELETE FROM wp_term_relationships WHERE term_taxonomy_id=1 AND object_id IN ( SELECT object_id  FROM (
SELECT tr.object_id FROM wp_term_relationships tr, wp_term_taxonomy tt WHERE tr.term_taxonomy_id=tt.term_taxonomy_id and tt.taxonomy='category' GROUP BY tr.object_id HAVING COUNT(*) >1
) as temp_table);
dulesaga
источник