WordPress как на ладони
Готовые темы (шаблоны) для WordPress wordpress jino

Создаем новые поля для комментариев WordPress

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

В этой статье мы добавим три новых поля в форму комментария WordPress:

  • два текстовых поля: номер телефона и название комментария.
  • и одно поле выбора - радио-кнопки для оценки текущей статьи.

А также, научимся сохранять их в метаполя комментария и выведем эти поля в админке, чтобы их можно было видеть и редактировать.

Как лучше создавать новые поля?

Расширить форму комментария можно, отредактировав оригинальную тему, создав дочернюю тему или создав плагин. Модифицировать оригинальную тему проще, чем создавать дочернюю, но тут есть серьезный недостаток: все усилия будут утеряны, если тему обновить. Но еще лучше создать плагин, потому что так настраиваемая форма комментариев будет работать на всех темах (за исключением тех, в которых форма комментариев добавляется нестандартно).

Пойдем по пути создания плагина для WordPress, к тому же делается это очень просто. Назовём плагин "Расширенные комментарии".

Создание плагина для расширения формы комментариев

Создадим в папке с плагинами новую папку с именем extend-comment, а внутри неё файл extend-comment.php. Теперь, чтобы WordPress увидел плагин, ему нужно указать специальные комментарии-заголовки:

<?php
/*
Plugin Name: Расширенные комментарии
Version: 1.0
Plugin URI: https://wp-kama.ru/?p=8342
Description: Плагин, добавляющий произвольные поля в форму комментариев.
Author: Campusboy
Author URI: https://wp-plus.ru/
*/

Заходим в раздел админки "Плагины" и видим наш плагин:

Его уже можно активировать, но на данный момент он "пустой" и никаких функций пока не выполняет...

к началу

Создание полей для неавторизованных пользователей

Подключимся к фильтру comment_form_default_fields и "дополним" массив с дефолтными полями WordPress (автор, email, url). В коде ниже мы заменяем код дефолтных полей формы и добавляем новое поле "Телефон".

add_filter('comment_form_default_fields', 'extend_comment_custom_default_fields');
function extend_comment_custom_default_fields($fields) {

	$commenter = wp_get_current_commenter();
	$req = get_option( 'require_name_email' );
	$aria_req = ( $req ? " aria-required='true'" : '' );

	$fields[ 'author' ] = '<p class="comment-form-author">'.
	  '<label for="author">' . __( 'Name' ) . '</label>'.
	  ( $req ? '<span class="required">*</span>' : '' ).
	  '<input id="author" name="author" type="text" value="'. esc_attr( $commenter['comment_author'] ) .
	  '" size="30" tabindex="1"' . $aria_req . ' /></p>';

	$fields[ 'email' ] = '<p class="comment-form-email">'.
	  '<label for="email">' . __( 'Email' ) . '</label>'.
	  ( $req ? '<span class="required">*</span>' : '' ).
	  '<input id="email" name="email" type="text" value="'. esc_attr( $commenter['comment_author_email'] ) .
	  '" size="30"  tabindex="2"' . $aria_req . ' /></p>';

	$fields[ 'url' ] = '<p class="comment-form-url">'.
	  '<label for="url">' . __( 'Website' ) . '</label>'.
	  '<input id="url" name="url" type="text" value="'. esc_attr( $commenter['comment_author_url'] ) .
	  '" size="30"  tabindex="3" /></p>';

	$fields[ 'phone' ] = '<p class="comment-form-phone">'.
	  '<label for="phone">' . __( 'Phone' ) . '</label>'.
	  '<input id="phone" name="phone" type="text" size="30"  tabindex="4" /></p>';

  return $fields;
}

Код прекрасно работает, но если не нужно изменять вид дефолтных полей, то его можно упростить, а именно, добавить только своё поле:

add_filter('comment_form_default_fields', 'extend_comment_default_fields');
function extend_comment_default_fields($fields) {

  $fields[ 'phone' ] = '<p class="comment-form-phone">'.
	'<label for="phone">' . __( 'Phone' ) . '</label>'.
	'<input id="phone" name="phone" type="text" size="30"/></p>';

  return $fields;
}

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

к началу

Создание полей для всех пользователей

На следующем шаге мы добавим текстовое поле для заголовка комментария и список радио-кнопок для оценки статьи.

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

Добавление комментария авторизованным пользователем

