WordPress Multisite - глобальные категории

21

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

Какой лучший способ сделать это?

ана
источник
Я думаю, что создание категорий, присвоенных глобальной переменной, а затем импортировать на тему инициализации.
Кайзер
4
Я думаю, что этот вопрос такой же, как и разделить одну таксономию по нескольким блогам в версии 3.0 . Однако этот вопрос не получил хорошего ответа. Это интересный вопрос, я предложу вознаграждение за это.
Ян Фабри

Ответы:

14
function __add_global_categories( $term_id )
{
    if ( get_current_blog_id() !== BLOG_ID_CURRENT_SITE || ( !$term = get_term( $term_id, 'category' ) ) )
        return $term_id; // bail

    if ( !$term->parent || ( !$parent = get_term( $term->parent, 'category' ) ) )
        $parent = null;

    global $wpdb;

    $blogs = $wpdb->get_col( "SELECT blog_id FROM {$wpdb->blogs} WHERE site_id = '{$wpdb->siteid}'" );
    foreach ( $blogs as $blog ) {
        $wpdb->set_blog_id( $blog );

        if ( $parent && ( $_parent = get_term_by( 'slug', $parent->slug, 'category' ) ) )
            $_parent_ID = $_parent->term_id;
        else
            $_parent_ID = 0;

        wp_insert_term( $term->name, 'category',  array(
            'slug' => $term->slug,
            'parent' => $_parent_ID,
            'description' => $term->description
        ));
    }

    $wpdb->set_blog_id( BLOG_ID_CURRENT_SITE );
}
add_action( 'created_category', '__add_global_categories' );

Это будет выполняться всякий раз, когда на главном сайте добавляется категория . Несколько предостережений / пунктов, которые стоит упомянуть;

  • Если у вас много блогов, эта функция может стать довольно интенсивной.
  • В среднем мы выполняем от 5 до 8 запросов (возможно, больше) на блог - в зависимости от скорости вашей базы данных, эта функция может потребоваться разбить на части.
  • Только недавно добавленные категории синхронизируются. Обновления и удаления категорий нет (код необходимо будет пересмотреть).
  • Если у вновь добавленной категории есть родительский элемент, и родительский объект не может быть найден в рассматриваемом многосайтовом блоге, категория будет создана без родительского элемента (это должно иметь место только в том случае, если родительская категория была создана до установки этой функции).
TheDeadMedic
источник
1
Есть или может быть плагин, который делает это? Вместе с правками и удалениями? И страницу настроек, чтобы выбрать, к каким таксономиям и к каким дочерним сайтам ее применять?
Маркус Даунинг
На самом деле, вы бы возражали, если бы я использовал ваш код в качестве отправной точки для написания плагина?
Маркус Даунинг
Никаких проблем - мои ответы подпадают под лицензию обмена стека, cc-wiki с указанием авторства требуется :)
TheDeadMedic
11

О, воскресенье промедление ...

https://github.com/maugly/Network-Terminator

  • Позволяет массово добавлять термины в сети
  • Вы можете выбрать, какие сайты будут затронуты
  • Работает с пользовательскими таксономиями
  • Не удаляет
  • Не синхронизируется

Это то, что я сделал за последние несколько часов, и сейчас у меня нет времени на дополнительные тесты. Во всяком случае - это работает для меня! .)

Попробуйте. Также реализована функция «пробный запуск», так что вы можете проверить результат, прежде чем что-то делать.

Обновление -> Скриншоты:

Перед действием:

Перед действием

После пробного запуска:

После пробного запуска

