WordPress как на ладони
Недорогой хостинг для сайтов на WordPress: wordpress.jino.ru Получай пассивный доход от сайта с помощью браузерных PUSH уведомлений

Комментарии в WordPress

Комментарии это отдельная сущность в структуре данных WordPress. Связывают комментарии с записями (постами, таблица wp_posts) и пользователями (таблица wp_users).

Читайте также:

Структура таблиц комментариев в БД

В базе данных WordPress за комментарии отвечают две таблицы: wp_comments и wp_commentmeta. Разберем каждую.

См. полную схему таблиц.

wp_comments

Содержит основные данные комментария.

Поле Описание и пример значения
comment_ID ID комментария. (7999)
comment_post_ID ID записи к которой относится комментарий. Равно колонке ID в таблице wp_posts (4896)
comment_author Имя автора комментария. (Mseo)
comment_author_email email автора комментария. (maoru@yandex.ru)
comment_author_url URL автора комментария. (http://maeo.ru)
comment_author_IP IP автора комментария. Автоматически НЕ определяется. (95.79.52.2)
comment_approved Одобрен коммент или нет. (1/0)
comment_agent User agent автора комментария. (Mozilla/5.0 (Windows...)
comment_date Дата и время отправки комментария. В MySQL формате. (2015-09-01 16:28:33)
comment_date_gmt Дата и время отправки комментария в GMT зоне. (2015-09-01 16:28:33)
comment_content Текст комментария. (Приветствую, выше указанный...)
comment_karma Карма комментария. (0)
comment_type Тип комментария. comment - тип обычного комментария (до версии 5.0 был пустой строкой '').
comment_parent ID родительского комментария. (7998)
user_id ID пользователя, который опубликовал комментарий. Равно колонке ID в таблице wp_users (123)

ВАЖНО! Длинна значение поля comment_type = 20 символов! Пример максимально допустимой длины: new_question_comment.

Пример того, как такое ограничение может испортить код: допустим у нас есть дополнительный типа комментария question_comment. Некоторые из таких комментариев со временем попадают в архив, при этом нам нужно добавить префикс archive- к типу. Делаем мы это так:

// $com - это объект обрабатываемого комментария
wp_update_comment( [
	'comment_ID'   => $com->comment_ID,
	'comment_type' => "archive-$com->comment_type", // archive-question_comment
] );

В результате такое обновление не сработает и что важнее мы не увидим никакой ошибки - ничего! Чтобы понять почему не обновляется придется лезть в дебри ядра ВП.

меню

wp_commentmeta

Содержит дополнительные данные комментария. Из коробки в эту таблицу ничего не записывается, она нужна для расширения функционала комментирования, чтобы добавить комментариям дополнительные данные.

Вывод комментариев в теме

Для вывода комментариев на странице нужно использовать функцию comments_template() в том месте, где нам нужно показать список комментариев. Эта функция сделает запрос и соберет комментарии для страницы.

Также в тему нужно добавить файл comments.php. В нём нужно описать вывод комментариев:

  • Нужно проверить есть ли комментарии на странице. Делается это с помощью переменной $comemnts, которая устанавливается в comments_template() - $comments = & $wp_query->comments и доступна в этом файле. Также проверить наличие комментариев на странице можно функцией have_comments(). Далее если:
    • комментарии есть, нужно использовать функцию wp_list_comments() чтобы вывести список комментариев.
    • комментариев нет, нужно вывести сообщение что их нет.
  • Нужно вывести форму комментирования. См. comment_form().

Пример файла comments.php из темы Twenty Twenty:

<?php
/**
 * The template file for displaying the comments and comment form for the
 * Twenty Twenty theme.
 *
 * @package WordPress
 * @subpackage Twenty_Twenty
 * @since Twenty Twenty 1.0
 */

/*
 * If the current post is protected by a password and
 * the visitor has not yet entered the password we will
 * return early without loading the comments.
*/
if ( post_password_required() ) {
	return;
}

if ( $comments ) {
	?>

	<div class="comments" id="comments">

		<?php
		$comments_number = absint( get_comments_number() );
		?>

		<div class="comments-header section-inner small max-percentage">

			<h2 class="comment-reply-title">
				<?php
				if ( ! have_comments() ) {
					_e( 'Leave a comment', 'twentytwenty' );
				}
				elseif ( 1 === $comments_number ) {
					/* translators: %s: Post title. */
					printf( _x( 'One reply on “%s”', 'comments title', 'twentytwenty' ), get_the_title() );
				}
				else {
					printf(
					/* translators: 1: Number of comments, 2: Post title. */
						_nx(
							'%1$s reply on “%2$s”',
							'%1$s replies on “%2$s”',
							$comments_number,
							'comments title',
							'twentytwenty'
						),
						number_format_i18n( $comments_number ),
						get_the_title()
					);
				}

				?>
			</h2><!-- .comments-title -->

		</div><!-- .comments-header -->

		<div class="comments-inner section-inner thin max-percentage">

			<?php
			wp_list_comments(
				array(
					'walker'      => new TwentyTwenty_Walker_Comment(),
					'avatar_size' => 120,
					'style'       => 'div',
				)
			);

			$comment_pagination = paginate_comments_links(
				array(
					'echo'      => false,
					'end_size'  => 0,
					'mid_size'  => 0,
					'next_text' => __( 'Newer Comments', 'twentytwenty' ) . ' <span aria-hidden="true">→</span>',
					'prev_text' => '<span aria-hidden="true">←</span> ' . __( 'Older Comments', 'twentytwenty' ),
				)
			);

			if ( $comment_pagination ) {
				$pagination_classes = '';

				// If we're only showing the "Next" link, add a class indicating so.
				if ( false === strpos( $comment_pagination, 'prev page-numbers' ) ) {
					$pagination_classes = ' only-next';
				}
				?>

				<nav class="comments-pagination pagination<?php echo $pagination_classes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static output ?>" aria-label="<?php esc_attr_e( 'Comments', 'twentytwenty' ); ?>">
					<?php echo wp_kses_post( $comment_pagination ); ?>
				</nav>

				<?php
			}
			?>

		</div><!-- .comments-inner -->

	</div><!-- comments -->

	<?php
}

if ( comments_open() || pings_open() ) {

	if ( $comments ) {
		echo '<hr class="styled-separator is-style-wide" aria-hidden="true" />';
	}

	comment_form(
		array(
			'class_form'         => 'section-inner thin max-percentage',
			'title_reply_before' => '<h2 id="reply-title" class="comment-reply-title">',
			'title_reply_after'  => '</h2>',
		)
	);

}
elseif ( is_single() ) {

	if ( $comments ) {
		echo '<hr class="styled-separator is-style-wide" aria-hidden="true" />';
	}

	?>

	<div class="comment-respond" id="respond">

		<p class="comments-closed"><?php _e( 'Comments are closed.', 'twentytwenty' ); ?></p>

	</div><!-- #respond -->

	<?php
}
меню

Установка куков комментирования для неавторизованных пользователей

Когда неавторизованный пользователь оставляет комментарий, WP устанавливает куки, которые сохраняют введенные данные. Какие куки сохраняются:

'comment_author_' . COOKIEHASH
'comment_author_email_' . COOKIEHASH
'comment_author_url_' . COOKIEHASH

// где COOKIEHASH = md5( get_site_option( 'siteurl' ) )

Делается это функцией wp_set_comment_cookies(), которая повешена на следующий хук:

// из файла: /wp-includes/default-filters.php
add_action( 'set_comment_cookies', 'wp_set_comment_cookies', 10, 3 );

И которая срабатывает при обработке комментария в файле /wp-comments-post.php:

// из файла: /wp-comments-post.php
/**
 * Perform other actions when comment cookies are set.
 *
 * @since 3.4.0
 * @since 4.9.6 The `$cookies_consent` parameter was added.
 *
 * @param WP_Comment $comment         Comment object.
 * @param WP_User    $user            Comment author's user object. The user may not exist.
 * @param bool       $cookies_consent Comment author's consent to store cookies.
 */
do_action( 'set_comment_cookies', $comment, $user, $cookies_consent );

Получить данные этих куков можно функцией wp_get_current_commenter().

меню

Функции комментариев

Это список часто используемых функций. Полный список смотрите здесь.

comments_template() Подгружает файл шаблона комментариев на странице записи. По умолчанию загружает файл: /comments.php из папки темы.
wp_list_comments() Выводит комментарии записей (постов, страниц). Функция может принимать ряд параметров и используется в шаблоне для вывода списка комментариев к посту/странице. Некоторые из параметров можно настроить в админ-панели.
comment_form() Выводит на экран готовый код формы комментирования, который можно использовать в шаблонах.
get_comments() Получает комментарии по указанным параметрам, в виде массива данных.
get_comment() Получает данные указанного комментария из базы данных. Возвращает экземпляр класса WP_Comment (условно можно сказать что возвращаются все поля таблицы wp_comments).
get_comments_number() Получает количество всех комментариев поста, включая уведомления и пинги.
wp_count_comments() Получает данные о количестве комментариев на сайте или отдельно для указанного поста. Данные собираются отдельно по типам комментов (все варианты поля comment_approved: approved, spam и т.д.).
get_comment_date() Получает дату указанного комментария.
get_avatar_url() Получает ссылку на аватар, по переданному email, ID или объекту пользователя. Также можно передать объект поста или комментария.
comment_reply_link() Выводит ссылку <a>, которая позволяет отвечать на комментарий. Тег используется в цикле комментариев, для каждого комментария.
edit_comment_link() Выводит ссылку (HTML тег A) на редактирование текущего в цикле комментария, если у пользователя есть право на это.
comment_link() Выводит ссылку (URL) комментария.
paginate_comments_links() Выводит список ссылок на страницы комментариев (ссылки пагинации), текущего поста.
wp_insert_comment() Вставляет/добавляет комментарий в базу данных.
wp_new_comment() Добавляет новый комментарий в Базу Данных. Фильтрует данные.
1 коммент
    Войти