Руководство по добавлению полей на страницу оформления заказа

Добро пожаловать в подробнейший пошаговый гайд, где я не только расскажу вам, как добавлять собственные поля на страницу оформления заказа, но также и как отобразить их значения в админке, письмах пользователю и администратору и на странице «Заказ принят».

Также хочу напомнить, что в моём видеокурсе по WooCommerce есть отдельный урок посвящённый кастомизации страници оформления заказа. Вот ссылка на него.

1. Добавление поля

1.1 Используя хуки

WooCommerce позволяет нам добавлять поля в разные места формы оформления заказа. Для каждой локации предусмотрен отдельный хук.

ХукРасположение
woocommerce_before_checkout_billing_formПеред полями платёжного адреса.
woocommerce_after_checkout_billing_formПосле полей платёжного адреса
woocommerce_before_checkout_registration_formПеред формы регистрации.
woocommerce_after_checkout_registration_formПосле формы регистрации.
woocommerce_before_checkout_shipping_formПеред полями адреса доставки.
woocommerce_after_checkout_shipping_formПосле полей адреса доставки.
woocommerce_before_order_notesПеред полем примечания к заказу.
woocommerce_after_order_notesПосле поля примечания к заказу.

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

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

add_action( 'woocommerce_before_order_notes', 'true_custom_checkout_field' );
 
function true_custom_checkout_field() {
	echo 'Однажды тут будет поле.';
}

Не знаете, куда вставлять код?

Работает:

хуки добавления полей в WooCommerce
Вы же заметили строчку текста «Однажды тут будет поле»?

А теперь поменяем этот текст на настоящее поле. Это можно сделать функцией woocommerce_form_field().

add_action( 'woocommerce_before_order_notes', 'true_custom_checkout_field' );
 
function true_custom_checkout_field() {
	// выводим поле функцией woocommerce_form_field()
	woocommerce_form_field( 
		'billing_contactmethod', 
		array(
			'type'          => 'select', // text, textarea, select, radio, checkbox, password
			'required'	=> true, // по сути только добавляет значок "*" и всё
			'class'         => array( 'true-field', 'form-row-wide' ), // массив классов поля
			'label'         => 'Предпочитаемый метод связи',
			'label_class'   => 'true-label', // класс лейбла
			'options'	=> array( // options for  or 
				''		=> 'Выберите', // пустое значение
				'По телефону'	=> 'По телефону', // 'значение' => 'заголовок'
				'По email'	=> 'По email'
			)
		),
		$checkout->get_value( 'contactmethod' )
	);
}

Не знаете, куда вставлять код?

Подробное описание всех параметров – в уроке про функцию woocommerce_form_field().

А вот результат:

добавление поля выпадающего списка на страницу оформления заказа

1.2 Добавление в существующую группу полей платёжного адреса или адреса доставки

Но что делать, если вам нужно добавить поле ну прямо обязательно после полей «Имя» и «Фамилия» и других вариантов нет?

Тут для нас также целых три хука на выбор.

ХукОписание
woocommerce_default_address_fieldsПозволяет добавить поле в обе группы полей одновременно – платёжного адреса и адреса доставки.
woocommerce_billing_fieldsПозволяет добавить поле в группу полей платёжного адреса.
woocommerce_shipping_fieldsПозволяет добавить поле в группу полей адреса доставки.

Пробуем.

add_filter( 'woocommerce_billing_fields', 'true_add_custom_billing_field', 25 );
 
function true_add_custom_billing_field( $fields ) {
 
	// массив нового поля
	$new_field = array(
		'billing_contactmethod' => array(
			'type'          => 'select', // text, textarea, select, radio, checkbox, password
			'required'	=> true, // по сути только добавляет значок "*" и всё
			'class'         => array( 'true-field', 'form-row-wide' ), // массив классов поля
			'label'         => 'Предпочитаемый метод связи',
			'label_class'   => 'true-label', // класс лейбла
			'options'	=> array( // options for  or
				''		=> 'Выберите', // пустое значение
				'По телефону'	=> 'По телефону', // 'значение'=>'заголовок'
				'По email'	=> 'По email'
			)
		)
	);
 
	// объединяем поля
	$fields = array_slice( $fields, 0, 2, true ) + $new_field + array_slice( $fields, 2, NULL, true );
 
	return $fields;
 
}

Всё ещё не знаете, куда вставлять код?

Все параметры массива $new_field идентичны параметрам функции woocommerce_form_field(), которую мы использовали в предыдущем примере.

Результат:

Добавление поля адреса на страницу оформления заказа WooCommerce

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

И ещё одно но – при таком методе добавления полей они у нас будут появляться не только на странице оформления заказа, но и в личном кабинете, в секции адресов. Чтобы избежать этого, достаточно добавить условие на функцию is_checkout():

if( ! is_checkout() ) {
	return $fields;
}

2. Валидация полей

Как вы помните из предыдущей главы, рядом с полем мы добавили знак *, типо как оно обязательное. Но не спешите радоваться. Попробуйте оформить заказ, не заполняя это поле. Небольшой спойлер – для первого метода никакой валидации там не будет, а для второго – отобразится стандартное сообщение об ошибке!

Как же мы поступим?

Ну во-первых, про валидацию полей у меня на сайте уже был отдельный урок. Исходя из урока, всё, что нам потребуется – это хук woocommerce_after_checkout_validation и проверка на то, что значение поля не пустое.

add_action( 'woocommerce_after_checkout_validation', 'truemisha_validate_field', 25, 2 );
 
function truemisha_validate_field( $fields, $errors ){
 
	// проверка, что пустое
	if ( '' === $fields[ 'billing_contactmethod' ] ){
		// удаление стандартной ошибки нужно, если вы решили использовать 2-й метод добавления поля
		$errors->remove( 'billing_contactmethod_required' );
		// добавляем кастомную ошибку
		$errors->add( 'validation', 'А вы забыли указать предпочтительный метод связи с вами!' );
	}
 
}

Результат:

Добавление валидации на поле оформления заказа

3. Сохранение в информацию о заказе

Тут всё очень похоже на обычный хук save_post, если вы с ним работали до этого. Проверяем, что поле заполнено и сохраняем его в метаданные заказа функцией update_post_meta(). Ведь заказы – это типы постов.

Не забываем про очистку поля.

add_action( 'woocommerce_checkout_update_order_meta', 'true_save_field', 25 );
 
function true_save_field( $order_id ){
 
	if( ! empty( $_POST[ 'billing_contactmethod' ] ) ) {
		update_post_meta( $order_id, 'billing_contactmethod', sanitize_text_field( $_POST[ 'billing_contactmethod' ] ) );
	}
 
}

4. Отображение в редактировании заказа в админке

4.1 Без возможности редактирования

Если в админке WooCommerce вы перейдёте в редактирование заказа, то там будет большой метабокс с информацией о заказе – «Детали заказа». Давайте для начала выведем там значение нашего поля, а потом ещё и добавим в него возможность редактирования.

Прежде всего WooCommerce нам даёт неплохой выбор относительно того, где мы будем выводить информацию, это можно понять по целым трём доступным хукам.

  • woocommerce_admin_order_data_after_order_details – если вы хотите добавить информацию в первую колонку, под полем «Клиент».
  • woocommerce_admin_order_data_after_billing_address – под платёжным адресом.
  • woocommerce_admin_order_data_after_shipping_address – под адресом доставки.

В целом я думаю для нас довольно логичным решение будет использовать второй хук. Тогда:

add_action( 'woocommerce_admin_order_data_after_billing_address', 'true_print_field_value', 25 );
 
function true_print_field_value( $order ) {
 
	if( $method = get_post_meta( $order->get_id(), 'billing_contactmethod', true ) ) {
		echo '<p><strong>Предпочтительный метод связи:</strong><br>' . esc_html( $method ) . '</p>';
	}
}

В итоге вставляем этот код, куда нужно и получаем:

Добавление информации в детали заказа

4.2 С возможностью редактирования в админке

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

add_action( 'woocommerce_admin_order_data_after_billing_address', 'true_print_editable_field_value', 25 );
 
function true_print_editable_field_value( $order ){
 
	$method = get_post_meta( $order->get_id(), 'billing_contactmethod', true );
 
	echo '<div class="address">
		<p' . ( ! $method ? ' class="none_set"' : '' ) . '>
			<strong>Предпочтительный метод связи:</strong>
			' . ( $method ? $method : 'Не указан.' ) . '
		</p>
	</div>
	<div class="edit_address">';
	woocommerce_wp_select( array(
		'id' => 'billing_contactmethod',
		'label' => 'Предпочтительный метод связи:',
		'wrapper_class' => 'form-field-wide',
		'value' => $method,
		'options' => array(
			'По телефону'	=> 'По телефону', // 'значение'=>'заголовок'
			'По email'	=> 'По email'
		)
	) );
	echo '</div>';
 
}
 
// и сохраняем
add_action( 'woocommerce_process_shop_order_meta', 'true_save_billing_details' );
 
function true_save_billing_details( $order_id ){
	update_post_meta( $order_id, 'billing_contactmethod', wc_clean( $_POST[ 'billing_contactmethod' ] ) );
}

У меня на сайте вы можете почитать про функции woocommerce_wp_text_input(), woocommerce_wp_textarea_input(), woocommerce_wp_select(), woocommerce_wp_radio() и woocommerce_wp_checkbox().

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

Редактирование поля в деталях заказа

5. Отображение в email-письмах

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

А сейчас готовый код по добавлению нашего поля!

Код применится как к письму администратору магазина, так и к письму клиенту.

add_filter( 'woocommerce_get_order_item_totals', 'truemisha_field_in_email', 25, 2 );
 
function truemisha_field_in_email( $rows, $order ) {
 
 	// удалите это условие, если хотите добавить значение поля и на страницу "Заказ принят"
	if( is_order_received_page() ) {
		return $rows;
	}
 
	$rows[ 'billing_contactmethod' ] = array(
		'label' => 'Предпочитаемый метод связи',
		'value' => get_post_meta( $order->get_id(), 'billing_contactmethod', true )
	);
 
	return $rows;
 
}

В результате всё получилось:

добавление значения поля в email пользователям и администратору

Понравился урок? Тогда предлагаю вам продолжить прокачивать свои навыки по WooCommerce в моём видеокурсе :)

Миша

Впервые познакомился с WordPress в 2009 году. Организатор и спикер на конференциях WordCamp. Преподаватель в школе Нетология.

Пишите, если нужна помощь с сайтом или разработка с нуля.

Комментарии — 2

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

Миша Рудрастых и WordPress

Полезности из мира WordPress и жизни студии.

Мой телеграм-канал