Удаление комментариев вместе с ответами в WordPress: руководство

Удаление комментариев вместе с ответами в WordPress

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

Как реализовать удаление ветки комментариев

Чтобы данная функция работала, добавьте код в файл functions.php вашей темы.

/**
 * Удаление всех дочерних комментариев (всего дерева) при удалении комментария
 */
add_action( 'delete_comment', 'del_child_comments_on_del_comment' );

function del_child_comments_on_del_comment( $comment_id ) {
    global $wpdb;

    $child_comments = $wpdb->get_col(
        "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'"
    );

    // Если дочерних комментариев нет, выходим из функции
    if( ! $child_comments ){
        return;
    }

    foreach( $child_comments as $val ){
        wp_delete_comment( $val );
    }
}

Ключевые моменты

Данная функция использует два важных элемента:

  • Хук: delete_comment
  • Функция: wp_delete_comment()

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

Что такое рекурсия?

Рекурсия — это процесс, при котором функция вызывает саму себя (простая рекурсия) или через другие функции (сложная рекурсия). Например, функция A вызывает функцию B, а функция B вызывает функцию A. Глубина рекурсии — это количество вложенных вызовов функций.

В начале я пытался использовать рекурсию напрямую, но это не сработало. Код только увеличивался в размерах. В какой-то момент, когда готовил себе чай, меня осенило: закрытие происходит, когда срабатывает хук delete_comment во время последующих вызовов функции wp_delete_comment(). Не нужно вызывать функцию внутри самой себя в привычном виде, т.е. будет использована косвенная рекурсия.

Честно говоря, я не могу представить реальную ситуацию в обычном блоге, когда такое удаление комментариев было бы особенно необходимо. Однако это логично и может пригодиться. Лично я предпочел реализовать это так, чтобы при удалении комментария с дочерними комментариями не терялся их смысл. Иначе получится, что будут комментарии без контекста.

Перемещение в корзину

После решения задачи с удалением комментариев, я также добавил функцию для перемещения комментариев в корзину и восстановления их оттуда с той же логикой.

Принцип тот же, только теперь используются фильтры:

  • trash_comment — перемещение в корзину
  • untrash_comment — восстановление из корзины

И соответствующие функции:

/**
 * Перемещение всех дочерних комментариев в корзину (всё дерево) при удалении комментария
 */
add_action( 'trash_comment', 'trash_child_comments_on_trash_comment' );
function trash_child_comments_on_trash_comment( $comment_id ) {
    global $wpdb;

    // Если дочерних комментариев нет, выходим из функции
    $child_comments = $wpdb->get_col(
        "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'"
    );
    if( ! $child_comments ){
        return;
    }

    foreach( $child_comments as $val ){
        wp_trash_comment( $val );
    }
}

add_action( 'untrash_comment', 'untrash_child_comments_on_untrash_comment' );
function untrash_child_comments_on_untrash_comment( $comment_id ) {
    global $wpdb;

    // Если дочерних комментариев нет, выходим из функции
    $child_comments = $wpdb->get_col(
        "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'"
    );
    if( ! $child_comments ){
        return;
    }

    foreach( $child_comments as $val ){
        wp_untrash_comment( $val );
    }
}

Упрощенный код для перемещения в корзину

Вот очень интересный код для тех, кто понимает PHP: упрощенная версия вышеуказанного кода. Здесь интересно, как можно использовать функцию current_filter() и необычный динамический вызов функции в PHP с помощью переменной $use_function( $val ). В общем, посмотрите сами:

/**
 * Перемещение всех дочерних комментариев в корзину (всё дерево) при удалении комментария
 */
add_action( 'trash_comment', 'trash_untrash_child_comments_with_parent' );
add_action( 'untrash_comment', 'trash_untrash_child_comments_with_parent' );
function trash_untrash_child_comments_with_parent( $comment_id ) {
    global $wpdb;

    // Если дочерних комментариев нет, выходим из функции
    $child_comments = $wpdb->get_col(
        "SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'"
    );
    if( ! $child_comments ){
        return;
    }

    foreach( $child_comments as $val ){
        // Получаем wp_trash_comment или wp_untrash_comment
        $use_function = 'wp_' . current_filter();
        $use_function( $val );
    }
}

Теперь вы знаете, как управлять комментариями и их дочерними элементами в WordPress. Эти простые функции помогут вам поддерживать порядок в комментариях на вашем сайте.

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *