Добавьте настраиваемое поле для оформления заказа и в данные пользователя my_account при регистрации

У меня есть сайт woocommerce, который я создаю, и я хочу добавить дату рождения пользователя в usermeta в базе данных, а также отобразить ее в wp-admin под их профилем.

У меня ограниченный опыт возиться с PHP.

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

В документации Woocommerce показано, как добавить его в информацию о заказе, но не в саму учетную запись пользователя. Он правильно добавляется в заказ, но не в аккаунт.

Вот что у меня есть на данный момент:

/**
 * Add the field to the checkout
 */
add_action( 'woocommerce_after_order_notes', 'my_custom_checkout_field' );

function my_custom_checkout_field( $checkout ) {

    echo '<div id="my_custom_checkout_field">';

    woocommerce_form_field( 'birthdate', array(
        'type'          => 'text',
        'class'         => array('my-field-class form-row-wide'),
        'label'         => __('Date of Birth'),
        'placeholder'   => __('mm/dd/yyyy'),
        ), $checkout->get_value( 'birthdate' ));

    echo '</div>';

}

/**
 * Process the checkout
 */
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');

function my_custom_checkout_field_process() {
    // Check if set, if its not set add an error.
    if ( ! $_POST['birthdate'] )
        wc_add_notice( __( 'Please enter your date of birth.' ), 'error' );
}

/**
 * update order meta with field value
 */

add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );


function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['birthdate'] ) ) {
        update_post_meta( $order_id, 'Birthdate', sanitize_text_field( $_POST['birthdate'] ) );
    }
}

/**
 * update user meta with birthdate
 */

add_action ( 'personal_options_update', 'my_save_extra_profile_fields' );
add_action ( 'edit_user_profile_update', 'my_save_extra_profile_fields' );

function my_save_extra_profile_fields( $user_id )
{
    if ( ! empty( $_POST['birthdate'] ) ) {
        update_usermeta( $user_id, 'Birthdate', sanitize_text_field( $_POST['birthdate'] ) );
    }
}


/**
 * Display field value on the order edit page
 */
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_custom_checkout_field_display_admin_order_meta', 10, 1 );
add_action ( 'show_user_profile', 'my_custom_checkout_field_display_admin_order_meta' );
add_action ( 'edit_user_profile', 'my_custom_checkout_field_display_admin_order_meta' );

function my_custom_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>'.__('Birthdate').':</strong> ' . get_post_meta( $order->id, 'Birthdate', true ) . '</p>';
}

Я также получаю эту ошибку на странице информации о пользователе:

Notice: WP_User->id was called with an argument that is deprecated since 
version 2.1.0! Use WP_User->ID instead. in 
/Applications/MAMP/htdocs/tst_dev/wp-includes/functions.php on line 3891

Я также пробовал это вместо моей версии мета обновления пользователя.

add_action( 'user_register', 'my_custom_update_user');

function my_custom_update_user( $user_id )
{        
    if ( $user_id != 0 ) {             // check if user is not a guest
            update_usermeta( $user_id, 'Birthdate', sanitize_text_field( $_POST['birthdate'] ) );
        }
}

person Brian Edelman    schedule 10.09.2016    source источник
comment
Еще нет. Пришлось спать и работать. Займитесь этим сегодня. Спасибо за помощь   -  person Brian Edelman    schedule 11.09.2016


Ответы (2)


- Легкое обновление - (Все данные теперь обновлены в базе данных)


1) УСТРАНЕНИЕ ОШИБКИ:

Вместо устаревшего update_usermeta(), чтобы избежать ошибки.

2) ЧИСТКА И ИЗМЕНЕНИЕ КОДА:

Для настраиваемых полей лучше избегать заглавных букв в заголовке.

// Add the field to the checkout
add_action( 'woocommerce_after_order_notes', 'birth_day_checkout_field' );
function birth_day_checkout_field( $checkout ) {

    // if customer is logged in and his birth date is defined
    if(!empty(get_user_meta( get_current_user_id(), 'account_birth_date', true ))){
        $checkout_birht_date = esc_attr(get_user_meta( get_current_user_id(), 'account_birth_date', true ));
    }
    // The customer is not logged in or his birth date is NOT defined
    else {
        $checkout_birht_date = $checkout->get_value( 'birth_date' );
    }

    echo '<div id="my_custom_checkout_field">';

    woocommerce_form_field( 'birth_date', array(
        'type'          => 'text',
        'class'         => array('birth-date form-row-wide'),
        'label'         => __( 'Date of Birth', 'theme_domain_slug' ),
        'placeholder'   => __( 'mm/dd/yyyy', 'theme_domain_slug' ),
        ), $checkout_birht_date);

    echo '</div>';

}


// Process the checkout
add_action('woocommerce_checkout_process', 'birth_day_checkout_field_process');
function birth_day_checkout_field_process() {
    // Check if set, if its not set add an error.
    if ( ! $_POST['birth_date'] )
        wc_add_notice( __( 'Please enter your date of birth.', 'theme_domain_slug' ), 'error' );
}