А чтобы показать поля для незарегистрированных пользователей, используем событие comment_form_after_fields, которое отобразит наши поля ниже полей по умолчанию (автор, email, url).

Добавление комментария неавторизованным пользователем

Т.е. в результате нужно вывести поля в момент срабатывания одного из событий:
comment_form_logged_in_after или comment_form_after_fields.

// Добавляем поля для всех пользователей
add_action( 'comment_form_logged_in_after', 'extend_comment_custom_fields' );
add_action( 'comment_form_after_fields', 'extend_comment_custom_fields' );
function extend_comment_custom_fields() {

	echo '<p class="comment-form-title">'.
			  '<label for="title">' . __( 'Comment Title' ) . '</label>'.
			  '<input id="title" name="title" type="text" size="30"/></p>';

	echo '<p class="comment-form-rating">'.
			  '<label for="rating">'. __('Rating') . '<span class="required">*</span></label>
			  <span class="commentratingbox">';

	for( $i=1; $i <= 5; $i++ ){
		echo '
		<label class="commentrating" style="display:inline-block;">
			<input type="radio" name="rating" id="rating" value="'. $i .'"/> '. $i .'   
		</label>';
	}

	echo'</span></p>';
}

Чтобы отобразить 5 радио-кнопок для рейтинга, запускаем цикл. Этот участок кода можно изменить под себя, к примеру вместо 5 указать 10.

к началу

Сохранение данных из полей во фронт-энде

Поля для формы комментариев добавлены, но они бесполезны, пока нет алгоритма сохранения данных. Чтобы реализовать этот механизм, используем хук comment_post. Предусмотрим сохранение только непустых данных, чтобы не загромождать базу данных пустыми строками.

Для добавления метаданных комментария используем функцию add_comment_meta().

add_action( 'comment_post', 'save_extend_comment_meta_data' );
function save_extend_comment_meta_data( $comment_id ){

	if( !empty( $_POST['phone'] ) ){
		$phone = sanitize_text_field($_POST['phone']);
		add_comment_meta( $comment_id, 'phone', $phone );
	}

	if( !empty( $_POST['title'] ) ){
		$title = sanitize_text_field($_POST['title']);
		add_comment_meta( $comment_id, 'title', $title );
	}

	if( !empty( $_POST['rating'] ) ){
		$rating = intval($_POST['rating']);
		add_comment_meta( $comment_id, 'rating', $rating );
	}

}

Обратите внимание, что для защиты мы очищаем поля через sanitize_text_field().

Теперь, после публикации комментария в базе появятся подобные строчки:

Добавленные метаданные для комментария к началу

Проверка заполнения обязательных полей

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

// Проверяем, заполнено ли поле "Рейтинг"
add_filter( 'preprocess_comment', 'verify_extend_comment_meta_data' );
function verify_extend_comment_meta_data( $commentdata ) {

	if ( empty( $_POST['rating'] ) || ! (int)$_POST['rating'] )
		wp_die( __( 'Error: You did not add a rating. Hit the Back button on your Web browser and resubmit your comment with a rating.' ) );

	return $commentdata;
}
к началу

Отображение содержимого метаполей во фронт-энде

С добавлением метаданных разобрались. Теперь возникает вопрос: как получить и отобразить метаданные комментария в форме? Для получения метаданных будем использовать функцию get_comment_meta.

Изменить код формы и добавить туда нужные данные можно через фильтр comment_text.

Два варианта вывода рейтинга

Рассмотрим 2 варианта, как можно было бы отобразить рейтинг.

Звёзды рейтинга из собственных картинок

В первом варианте мы будет отображать изображения звёзд, которые должны быть в виде картинок в папке плагина:

add_filter( 'comment_text', 'modify_extend_comment');
function modify_extend_comment( $text ){

  $plugin_url_path = WP_PLUGIN_URL;

  if( $commenttitle = get_comment_meta( get_comment_ID(), 'title', true ) ) {
	$commenttitle = '<strong>' . esc_attr( $commenttitle ) . '</strong><br/>';
	$text = $commenttitle . $text;
  } 

  if( $commentrating = get_comment_meta( get_comment_ID(), 'rating', true ) ) {
	$commentrating = '<p class="comment-rating">  <img src="'. $plugin_url_path .
	'/extend-comment/images/'. $commentrating . 'star.gif"/><br/>Rating: <strong>'. $commentrating .' / 5</strong></p>';
	$text = $text . $commentrating;
	return $text;
  } else {
	return $text;
  }
}

