Обновление user_email через php – WP 4.7

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

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

Есть много сообщений на эту тему, например, это Как обновить user_email на фронтенде в WP 3.3?, но ни один из предложенных методов не работает у меня. Я использую WP 4.7.3.

Вот это из вышеупомянутого сообщения. Этот способ обновляет электронную почту, но после отправки формы моя страница зависает на неопределенное время:

wp_update_user( array( 'ID' => $current_user->ID, 'user_email' => $_POST['email'] ) );

Я также попробовал этот способ. Он не обновляет электронную почту пользователя и не зависает:

$wpdb->update($wpdb->users, array('user_email' => $_POST['email']), array('ID' => $current_user->ID));

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

Отредактировано: обновлён код профиля пользователя. Оказывается, пароль тоже зависает на неопределенное время.

if ( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $_POST['action'] ) && $_POST['action'] == 'update-user' ) {

/* Обновление информации о пользователе. */

    // Электронная почта
    if (isset( $_POST['email'])) {
            // проверяем, действительно ли пользователь обновляет значение
            if ($user_email != $_POST['email']) {           
                    // проверяем, свободна ли электронная почта для использования
                    if (email_exists( $_POST['email'] )){
                        // Электронная почта уже существует, не обновлять значение.
                        $error[] = __('Этот email уже используется.', 'profile');
                    } 
                    else if (!is_email( $_POST['email'] )){
                        // Неправильный формат электронной почты.
                        $error[] = __('Email в неправильном формате.', 'profile');
                    } 
                    else {
                        wp_update_user( array( 'ID' => $current_user->ID, 'user_email' => $_POST['email'] ) );
                        //$wpdb->update($wpdb->users, array('user_email' => $_POST['email']), array('ID' => $current_user->ID));
                 }   
         }
    }  

    // Пароль
if ( !empty($_POST['pass1'] ) && !empty( $_POST['pass2'] ) ) {
    if ( $_POST['pass1'] == $_POST['pass2'] )
        wp_update_user( array( 'ID' => $current_user->ID, 'user_pass' => esc_attr( $_POST['pass1'] ) ) );
    else {
      $error[] = __('Пароли не совпадают.', 'profile');
            }
}

    // Имя
if ( !empty( $_POST['first-name'] ) ){
    update_user_meta( $current_user->ID, 'first_name', esc_attr( $_POST['first-name'] ) );
    }

    // Фамилия
if ( !empty( $_POST['last-name'] ) )
    update_user_meta($current_user->ID, 'last_name', esc_attr( $_POST['last-name'] ) );

    // Год рождения
if ( !empty( $_POST['birth_year'] ) ) {
        // Убедитесь, что это только цифры
        if (!ctype_digit($_POST['birth_year'])){
    $error[] = __('Введите год.', 'profile');
        }
        else
    update_user_meta($current_user->ID, 'birth_year', esc_attr( $_POST['birth_year'] ) );
    }

    // Телефон
if ( !empty( $_POST['phone'] ) ) {
    update_user_meta($current_user->ID, 'phone', esc_attr( $_POST['phone'] ) );
    }

    // Улица
if ( !empty( $_POST['address'] ) )
    update_user_meta($current_user->ID, 'street_address', esc_attr( $_POST['address'] ) );

    // Город
if ( !empty( $_POST['city'] ) )
    update_user_meta($current_user->ID, 'city', esc_attr( $_POST['city'] ) );

    // Штат
if ( !empty( $_POST['state'] ) )
    update_user_meta($current_user->ID, 'state', esc_attr( $_POST['state'] ) );

    // Имя родителя
if ( !empty( $_POST['p_first_name'] ) )
    update_user_meta($current_user->ID, 'player_parent_first_name', esc_attr( $_POST['p_first_name'] ) );

    // Фамилия родителя
if ( !empty( $_POST['p_last_name'] ) )
    update_user_meta($current_user->ID, 'player_parent_last_name', esc_attr( $_POST['p_last_name'] ) );

    // Email родителя
    if (isset( $_POST['p_email'])) {
        // проверяем, действительно ли пользователь обновляет значение
        if ($user_email != $_POST['p_email']) {       
                if (!is_email( $_POST['p_email'] )){
                    // Неправильный формат электронной почты.
                    $error[] = __('Email родителя в неправильном формате.', 'profile');
                } 
                else {
                    $args = array(
                        'ID' => $current_user->id,
                        'player_parent_email' => esc_attr( $_POST['p_email'] )
                );            
                wp_update_user( $args );
                }   
        }
    }

    // Телефон родителя
    if ( !empty( $_POST['p_phone'] ) ) {
    update_user_meta($current_user->ID, 'player_parent_phone', esc_attr( $_POST['p_phone'] ) );
    }

/* Перенаправление, чтобы страница показывала обновленную информацию. */
    // Убедитесь, что нет ошибок
if ( count($error) == 0 ) {
            echo "redirecting";
    // хук действия для плагинов и сохранения дополнительных полей
    do_action('edit_user_profile_update', $current_user->ID);
            wp_redirect( get_permalink().'?updated=true' );
    exit;
}   
    else {
        // вывод ошибок здесь
    }

}