// update order meta with field value
add_action( 'woocommerce_checkout_update_order_meta', 'birth_day_checkout_field_update_order_meta' );
function birth_day_checkout_field_update_order_meta( $order_id ) {
    if (!empty( $_POST['birth_date'])){
        update_post_meta( $order_id, 'birth_date', sanitize_text_field( $_POST['birth_date'] ) );

        // updating user meta (for customer my account edit details page post data)
        update_user_meta( get_post_meta( $order_id, '_customer_user', true ), 'account_birth_date', sanitize_text_field($_POST['birth_date']) );
    }
}

// update user meta with Birth date (in checkout and my account edit details pages)
add_action ( 'personal_options_update', 'birth_day_save_extra_profile_fields' );
add_action ( 'edit_user_profile_update', 'birth_day_save_extra_profile_fields' );
add_action( 'woocommerce_save_account_details', 'birth_day_save_extra_profile_fields' );
function birth_day_save_extra_profile_fields( $user_id )
{
    // for checkout page post data
    if ( isset($_POST['birth_date']) ) {
        update_user_meta( $user_id, 'account_birth_date', sanitize_text_field($_POST['birth_date']) );
    }
    // for customer my account edit details page post data
    if ( isset($_POST['account_birth_date']) ) {
        update_user_meta( $user_id, 'account_birth_date', sanitize_text_field($_POST['account_birth_date']) );
    }
}


// Display field value on the order edit page
add_action( 'woocommerce_admin_order_data_after_billing_address', 'birth_day_checkout_field_display_admin_order_meta', 10, 1 );
add_action ( 'show_user_profile', 'birth_day_checkout_field_display_admin_order_meta' );
add_action ( 'edit_user_profile', 'birth_day_checkout_field_display_admin_order_meta' );
function birth_day_checkout_field_display_admin_order_meta($order){
    echo '<p><strong>' . __( 'Birth date:', 'theme_domain_slug' ) . '</strong> ' . get_post_meta( $order->id, 'birth_date', true ) . '</p>';
}

3) ДОБАВЛЕНИЕ ПОЛЯ В МОЙ АККАУНТ КЛИЕНТА ИЗМЕНИТЬ ДАННЫЕ:

Вы могли бы использовать ловушку woocommerce_edit_account_form_start для вставки этого настраиваемого поля на страницу редактирования сведений о клиенте my_account, но у вас нет контроля над размещением и заказом.

