Видаляємо коментарі гілками

Пропоную увазі хук видалення всіх дочірніх коментарів при видаленні коментаря, тобто. ми видаляємо коментар і разом з ним видаляються всі його дочірні коментарі, і дочірні дочірні, і так далі. Іншими словами, при видаленні коментаря відійде вся гілка відповідей на нього.

Щоб “видалення гілками” почало працювати, вставляємо код у файл теми 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);
	}
}

Залишити коментар

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *