Создание пользовательского приветственного письма без плагина
Есть ли способ настроить содержимое и тему приветственных и подтверждающих писем, отправляемых во время процесса регистрации в WordPress? Хотелось бы использовать хуки или фильтры без использования плагина или функции "pluggable".
Если кто-то может подсказать правильное направление, буду очень признателен. Спасибо!

К сожалению, вам придется использовать функциональность подключаемых функций — внутри этих функций нет фильтров или хуков (как видно из кода ниже). И что еще хуже, для вас лучше использовать подключаемую функцию в плагине.
Это связано с тем, что определение новой подключаемой функции в functions.php вашей темы требует создания нового определения функции внутри другой функции (чтобы вызвать ее после полной загрузки всех плагинов), что может быть не лучшим решением (см. комментарии ниже этого поста). Однако с другой стороны, это работает — см. код ниже первого примера.
Для тех, кто не против плагинов, вот вариант, который переопределяет подключаемую функцию — просто сохраните его в my_plugin.php (или любой другой файл) в директорию плагинов и активируйте через админ-панель:
<?php
/*
Plugin Name: Название плагина
Plugin URI: http://URI_страницы_с_описанием_плагина_и_обновлениями
Description: Краткое описание плагина.
Version: Версия плагина, например: 1.0
Author: Имя автора плагина
Author URI: http://URI_автора_плагина
License: Идентификатор лицензии, например GPL2
*/
if( !function_exists('new_user_notification') ){
function new_user_notifiaction(){
/**
* Уведомление администратора блога о новом пользователе, обычно по email.
*
* @since 2.0
*
* @param int $user_id ID пользователя
* @param string $plaintext_pass Опционально. Пароль пользователя в открытом виде
*/
function wp_new_user_notification($user_id, $plaintext_pass = '') {
$user = get_userdata( $user_id );
$user_login = stripslashes($user->user_login);
$user_email = stripslashes($user->user_email);
// Опция blogname экранируется с помощью esc_html при сохранении в базу через sanitize_option
// нам нужно обратное преобразование для обычного текста в email.
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$message = sprintf(__('Новая регистрация пользователя на вашем сайте %s:'), $blogname) . "\r\n\r\n";
$message .= sprintf(__('Имя пользователя: %s'), $user_login) . "\r\n\r\n";
$message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
@wp_mail(get_option('admin_email'), sprintf(__('[%s] Новая регистрация пользователя'), $blogname), $message);
if ( empty($plaintext_pass) )
return;
$message = sprintf(__('Имя пользователя: %s'), $user_login) . "\r\n";
$message .= sprintf(__('Пароль: %s'), $plaintext_pass) . "\r\n";
$message .= wp_login_url() . "\r\n";
wp_mail($user_email, sprintf(__('[%s] Ваши имя пользователя и пароль'), $blogname), $message);
}
}
}
Если вам интересно, вот тот же эффект, достигнутый через functions.php с определением новой функции внутри другой функции:
// переопределяем wp_new_user_notification после загрузки всех плагинов
add_action( 'plugins_loaded', 'new_user_notifiaction' );
function new_user_notifiaction(){
/**
* Уведомление администратора блога о новом пользователе, обычно по email.
*
* @since 2.0
*
* @param int $user_id ID пользователя
* @param string $plaintext_pass Опционально. Пароль пользователя в открытом виде
*/
function wp_new_user_notification($user_id, $plaintext_pass = '') {
$user = get_userdata( $user_id );
$user_login = stripslashes($user->user_login);
$user_email = stripslashes($user->user_email);
// Опция blogname экранируется с помощью esc_html при сохранении в базу через sanitize_option
// нам нужно обратное преобразование для обычного текста в email.
$blogname = wp_specialchars_decode(get_option('blogname'), ENT_QUOTES);
$message = sprintf(__('Новая регистрация пользователя на вашем сайте %s:'), $blogname) . "\r\n\r\n";
$message .= sprintf(__('Имя пользователя: %s'), $user_login) . "\r\n\r\n";
$message .= sprintf(__('E-mail: %s'), $user_email) . "\r\n";
@wp_mail(get_option('admin_email'), sprintf(__('[%s] Новая регистрация пользователя'), $blogname), $message);
if ( empty($plaintext_pass) )
return;
$message = sprintf(__('Имя пользователя: %s'), $user_login) . "\r\n";
$message .= sprintf(__('Пароль: %s'), $plaintext_pass) . "\r\n";
$message .= wp_login_url() . "\r\n";
wp_mail($user_email, sprintf(__('[%s] Ваши имя пользователя и пароль'), $blogname), $message);
}
}

Можете ли вы привести пример из стороннего кода, где подключаемая функция определена как функция внутри функции
? Я впервые такое вижу...

Боюсь, что не могу, но это работает ;) Есть ли причины, по которым такой подход может вызвать проблемы? Производительность? Целостность?

Я хотел убедиться, что это не просто скопированный/вставленный код. Определять функцию внутри функции — плохая практика. А для переопределения подключаемой функции достаточно if( !function_exists('plug_func') ) { function plug_func() {} }
.

Да, это правда, что мне нужен только предоставленный вами код, но в этом случае мой код должен загружаться раньше оригинального. А functions.php темы загружается после исходного кода в pluggable.php - отсюда и хук plugins_loaded. И есть ли причина, почему объявление функции внутри функции — это плохая идея?

PHP - Функция внутри функции. Хорошо или плохо?

ОК, спасибо. Я изменил ответ — теперь он включает стандартный способ реализации через плагин, помимо менее предпочтительного способа определения функции внутри функции (в данном случае, я считаю, это лучше, чем создание функции прямо в колбэке, что могло бы быть другим вариантом)

Это кажется хорошей идеей, которая также будет работать в functions.php:
// Добавляем фильтр для тела письма регистрации
add_filter('wp_mail','handle_wp_mail');
function handle_wp_mail($atts) {
/*"Your username and password" - это тема письма, которое WordPress отправляет из "function wp_new_user_notification" в файле "wp-includes/pluggable.php"*/
if (isset ($atts ['subject']) && substr_count($atts ['subject'],'Your username and password')>0 ) {
if (isset($atts['message'])) {
$atts['message'] = 'новое тело письма';
}
}
return ($atts);
}
Просто убедитесь, что учитываете язык, чтобы правильно определить строку темы письма. (Источник: http://wordpress.org/support/topic/how-to-change-registration-email-content?replies=3)
