Автоматически проверять дочерние категории / термины при проверке родительской категории - PullRequest
1 голос
/ 05 февраля 2020

У меня есть этот Континент -> Настройка категории страны для пользовательского типа записи.

- Africa
    - Uganda
    - Zambia
    - Zimbabwe
- Asia
    - Afghanistan
    - Bahrain
    - Bangladesh
    - Bhutan

Я думаю, что это можно решить с помощью какой-то функции WordPress, которая будет автоматически проверять все дочерние категории (страны континент), если отмечена родительская категория (Африка), а не наоборот, как этот плагин.

Например, если отмечен Africa, все африканские страны должны быть проверены автоматически. Если отмечен только Zimbabwe, родительская категория Africa не должна проверяться.

Также, когда Africa не установлен не отмечен , африканские страны также должны быть автоматически отключены.

1 Ответ

2 голосов
/ 05 февраля 2020

РЕДАКТИРОВАТЬ:

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

Новый ответ:

Хорошо Я очень горжусь этим результатом на самом деле. Проведя некоторые исследования, я наткнулся на хук set_object_terms, который запускается в конце функции wp_set_object_terms(), расположенной в /wp-includes/taxonomy.php .

На этом хуке он принимает 6 аргументов: $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids. Важными здесь для "проверки детей" и" un проверки детей" являются $tt_ids и $old_tt_ids. Это массивы новых идентификаторов терминов и старых идентификаторов терминов, соответственно.

Это позволяет нам сравнить два массива и посмотреть, какие идентификаторы были добавлены добавлены , а какие удалены . Это важно, потому что вы можете проверить Африку, затем снять флажок с Африки и теперь проверить Азию. Вот удобная функция, которая позволит вам увидеть оба различия:

function array_diff_once($a1, $a2){
    foreach($a2 as $val){
        if( false !== ($pos = array_search($val, $a1)) ){
            unset($a1[$pos]);
        }
    }

    return array_values($a1);
}

Таким образом, вместо использования хука save_post, мы можем вместо этого сравнить добавленные / удаленные термины на хуке set_object_terms и добавить / удалить дочерние термины для каждого там. Обратите внимание, что это также может срабатывать в неподходящее время (автосохранение, если публикация не опубликована и т. Д. c, поэтому я поставил несколько условий отмены.)

add_action( 'set_object_terms', 'so_60079535_toggle_child_terms', 10, 6 );
function so_60079535_toggle_child_terms( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ){
    // Abort if this is an autosave/backup
    if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;

    // Abort if no ids are set from before or now
    if( empty($tt_ids) && empty($old_tt_ids) )
        return;

    // Only do things if this post is published (front facing)
    $post_status = get_post_status( $object_id );
    if( $post_status != 'publish' )
        return;

    // What terms where ADDED, and which were REMOVED?
    $added_terms   = array_diff_once( $tt_ids, $old_tt_ids );
    $removed_terms = array_diff_once( $old_tt_ids, $tt_ids );

    // Any terms ADDED this time?
    if( !empty($added_terms) ){
        foreach( $added_terms as $added_term ){
            // Do any of these added terms have children?
            if( $added_child_terms = get_term_children( $added_term, $taxonomy ) ){
                // Append those children
                wp_set_object_terms( $object_id, $added_child_terms, $taxonomy, true );
            }
        }
    }

    // Any terms REMOVED?
    if( !empty($removed_terms) ){
        foreach( $removed_terms as $removed_term ){
            // Do any of the removed terms have children?
            if( $removed_child_terms = get_term_children( $removed_term, $taxonomy ) ){
                // Remove them all
                wp_remove_object_terms( $object_id, $removed_child_terms, $taxonomy, true );
            }
        }
    }
}

Я на самом деле разместите этот код на моем тестовом сайте, и он, кажется, работает безупречно, независимо от того, насколько глубоко (термины «внучка» / «великий внук») термины и сколько добавляется или удаляется одновременно. Еще одна приятная вещь - этот хук уже передан параметру $taxonomy, поэтому он должен работать автоматически для всех без исключения таксономий, которые когда-либо добавлялись. Если это нежелательно, вы всегда можете очень легко добавить условие прерывания для некоторых таксономий, типов записей и т. Д. c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...