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

Вопрос или проблема

У меня есть следующий код, который должен выполняться при первом опубликовании нового поста, проверять, есть ли данные в пользовательском поле ‘specific_users’ (это использует Advanced Custom Fields), и если да, отправить электронное письмо каждому из выбранных пользователей.

/**
 * Отправить пользователям уведомление о новых постах фермеров
 */
function notify_growers($post) {
// Уведомлять только для постов фермеров
if ( $post->post_type != 'grower_posts' ) return;

$post_id = $post->ID;

// ...выполнять код один раз
if ( !get_post_meta( $post_id, 'emailsent', $single = true ) ) {

    $specific_users = get_field('specific_users',$post_id);
    if(isset($specific_users) && is_array($specific_users)) {
        foreach($specific_users as $specific_user) {

            $to = $specific_user['user_email'];
            $subject="Новости фермеров: " . get_the_title($post_id);

            $message="";
            $message .= '

' . get_the_excerpt($post_id) . '…

'; $message .= '

Читать далее »

'; wp_mail($to, $subject, $message ); } unset($specific_user); } else { return; } // Убедитесь, что это не выполнится снова update_post_meta( $post_id, 'emailsent', true ); } } add_action( 'draft_to_publish', 'notify_growers' ); add_action( 'new_to_publish', 'notify_growers' );

Письма не отправляются, и я не уверен, как это отладить.

Дополнительный вопрос: является ли отправка электронного письма в цикле foreach лучшим способом сделать это? Или мне следует сделать это сразу с помощью BCC каким-то образом?

Спасибо,
Ангус

Вы знаете, работает ли ваша функция wp_mail() вообще?
Знаете ли вы, не терпит ли неудачу ваша функция выше по цепочке?

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

Также я убрал вызов функции get_field(), который является всего лишь оберткой для get_post_meta().

Сохранение $post_id = $post->ID также было удалено, поскольку на этом этапе нет необходимости манипулировать или кэшировать ID по какой-либо конкретной причине, так что это немного упрощает код.

Если вы знаете, что ваш вызов к пользовательскому полю specific_users возвращает сериализованный массив, то вы можете добавить параметр true после meta_key, чтобы получить несериализованный массив, в противном случае опустите значение true.

isset вернет true, даже если массив пуст, и ЕСЛИ в массиве нет результатов, WordPress фактически вернет пустой массив, если только параметр true не установлен, в этом случае он вернет пустую строку, поэтому вызов isset был удален и заменен на !empty($array).

С этого момента вы можете немного легче отладить функцию…

function notify_growers($post) {
    //если НЕ тип поста 'grower_posts', выходите;
    if ( $post->post_type != 'grower_posts' ) 
         return;

    //если электронное письмо уже отправлено, выходите.
    if ( get_post_meta( $post->ID, 'emailsent', true ) )
         return;

    //если письмо не отправлено, то получите массив пользователей для отправки письма
    $specific_users = get_post_meta($post->ID, 'specific_users');

    //если $specific_users является массивом и не пустой, то отправьте электронное письмо. 
    if(is_array($specific_users) && !empty($specific_users)) { 
        foreach($specific_users as $specific_user) {
            //добавить логику почты здесь, $to, $subject, $message
            wp_mail($to, $subject, $message );
        }
        unset($specific_user);

        //предотвратить отправку писем, обновив метаполе поста
        update_post_meta( $post->ID, 'emailsent', true );
    }   

}

add_action( 'draft_to_publish', 'notify_growers' );
add_action( 'new_to_publish', 'notify_growers' );

Вы также можете отлаживать внутри вашей функции. Запишите данные переменных во временное хранилище с помощью стандартных функций WordPress, таких как set_transient() или отлаживайте в консоли вашего браузера. Вы можете использовать плагин Debug Objects для записи из php в консоль Webinspector в Chrome.

Возможно, хорошая идея добавить exit(); перед закрывающими скобками функции, чтобы создать вывод через возможности php, такие как var_dump() и остановить функцию для удобочитаемости на экране.

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

Ответ или решение

Отправка уведомлений пользователям при публикации постов в WordPress

Ваша задача заключается в отправке уведомлений по электронной почте определенным пользователям при публикации новых постов типа ‘grower_posts’. Давайте разберем вашу реализацию кода и предложим корректировки для улучшения его работы.

Проблемы в исходном коде

  1. Проверка отправки email: Ваша логика проверки на предмет уже отправленных писем с использованием мета-поля 'emailsent' в целом правильная, но вы не используете стандартные функции WordPress в оптимальном порядке.

  2. Получение списка пользователей: Обращение к пользовательскому полю 'specific_users' не совсем корректно. Если это массив, важно убедиться, что он существует и не пуст.

  3. Отправка писем: Использование функции wp_mail() внутри цикла foreach является приемлемым, но в случае большого количества пользователей это может вызвать проблемы с производительностью и временем выполнения скрипта.

  4. Отладка: Не хватает механизма для отслеживания ошибок и состояния выполнения.

Улучшенный код функции

Вот улучшенная версия вашей функции с учетом вышеперечисленных моментов:

/**
 * Уведомление пользователей о новых публикациях постов о производителях
 */
function notify_growers($post) {
    // Проверка типа поста
    if ($post->post_type != 'grower_posts') {
        return;
    }

    // Проверка, было ли уже отправлено уведомление
    if (get_post_meta($post->ID, 'emailsent', true)) {
        return;
    }

    // Получение массива пользователей
    $specific_users = get_post_meta($post->ID, 'specific_users', true); // Используем параметр true для получения правильного формата

    // Проверка на пустоту массива
    if (!empty($specific_users) && is_array($specific_users)) {
        $to = [];

        foreach ($specific_users as $specific_user) {
            // Предполагаем, что $specific_user — это массив с ключом 'user_email'
            if (!empty($specific_user['user_email'])) {
                $to[] = $specific_user['user_email'];
            }
        }

        if (!empty($to)) {
            $subject = "Grower News: " . get_the_title($post->ID);
            $message = "<p>" . get_the_excerpt($post->ID) . "…</p>";
            $message .= "<p><a href=\"" . get_permalink($post->ID) . "\"><strong>Continue Reading &raquo;</strong></a></p>";

            // Отправка email с использованием BCC
            wp_mail(implode(',', $to), $subject, $message);
        }

        // Обновление мета-поля, чтобы не отправлять повторно
        update_post_meta($post->ID, 'emailsent', true);
    }
}

add_action('draft_to_publish', 'notify_growers');
add_action('new_to_publish', 'notify_growers');

Рекомендации по оптимизации email-отправки

  • Использование BCC: Объединение всех адресов электронной почты в одну строку с использованием запятых (как в примере выше) эффективно обрабатывает рассылку одним вызовом wp_mail().

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

  • Отладка через var_dump() или set_transient(): Вы можете использовать функцию set_transient() для временного сохранения данных и последующего их просмотра, что может быть полезно для отладки.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...