Плагин, связанный выше, добавляет пользовательский интерфейс, но в этой функции происходит почти все важное:

        <?php function mau_add_network_terms($terms_to_add, $siteids, $testrun = false) {

        // check if this is multisite install
        if ( !is_multisite() )
            return 'This is not a multisite WordPress installation.';

        // very basic input check
        if ( empty($terms_to_add) || empty($siteids) || !is_array($terms_to_add) || !is_array($siteids) )
            return 'Nah, I eat only arrays!';

        if ($testrun) $log = '<p><em>No need to get excited. This is just a test run.</em></p>';
        else $log = '';

        // loop thru blogs
        foreach ($siteids as $blog_id) :

            switch_to_blog( absint($blog_id) );

            $log .= '<h4>'.get_blog_details(  $blog_id  )->blogname.':</h4>';
            $log .= '<ul id="ntlog">';

            // loop thru taxonomies
            foreach ( $terms_to_add as $taxonomy => $terms ) {

                // check if taxonomy exists
                if ( taxonomy_exists($taxonomy) ) {
                    // get taxonomy name
                    $tax_name = get_taxonomy($taxonomy);
                    $tax_name = $tax_name->labels->name;

                    //loop thru terms   
                    foreach ( $terms as $term ) {

                        // check if term exists
                        if ( term_exists($term, $taxonomy) ) {
                            $log .= "<li class='notice' ><em>$term already exists in the $tax_name taxonomy - not added!</em></li>";

                        } else {

                            // if it doesn't exist insert the $term to $taxonomy
                            $term = strip_tags($term);
                            $taxonomy = strip_tags($taxonomy);
                            if (!$testrun)
                                wp_insert_term( $term, $taxonomy );
                            $log .= "<li><b>$term</b> successfully added to the <b>$tax_name</b> taxonomy</li>"; 
                        }
                    }
                } else {
                    // tell our log that taxonomy doesn't exists
                    $log .= "<li class='notice'><em>The $tax_name taxonomy doesn't exist! Skipping...</em></li>"; 
                }
            }

            $log .= '</ul>';    

            // we're done here
            restore_current_blog();

        endforeach;
        if ($testrun) $log .= '<p><em>No need to get excited. This was just the test run.</em></p>';
        return $log;
    } ?>

Я вернусь и отредактирую это с дополнительной информацией позже (если необходимо).

Это далеко от совершенства (см. Известные проблемы в главе плагина).
Любые отзывы приветствуются!

Михал Мау
источник
3
Мне нравится, когда люди создают плагины в ответ на вопросы! Вы заслуживаете щедрости!
Ян Фабри
Спасибо за вашу поддержку @Jan Fabry. Я буду счастлив, если кто-то рядом со мной действительно найдет эту вещь полезной.
Михал Мау
5

Ответ TheDeadMedic выглядит неплохо, но я решил использовать другой подход к проблеме. Вместо дублирования одних и тех же терминов на многих сайтах, я заставил другие сайты использовать таблицы терминов на домашнем сайте.

add_action('init', 'central_taxonomies');

function central_taxonomies () {
  global $wpdb;

  $wpdb->terms = "wp_terms";
  $wpdb->term_taxonomy = "wp_term_taxonomy";
}

Это заменяет имя таблицы wp_2_termsна wp_termsи т. Д. Вы, конечно, должны проверить в своей базе данных, чтобы убедиться в точном названии таблиц, которые могут отличаться, если вы измените свой префикс.

Вы можете запустить это из плагина или темы (хотя я рекомендую плагин). Я могу начать плагин, чтобы сделать это в какой-то момент. У этого подхода есть два недостатка:

  • Он активен только на дочерних сайтах, на которых активирован плагин. Нет способа обеспечить это с родительского сайта.
  • Это относится ко всем таксономиям, а не только к избранным.

Этот подход является гибким - его можно адаптировать для извлечения категорий из любого блога, а не только из центрального.


Обновление: я превратил это в плагин, который можно активировать по всему сайту, если вам нужно: MU Central Taxonomies

Маркус Даунинг
источник
С этим подходом есть большая проблема: отношения между постами и терминами могут быть неправильными. Таблица term_relationships содержит это отношение на основе идентификатора поста и идентификатора термина. Но всегда есть вероятность, что сообщения на дочерних сайтах имеют одинаковый идентификатор. Изменение условий для одного сообщения может непредсказуемо повлиять на другое сообщение в другом блоге.
Ань Чан
Правильно, term_relationshipsтаблица не должна быть включена. Я обнаружил и исправил это давно в плагине, но никогда не обновлял этот ответ, чтобы соответствовать.
Маркус Даунинг