Лучше включить его в папку шаблона woocommerce активной темы my_account/form-edit-account.php (если у вас еще нет этой папки, прочтите Переопределение шаблонов с помощью темы, чтобы понять, как это можно сделать.

Здесь настраиваемое поле «Дата рождения» будет расположено справа от адреса электронной почты в форме редактирования сведений об учетной записи «Моя учетная запись».

Вот код этого настроенного шаблона:

<?php
/**
 * Edit account form
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/myaccount/form-edit-account.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see     https://docs.woocommerce.com/document/template-structure/
 * @author  WooThemes
 * @package WooCommerce/Templates
 * @version 2.6.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

do_action( 'woocommerce_before_edit_account_form' ); ?>

<form class="woocommerce-EditAccountForm edit-account" action="" method="post">

    <?php do_action( 'woocommerce_edit_account_form_start' ); ?>

    <p class="woocommerce-FormRow woocommerce-FormRow--first form-row form-row-first">
        <label for="account_first_name"><?php _e( 'First name', 'woocommerce' ); ?> <span class="required">*</span></label>
        <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="account_first_name" id="account_first_name" value="<?php echo esc_attr( $user->first_name ); ?>" />
    </p>
    <p class="woocommerce-FormRow woocommerce-FormRow--last form-row form-row-last">
        <label for="account_last_name"><?php _e( 'Last name', 'woocommerce' ); ?> <span class="required">*</span></label>
        <input type="text" class="woocommerce-Input woocommerce-Input--text input-text" name="account_last_name" id="account_last_name" value="<?php echo esc_attr( $user->last_name ); ?>" />
    </p>
    <div class="clear"></div>

    <!-- class modification here in <p> tag -->
    <p class="woocommerce-FormRow woocommerce-FormRow--wide form-row form-row-first"><?php // <== Changed the class from "form-row-wide" to "form-row-first" ?>
        <label for="account_email"><?php _e( 'Email address', 'woocommerce' ); ?> <span class="required">*</span></label>
        <input type="email" class="woocommerce-Input woocommerce-Input--email input-text" name="account_email" id="account_email" value="<?php echo esc_attr( $user->user_email ); ?>" />
    </p>
    <!-- (BEGIN) ADDED: Birth day field -->
    <p class="woocommerce-FormRow woocommerce-FormRow--last form-row form-row-last">
        <label for="account_birth_date"><?php _e( 'Birth date', 'theme_domain_slug' ); ?> <span class="required">*</span></label>
        <input type="text" class="woocommerce-Input woocommerce-Input--email input-text" name="account_birth_date" id="account_birth_date" placeholder="mm/dd/yyyy" value="<?php echo esc_attr(get_user_meta( $user->ID, 'account_birth_date', true )); ?>" />
    </p>
    <div class="clear"></div>
    <!-- (END) Birth day field -->

    <fieldset>
        <legend><?php _e( 'Password Change', 'woocommerce' ); ?></legend>

        <p class="woocommerce-FormRow woocommerce-FormRow--wide form-row form-row-wide">
            <label for="password_current"><?php _e( 'Current Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
            <input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_current" id="password_current" />
        </p>
        <p class="woocommerce-FormRow woocommerce-FormRow--wide form-row form-row-wide">
            <label for="password_1"><?php _e( 'New Password (leave blank to leave unchanged)', 'woocommerce' ); ?></label>
            <input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_1" id="password_1" />
        </p>
        <p class="woocommerce-FormRow woocommerce-FormRow--wide form-row form-row-wide">
            <label for="password_2"><?php _e( 'Confirm New Password', 'woocommerce' ); ?></label>
            <input type="password" class="woocommerce-Input woocommerce-Input--password input-text" name="password_2" id="password_2" />
        </p>
    </fieldset>
    <div class="clear"></div>

    <?php do_action( 'woocommerce_edit_account_form' ); ?>

    <p>
        <?php wp_nonce_field( 'save_account_details' ); ?>
        <input type="submit" class="woocommerce-Button button" name="save_account_details" value="<?php esc_attr_e( 'Save changes', 'woocommerce' ); ?>" />
        <input type="hidden" name="action" value="save_account_details" />
    </p>

    <?php do_action( 'woocommerce_edit_account_form_end' ); ?>
</form>

<?php do_action( 'woocommerce_after_edit_account_form' ); ?>

4) СПАСИБО ПРЕДОСТАВЛЯЕТ БОНУСНЫЙ ПОДАРОК: ДОБАВЛЕНИЕ ПОЛЯ ДЛЯ АДМИНИСТРАЦИИ ПОЛЬЗОВАТЕЛЯ РЕДАКТИРОВАНИЯ:

введите описание изображения здесь

// ADDING CUSTOM FIELD TO INDIVIDUAL USER SETTINGS PAGE IN BACKEND
add_action( 'show_user_profile', 'add_extra_birth_date' );
add_action( 'edit_user_profile', 'add_extra_birth_date' );
function add_extra_birth_date( $user )
{
    ?>
        <h3><?php _e("Birth Date", "theme_domain_slug"); ?></h3>
        <table class="form-table">
            <tr>
                <th><label for="birth_date_profile"><?php _e("Date", "theme_domain_slug"); ?> </label></th>
                <td><input type="text" name="account_birth_date" value="<?php echo esc_attr(get_user_meta( $user->ID, 'account_birth_date', true )); ?>" class="regular-text" /></td>
            </tr>
        </table>
        <br />
    <?php
}

add_action( 'personal_options_update', 'save_extra_birth_date' );
add_action( 'edit_user_profile_update', 'save_extra_birth_date' );
function save_extra_birth_date( $user_id )
{
    update_user_meta( $user_id, 'account_birth_date', sanitize_text_field( $_POST['account_birth_date'] ) );
}

Весь код находится в файле function.php вашей активной дочерней темы (или темы) или также в любом файле плагина (кроме кода шаблона).

Этот код протестирован и работает.

person LoicTheAztec    schedule 11.09.2016
comment
К сожалению, это не работает. Я все еще получаю ту же ошибку. Также у меня была ошибка с функцией Birth_day_custom_checkout_field_display_admin_order_meta. Я удалил обычай, потому что его не было в остальной части кода. Я также подтвердил, что данные в базе данных не обновлялись. - person Brian Edelman; 11.09.2016
comment
Могу подтвердить, что это работает сейчас. Спасибо за помощь! - person Brian Edelman; 12.09.2016
comment
@BrianEdelman Спасибо за исправление этой маленькой ошибки :) (извините) - person LoicTheAztec; 14.09.2016

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

/**
 * update order meta with field value
 */

add_action( 'woocommerce_checkout_update_order_meta', 'my_custom_checkout_field_update_order_meta' );


function my_custom_checkout_field_update_order_meta( $order_id ) {
    if ( ! empty( $_POST['birthdate'] ) ) {

        update_post_meta( $order_id, 'Birthdate', sanitize_text_field( $_POST['birthdate'] ) );

        $order = WC_Order( $order_id );    // getting order object
        $user_id = $order->get_user_id();  // getting user id
        if ( $user_id != 0 ) {             // check if user is not a guest
            update_usermeta( $user_id, 'Birthdate', sanitize_text_field( $_POST['birthdate'] ) );
        }
    }
}

Вам также следует удалить раздел «обновить метаданные пользователя с датой рождения».

person pa7ryk    schedule 11.09.2016