Я заставил это работать с использованием $wpdb->update:

$ID = $current_user->ID;
$email = sanitize_email($_POST['email']);
$wpdb->update($wpdb->users, array('user_email' => $email), array('ID' => $ID));

К сожалению, точно не уверен, в чём была проблема с wp_update_user.

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

Чтобы обновить электронную почту пользователя на фронтальной стороне в WordPress версии 4.7.3, важно понять разницу между функциями и подходами, которые вы использовали. Вас интересуют методы wp_update_user() и непосредственное обновление базы данных через $wpdb.

Проблема:

Вы упомянули, что wp_update_user() приводит к зависанию страницы, в то время как $wpdb->update() выполняет обновление без проблем. Давайте разберем, почему это может происходить, и как правильно использовать каждую из этих функций.

1. Функция wp_update_user():

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

  • Обрабатывает различные проверки, такие как валидация формата email и проверка на уникальность.
  • Безопасно взаимодействует с базой данных, используя встроенные методы WordPress.

Однако зависание может происходить из-за нескольких факторов:

  • Проблемы с редиректом: Возможно, ваш код зацикливается из-за неправильно настроенного редиректа, особенно если wp_redirect() вызывается до завершения всех процессов.
  • Ошибки валидации: Неправильная обработка ошибок может привести к неопределенному состоянию скрипта.
  • Плагины или темы: Они также могут вмешиваться в работу, используя хуки или фильтры.

2. Метод $wpdb->update():

Этот подход заключается в непосредственном обновлении записи в таблице wp_users. Использование $wpdb позволяет более точно контролировать SQL-запросы, но требует осторожности:

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

Рекомендуемое решение:

  1. Диагностика зависания:

    • Проверьте, не вызывается ли wp_redirect() без выхода из скрипта с exit;.
    • Убедитесь, что все хуки обработаны правильно: не создавайте лишние цепочки с do_action().
  2. Использование wp_update_user():

    if (!email_exists($_POST['email'])) {
       $updated_user_id = wp_update_user(array(
           'ID' => $current_user->ID,
           'user_email' => sanitize_email($_POST['email'])
       ));
    
       if (is_wp_error($updated_user_id)) {
           $error[] = __('Не удалось обновить email.', 'profile');
       }
    } else {
       $error[] = __('Этот email уже используется.', 'profile');
    }
  3. Ошибки и валидация:

    • Добавьте обработку ошибок и валидацию прямо в форму и/или контроллер, чтобы ядро WordPress их понимало.

Заключение:

Выбор между wp_update_user() и $wpdb->update() зависит от требований безопасности и удобства. Для типичных сценариев предпочтительным будет использование wp_update_user() из-за его интеграции с системой WordPress. Однако $wpdb->update() подходит для случаев, когда требуется избежать встроенных проверок WordPress.

Если вы продолжаете сталкиваться с проблемами, настоятельно рекомендую посмотреть журнал ошибок сервера или использовать инструмент для профилирования скрипта, такой как Query Monitor, чтобы детализировать, почему это происходит.

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

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