В коде мы:

  • Получаем ссылку на папку с комментариями.

  • Проверяем наличие заголовка комментария и, если есть, добавляем его перед основным содержимым комментария.

  • Проверяем наличие рейтинга и, если есть, добавляем его после основного содержимого комментария.

Если, к примеру, пользователь поставил четверку, то путь к картинке будет: http://site.ru/wp-content/plugins/extend-comment/images/4star.gif. Естественно, картинки должны существовать...

Звёзды рейтинга из иконочного шрифта Dashicons

Второй вариант по алгоритму такой же, но тут будем использовать родную функцию WordPress wp_star_rating(), которая сама добавит красивые иконки звёзд:

// Отображение содержимого метаполей во фронт-энде
add_filter( 'comment_text', 'modify_extend_comment');
function modify_extend_comment( $text ){
	global $post;

	if( $commenttitle = get_comment_meta( get_comment_ID(), 'title', true ) ) {
		$commenttitle = '<strong>' . esc_attr( $commenttitle ) . '</strong><br/>';
		$text = $commenttitle . $text;
	}

	if( $commentrating = get_comment_meta( get_comment_ID(), 'rating', true ) ) {

		$commentrating = wp_star_rating( array (
			'rating' => $commentrating,
			'echo'=> false
		));

		$text = $text . $commentrating;
	}

	return $text;
}

Во фронт-энде функция wp_star_rating() не работает, её надо подключить. Также нужно подключить шрифты 'dashicons'.

Проверим, есть ли у записи комментарии и, если есть, подключим файл с функцией и шрифт:

add_action( 'wp_enqueue_scripts', 'check_count_extend_comments' );
function check_count_extend_comments(){
	global $post;

	if( isset($post) && (int)$post->comment_count > 0 ){
		require_once ABSPATH .'wp-admin/includes/template.php';
		add_action('wp_enqueue_scripts', function(){
			wp_enqueue_style('dashicons');
		});

		$stars_css = '
		.star-rating .star-full:before { content: "\f155"; }
		.star-rating .star-empty:before { content: "\f154"; }
		.star-rating .star {
			color: #0074A2;
			display: inline-block;
			font-family: dashicons;
			font-size: 20px;
			font-style: normal;
			font-weight: 400;
			height: 20px;
			line-height: 1;
			text-align: center;
			text-decoration: inherit;
			vertical-align: top;
			width: 20px;
		}
		';

		wp_add_inline_style( 'dashicons', $stars_css );
	}

}

Шрифт 'dashicons' имеет объем в 45,3Кб без gzip сжатия и 28.3Кб с включенным на сервере сжатием. А сколько будут занимать места ваши картинки? Какой из способов выбрать - решать вам.

к началу

Вывод метаполей в админке

На этом создание плагина можно было бы закончить, но что если надо будет изменить метаданные комментария? Поэтому продолжим дорабатывать плагин и добавим возможность изменять метаполя на странице редактирования комментариев.

Для этого добавим метаполя на страницу редактирования комментария с помощью хука add_meta_boxes_comment и функции add_meta_box(). Другими словами, мы ждем действие add_meta_boxes_comment (начало отрисовки дефолтных полей) и с помощью add_meta_box() добавляем новые к имеющимся.

<?php
// Добавляем новый метабокс на страницу редактирования комментария
add_action( 'add_meta_boxes_comment', 'extend_comment_add_meta_box' );
function extend_comment_add_meta_box(){
	add_meta_box( 'title', __( 'Comment Metadata - Extend Comment' ), 'extend_comment_meta_box', 'comment', 'normal', 'high' );
}

// Отображаем наши поля
function extend_comment_meta_box( $comment ){
	$phone  = get_comment_meta( $comment->comment_ID, 'phone', true );
	$title  = get_comment_meta( $comment->comment_ID, 'title', true );
	$rating = get_comment_meta( $comment->comment_ID, 'rating', true );

	wp_nonce_field( 'extend_comment_update', 'extend_comment_update', false );
	?>
	<p>
		<label for="phone"><?php _e( 'Phone' ); ?></label>
		<input type="text" name="phone" value="<?php echo esc_attr( $phone ); ?>" class="widefat" />
	</p>
	<p>
		<label for="title"><?php _e( 'Comment Title' ); ?></label>
		<input type="text" name="title" value="<?php echo esc_attr( $title ); ?>" class="widefat" />
	</p>
	<p>
		<label for="rating"><?php _e( 'Rating: ' ); ?></label>
		<span class="commentratingbox">
		<?php
		for( $i=1; $i <= 5; $i++ ){
		  echo '
		  <span class="commentrating">
			<input type="radio" name="rating" id="rating" value="'. $i .'" '. checked( $i, $rating, 0 ) .'/>
		  </span>';
		}
		?>
		</span>
	</p>
	<?php
}

