Видаляємо коментарі гілками
Пропоную увазі хук видалення всіх дочірніх коментарів при видаленні коментаря, тобто. ми видаляємо коментар і разом з ним видаляються всі його дочірні коментарі, і дочірні дочірні, і так далі. Іншими словами, при видаленні коментаря відійде вся гілка відповідей на нього.
Щоб “видалення гілками” почало працювати, вставляємо код у файл теми functions.php.
/* Видалення всіх дочірніх коментарів (усього дерева) при видаленні коментаря -------------------------------------------------- -------------------------------- */ add_action('delete_comment', 'del_child_comments_on_del_comment'); function del_child_comments_on_del_comment($comment_id){ Global $wpdb; // якщо немає дітей, повертаємо if( !$child_comments = $wpdb->get_col("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'") ) 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
і функції: wp_trash_comment()
, wp_untrash_comment()
:
/* Переміщення до кошика всіх дочірніх коментарів (вся глибина дерева), при видаленні коментаря -------------------------------------------------- -------------------------------------------------- */ add_action('trash_comment', 'trash_child_comments_on_trash_comment'); function trash_child_comments_on_trash_comment($comment_id){ Global $wpdb; // якщо немає дітей, повертаємо if( !$child_comments = $wpdb->get_col("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'") ) 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; // якщо немає дітей, повертаємо if( !$child_comments = $wpdb->get_col("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'") ) 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; // якщо немає дітей, повертаємо if( !$child_comments = $wpdb->get_col("SELECT comment_ID FROM $wpdb->comments WHERE comment_parent='$comment_id'") ) return; foreach( $child_comments as $val ){ // отримаємо wp_trash_comment або wp_untrash_comment $use_function = 'wp_'. current_filter(); $use_function($val); } }