Этот код похож на тот, который выводил поля в форме комментаривания в посте, и выполняет следующие действия:

  • Получает данные метаполей.

  • wp_nonce_field() выводит проверочное (защитное, одноразовое) скрытое поле для формы, повышая безопасность.

  • Очищает содержимое метаполей с помощью esc_attr() и выводит на экран. Ничего не проверяет. Если данных нет, то поле будет пустое.

  • При выводе радио-кнопок проверяет, какое значение было выбрано и помечает html атрибутом checked='checked' с помощью функции checked().
к началу

Сохранение метаполей в админке

На этом шаге необходимо создать механизм сохранения измененных данных на странице редактирования комментария. Это очень похоже на процесс сохранения метаданных из формы комментариев во фронд-энде.

add_action( 'edit_comment', 'extend_comment_edit_meta_data' );
function extend_comment_edit_meta_data( $comment_id ) {
	if( ! isset( $_POST['extend_comment_update'] ) || ! wp_verify_nonce( $_POST['extend_comment_update'], 'extend_comment_update' ) )
	return;

	if( !empty($_POST['phone']) ){
		$phone = sanitize_text_field($_POST['phone']);
		update_comment_meta( $comment_id, 'phone', $phone );
	}
	else
		delete_comment_meta( $comment_id, 'phone');

	if( !empty($_POST['title']) ){
		$title = sanitize_text_field($_POST['title']);
		update_comment_meta( $comment_id, 'title', $title );
	}
	else
		delete_comment_meta( $comment_id, 'title');

	if( !empty($_POST['rating']) ){
		$rating = intval($_POST['rating']);
		update_comment_meta( $comment_id, 'rating', $rating );
	}
	else
		delete_comment_meta( $comment_id, 'rating');

}

Здесь мы подключимся к хуку edit_comment и делаем следующее:

  • Проверим nonce-код и если проверка не пройдет - остановим выполнение функции.

  • Проверим переданные данные по каждому полю и если у какого-то поля его нет - удалим само метаполе, чтобы не занимало место в базе данных. Если поле есть обновляем его и незабываем очищать для безопасности.
к началу

Удаление плагина

Наш собственный плагин, расширяющий функционал формы комментирования готов!

Единственное, правилом хорошего тона считается удаление данных, создаваемые плагином, в данном случае - наших метаполей. Ведь если удалить плагин, то данные плагина останутся никому не нужными...

Мы уже рассказывали, как правильно удалить плагин WordPress, потому в корне плагина создадим файл uninstall.php и пропишем в него:

if( ! defined('WP_UNINSTALL_PLUGIN') ) exit; 

global $wpdb; 

$wpdb->query("DELETE FROM $wpdb->commentmeta WHERE meta_key IN ('phone', 'title', 'rating')");
к началу

Подведем итоги

В этой статье мы разобрались:

Данный плагин можно еще улучшать и дорабатывать - всё зависит от поставленных задач. Ну а пока мы научились изменять дефолтную форму комментирования WordPress и сделали её более привлекательной для пользователя.

Скачать: Extend Comment
Скачано: 46, размер: 0, дата: месяц назад

Статья создана на базе статьи "How To Add Custom Fields In A WordPress Comment Form" с авторскими правками и дополнениями.

campusboy 1455wp-plus.ru
WordPress-разработчик. Разработка сайтов и лендингов. Доработка существующих проектов. Сопровождение ресурсов.
Создаем новые поля для комментариев Wordpress 1 комментарий
  • garri833 cайт: clubwp.ru

    Скачал ваш архив. Поставил, в админке работает, а вот на сайте под комментариями вместо звезд Fatal error: Call to undefined function wp_star_rating() in \wp-content\plugins\extend-comment\extend-comment.php on line 91

    После одобрения комментария ошибка исчезает, но звезды не отображаются.

    А и на самом сайте стили не срабатывают и в форме комментария остаются круглеши вместо звезд.

    Ответить5 дней назад #

Здравствуйте, !

Ваш комментарий