WooCommerce, Wordpress

Campos Personalizados no Checkout e Pedidos Woocommerce

Compartilhe com seus amigos

WooCommerce é, sem dúvida, um plug-in de comércio eletrônico muito poderoso para WordPress. É capaz de configurar e gerenciar uma loja bem sucedida de comércio eletrônico de proporções consideráveis.

Ao longo deste artigo vou ensinar como deletar e criar personalizados no checkout, que são salvos nos pedidos, enviados por e-mail, editáveis pelo painel, e adicionáveis na hora de criar um pedido pelo painel.

Removendo dois campos de exemplo do checkout

function i9digital_billing_filter($fields){
unset( $fields["billing_first_name"] );
unset( $fields["billing_last_name"] );
return $fields;
}
add_filter( 'woocommerce_billing_fields', 'i9digital_billing_filter' );

Esta é a lista completa de campos do checkout:

  • Billing
    • billing_first_name
    • billing_last_name
    • billing_company
    • billing_address_1
    • billing_address_2
    • billing_city
    • billing_postcode
    • billing_country
    • billing_state
    • billing_email
    • billing_phone
  • Shipping
    • shipping_first_name
    • shipping_last_name
    • shipping_company
    • shipping_address_1
    • shipping_address_2
    • shipping_city
    • shipping_postcode
    • shipping_country
    • shipping_state
  • Account
    • account_username
    • account_password
    • account_password-2
  • Order
    • order_comments

Adicionando o campo personalizado ao checkout

Assim como no HTML, para adicionar os campos no Woocommerce, é necessário passar valores de propriedades, como Label, tipo, etc… Nesse caso, vamos criar dois campos personalizados, um será um campo de texto simples, e o outro será uma caixa de seleção…

Cada campo é um array, e podem passar as seguintes propriedades:

  • type – tipo do campo (text, textarea, password, select)
  • label – label do campo
  • placeholder – placeholder do campo (aquele texto quase invisível que fica dentro do campo)
  • class – class do campo (pra usar em css ou javascript)
  • required – true ou false, para tornar o campo obrigatório ou não, respectivamente
  • clear – true ou false, aplica uma correção clara ao campo/rótulo
  • label_class – class do label
  • options – opções para o select, array de opções (chave => valor)

Usaremos a função __() para futuras traduções, aconselho o plugin ser criado em inglês, e depois traduzido.

function i9digital_custom_checkout_fields($fields){
$fields['i9digital_extra_fields'] = array(
'i9digital_text_field' => array(
'type' => 'text',
'required'      => true,
'label' => __( 'Input Text Field' )
),
'i9digital_dropdown' => array(
'type' => 'select',
'options' => array( 'first' => __( 'First Option' ), 'second' => __( 'Second Option' ), 'third' => __( 'Third Option' ) ),
'required'      => true,
'label' => __( 'Dropdown field' )
)
);
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'i9digital_custom_checkout_fields' );
function i9digital_extra_checkout_fields(){
$checkout = WC()->checkout(); ?>
<div class="extra-fields">
<h3><?php _e( 'Additional Fields' ); ?></h3>
<?php
foreach ( $checkout->checkout_fields['i9digital_extra_fields'] as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>
<?php endforeach; ?>
</div>
<?php }
add_action( 'woocommerce_checkout_after_customer_details' ,'i9digital_extra_checkout_fields' );

A primeira função, usarmos o add_filter, essa é uma função do WordPress muito usada, capaz de alterar o conteúdo enquanto o site está sendo executado… E no caso, estamos usando pra alterar os campos que o Checkout possue…[

A segunda função, é um add_action que nada mais é do que executar um código à determinado local especificado por um plugin, tema, ou core do WordPress… No caso, estamos usando o local “woocommerce_checkout_after_customer_details” para adicionar esses campos, depois dos detalhes do cliente no Checkout… Nesse artigo, você poder ver melhor, onde existe cada Hook do Woocommerce… Ele vai procurar todos os campos do Checkout nomeados de (i9digital_extra_fields), que já nomeamos no código de cima, e vai adicionar os campos no local especificado dentro de uma Div chamada “extra-fields”…

Salvar os dados do Campo Personalizado nos Metadados do Pedido

function i9digital_save_extra_checkout_fields( $order_id, $posted ){
// don't forget appropriate sanitization if you are using a different field type
if( isset( $posted['i9digital_text_field'] ) ) {
update_post_meta( $order_id, '_i9digital_text_field', sanitize_text_field( $posted['i9digital_text_field'] ) );
}
if( isset( $posted['i9digital_dropdown'] ) && in_array( $posted['i9digital_dropdown'], array( 'first', 'second', 'third' ) ) ) {
update_post_meta( $order_id, '_i9digital_dropdown', $posted['i9digital_dropdown'] );
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'i9digital_save_extra_checkout_fields', 10, 2 );

A função update_post_meta, tem o objetivo de atualizar os metadados de um post do WordPress… Em resumo, são os dados que são guardados no posts, e no WordPress, pedidos também são posts… Estamos criando 2 metadados, um pra cada campo: _i9digital_text_field e _i9digital_dropdown, devemos usar o “_” antes da nomeação, pois assim os campos não aparecem nos “campos personalizados” na hora da edição do pedido, o que não vai ser necessário, pois vamos criar um novo “metabox” para nosso plugin… Que será uma caixa extra no pedido, capaz de editar estes campos…

Essa action está falando o seguinte: quando o pedido for atualizado, pegue os dados da meta, procurem pelos i9digital_text_field i9digital_dropdown dos dados recebidos pela action, e atualize os metadados do pedido de acordo com os novos dados…

Mostrar os dados dos campos personalizados, agora vinculados ao pedido ao usuário

Agora que os pedidos possuem os dados personalizados no banco de dados, podemos mostrá-los aos usuários…

function i9digital_display_order_data( $order_id ){  ?>
<h2><?php _e( 'Extra Information' ); ?></h2>
<table class="shop_table shop_table_responsive additional_info">
<tbody>
<tr>
<th><?php _e( 'Input Text Field:' ); ?></th>
<td><?php echo get_post_meta( $order_id, '_i9digital_text_field', true ); ?></td>
</tr>
<tr>
<th><?php _e( 'Drop Down Field:' ); ?></th>
<td><?php echo get_post_meta( $order_id, '_i9digital_dropdown', true ); ?></td>
</tr>
</tbody>
</table>
<?php }
add_action( 'woocommerce_thankyou', 'i9digital_display_order_data', 20 );
add_action( 'woocommerce_view_order', 'i9digital_display_order_data', 20 );

Essas duas actions estão colocando os dados salvos no pedido, em uma tabela, e mostrando em dois lugares, no pedido, quando visualizado pelo painel do usuário, e na finalização do checkout, quando mostrar os dados da compra finalizada… Aqueles “20” no final da action é a prioridade, e define a posição do HTML dentre os outros que já possuem lá…

Mostrar os campos no administrador

Bom, primeiro vou ensinar como adicionar de maneira estática abaixo dos detalhes de envio, e depois de maneira móvel (dá pra arrastar o campo pra qualquer lugar) a partir dos metaboxes… Mas podemos usar os dois ao mesmo tempo, se necessário…

Método 1. (Estático)

function i9digital_display_order_data_in_admin( $order ){  ?>
<div class="order_data_column">
<h4><?php _e( 'Additional Information', 'woocommerce' ); ?><a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a></h4>
<div class="address">
<?php
echo '<p><strong>' . __( 'Text Field' ) . ':</strong>' . get_post_meta( $order->get_id(), '_i9digital_text_field', true ) . '</p>';
echo '<p><strong>' . __( 'Dropdown' ) . ':</strong>' . get_post_meta( $order->get_id(), '_i9digital_dropdown', true ) . '</p>'; ?>
</div>
<div class="edit_address">
<?php woocommerce_wp_text_input( array( 'id' => '_i9digital_text_field', 'label' => __( 'Some field' ), 'wrapper_class' => '_billing_company_field' ) ); ?>
<?php woocommerce_wp_text_input( array( 'id' => '_i9digital_dropdown', 'label' => __( 'Another field' ), 'wrapper_class' => '_billing_company_field' ) ); ?>
</div>
</div>
<?php }
add_action( 'woocommerce_admin_order_data_after_order_details', 'i9digital_display_order_data_in_admin' );
function i9digital_save_extra_details( $post_id, $post ){
update_post_meta( $post_id, '_i9digital_text_field', wc_clean( $_POST[ '_i9digital_text_field' ] ) );
update_post_meta( $post_id, '_i9digital_dropdown', wc_clean( $_POST[ '_i9digital_dropdown' ] ) );
}
add_action( 'woocommerce_process_shop_order_meta', 'i9digital_save_extra_details', 45, 2 );

A primeira função, adiciona os campos abaixo dos dados do cliente… E a segunda, ao alterar os campos e salvar o pedido, eles atualizam os metadados do pedido..

Método 2. (Móvel, metaboxes).

add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
{
function mv_add_meta_boxes()
{
add_meta_box( 'mv_other_fields', __('My Custom Metabox','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
}
}
// Adding Meta field in the meta container admin shop_order pages
if ( ! function_exists( 'mv_add_other_fields_for_packaging' ) )
{
function mv_add_other_fields_for_packaging()
{
global $post;
$i9digital_text_field = get_post_meta( $post->ID, '_i9digital_text_field', true ) ? get_post_meta( $post->ID, '_i9digital_text_field', true ) : '';
echo '<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">
<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">
<input type="text" style="width:250px;";" name="my_field_text_field" placeholder="' . $meta_field_data . '" value="' . $meta_field_data . '">
<input type="text" style="width:250px;";" name="my_field_dropdown" placeholder="' . $meta_field_data . '" value="' . $meta_field_data . '"></p>';
}
}
// Save the data of the Meta field
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_save_wc_order_other_fields( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input  and update the meta field in the database.
update_post_meta( $post_id, '_i9digital_text_field', $_POST[ 'my_field_text_field' ] );
update_post_meta( $post_id, '_i9digital_dropdown', $_POST[ 'my_field_dropdown' ] );
}
}

A primeira função, cria o metabox dentro do painel do pedido, na barra lateral, mas pode ser arrastado pra a parte central. A segunda função, cria o campos que serão preenchidos com os metadados do pedido, e a terceira função, se encarrega de sempre que o pedido for salvo, alterar os metadados do pedido pra os novos…

Adicionar os Campos Personalizados aos Emails do Pedido

function i9digital_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['instagram'] = array(
'label' => __( 'Some field' ),
'value' => get_post_meta( $order->get_id(), '_i9digital_text_field', true ),
);
$fields['licence'] = array(
'label' => __( 'Another field' ),
'value' => get_post_meta( $order->get_id(), '_i9digital_dropdown', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'i9digital_email_order_meta_fields', 10, 3 );
function i9digital_show_email_order_meta( $order, $sent_to_admin, $plain_text ) {
$i9digital_text_field = get_post_meta( $order->get_id(), '_i9digital_text_field', true );
$i9digital_dropdown = get_post_meta( $order->get_id(), '_i9digital_dropdown', true );
if( $plain_text ){
echo 'The value for some field is ' . $i9digital_text_field . ' while the value of another field is ' . $i9digital_dropdown;
} else {
echo '<p>The value for <strong>input text field</strong> is ' . $i9digital_text_field. ' while the value of <strong>drop down</strong> is ' . $i9digital_dropdown . '</p>';
}
}
add_action('woocommerce_email_customer_details', 'i9digital_show_email_order_meta', 30, 3 );

Como nos campos do Checkout, a primeira função usa um filter, pra criar os campos do email, e o action, adiciona o texto aos detalhes do cliente…

Conclusão

Neste tutorial, mostrei como você poderiá adicionar, editar e salvar campos personalizados na página de pagamento do WooCommerce. Também adicionei um código para editar os modelos de e-mail para adicionar as informações dos campos personalizados aos e-mails. Se você enfrentar qualquer problema com o código ou gostaria de contribuir com a discussão, deixe um comentário abaixo.

Código completo:

function i9digital_custom_checkout_fields($fields){
$fields['i9digital_extra_fields'] = array(
'i9digital_text_field' => array(
'type' => 'text',
'required'      => true,
'label' => __( 'Input Text Field' )
),
'i9digital_dropdown' => array(
'type' => 'select',
'options' => array( 'first' => __( 'First Option' ), 'second' => __( 'Second Option' ), 'third' => __( 'Third Option' ) ),
'required'      => true,
'label' => __( 'Dropdown field' )
)
);
return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'i9digital_custom_checkout_fields' );
function i9digital_extra_checkout_fields(){
$checkout = WC()->checkout(); ?>
<div class="extra-fields">
<h3><?php _e( 'Additional Fields' ); ?></h3>
<?php
foreach ( $checkout->checkout_fields['i9digital_extra_fields'] as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>
<?php endforeach; ?>
</div>
<?php }
add_action( 'woocommerce_checkout_after_customer_details' ,'i9digital_extra_checkout_fields' );
function i9digital_save_extra_checkout_fields( $order_id, $posted ){
// don't forget appropriate sanitization if you are using a different field type
if( isset( $posted['i9digital_text_field'] ) ) {
update_post_meta( $order_id, '_i9digital_text_field', sanitize_text_field( $posted['i9digital_text_field'] ) );
}
if( isset( $posted['i9digital_dropdown'] ) && in_array( $posted['i9digital_dropdown'], array( 'first', 'second', 'third' ) ) ) {
update_post_meta( $order_id, '_i9digital_dropdown', $posted['i9digital_dropdown'] );
}
}
add_action( 'woocommerce_checkout_update_order_meta', 'i9digital_save_extra_checkout_fields', 10, 2 );
function i9digital_display_order_data( $order_id ){  ?>
<h2><?php _e( 'Extra Information' ); ?></h2>
<table class="shop_table shop_table_responsive additional_info">
<tbody>
<tr>
<th><?php _e( 'Input Text Field:' ); ?></th>
<td><?php echo get_post_meta( $order_id, '_i9digital_text_field', true ); ?></td>
</tr>
<tr>
<th><?php _e( 'Drop Down Field:' ); ?></th>
<td><?php echo get_post_meta( $order_id, '_i9digital_dropdown', true ); ?></td>
</tr>
</tbody>
</table>
<?php }
add_action( 'woocommerce_thankyou', 'i9digital_display_order_data', 20 );
add_action( 'woocommerce_view_order', 'i9digital_display_order_data', 20 );
function i9digital_display_order_data_in_admin( $order ){  ?>
<div class="order_data_column">
<h4><?php _e( 'Additional Information', 'woocommerce' ); ?><a href="#" class="edit_address"><?php _e( 'Edit', 'woocommerce' ); ?></a></h4>
<div class="address">
<?php
echo '<p><strong>' . __( 'Text Field' ) . ':</strong>' . get_post_meta( $order->get_id(), '_i9digital_text_field', true ) . '</p>';
echo '<p><strong>' . __( 'Dropdown' ) . ':</strong>' . get_post_meta( $order->get_id(), '_i9digital_dropdown', true ) . '</p>'; ?>
</div>
<div class="edit_address">
<?php woocommerce_wp_text_input( array( 'id' => '_i9digital_text_field', 'label' => __( 'Some field' ), 'wrapper_class' => '_billing_company_field' ) ); ?>
<?php woocommerce_wp_text_input( array( 'id' => '_i9digital_dropdown', 'label' => __( 'Another field' ), 'wrapper_class' => '_billing_company_field' ) ); ?>
</div>
</div>
<?php }
add_action( 'woocommerce_admin_order_data_after_order_details', 'i9digital_display_order_data_in_admin' );
function i9digital_save_extra_details( $post_id, $post ){
update_post_meta( $post_id, '_i9digital_text_field', wc_clean( $_POST[ '_i9digital_text_field' ] ) );
update_post_meta( $post_id, '_i9digital_dropdown', wc_clean( $_POST[ '_i9digital_dropdown' ] ) );
}
add_action( 'woocommerce_process_shop_order_meta', 'i9digital_save_extra_details', 45, 2 );
function i9digital_email_order_meta_fields( $fields, $sent_to_admin, $order ) {
$fields['instagram'] = array(
'label' => __( 'Some field' ),
'value' => get_post_meta( $order->get_id(), '_i9digital_text_field', true ),
);
$fields['licence'] = array(
'label' => __( 'Another field' ),
'value' => get_post_meta( $order->get_id(), '_i9digital_dropdown', true ),
);
return $fields;
}
add_filter('woocommerce_email_order_meta_fields', 'i9digital_email_order_meta_fields', 10, 3 );
function i9digital_show_email_order_meta( $order, $sent_to_admin, $plain_text ) {
$i9digital_text_field = get_post_meta( $order->get_id(), '_i9digital_text_field', true );
$i9digital_dropdown = get_post_meta( $order->get_id(), '_i9digital_dropdown', true );
if( $plain_text ){
echo 'The value for some field is ' . $i9digital_text_field . ' while the value of another field is ' . $i9digital_dropdown;
} else {
echo '<p>The value for <strong>input text field</strong> is ' . $i9digital_text_field. ' while the value of <strong>drop down</strong> is ' . $i9digital_dropdown . '</p>';
}
}
add_action('woocommerce_email_customer_details', 'i9digital_show_email_order_meta', 30, 3 );
add_action( 'add_meta_boxes', 'mv_add_meta_boxes' );
if ( ! function_exists( 'mv_add_meta_boxes' ) )
{
function mv_add_meta_boxes()
{
add_meta_box( 'mv_other_fields', __('My Custom Metabox','woocommerce'), 'mv_add_other_fields_for_packaging', 'shop_order', 'side', 'core' );
}
}
// Adding Meta field in the meta container admin shop_order pages
if ( ! function_exists( 'mv_add_other_fields_for_packaging' ) )
{
function mv_add_other_fields_for_packaging()
{
global $post;
$i9digital_text_field = get_post_meta( $post->ID, '_i9digital_text_field', true ) ? get_post_meta( $post->ID, '_i9digital_text_field', true ) : '';
echo '<input type="hidden" name="mv_other_meta_field_nonce" value="' . wp_create_nonce() . '">
<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">
<input type="text" style="width:250px;";" name="my_field_text_field" placeholder="' . $meta_field_data . '" value="' . $meta_field_data . '">
<input type="text" style="width:250px;";" name="my_field_dropdown" placeholder="' . $meta_field_data . '" value="' . $meta_field_data . '"></p>';
}
}
// Save the data of the Meta field
add_action( 'save_post', 'mv_save_wc_order_other_fields', 10, 1 );
if ( ! function_exists( 'mv_save_wc_order_other_fields' ) )
{
function mv_save_wc_order_other_fields( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'mv_other_meta_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'mv_other_meta_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// --- Its safe for us to save the data ! --- //
// Sanitize user input  and update the meta field in the database.
update_post_meta( $post_id, '_i9digital_text_field', $_POST[ 'my_field_text_field' ] );
update_post_meta( $post_id, '_i9digital_dropdown', $_POST[ 'my_field_dropdown' ] );
}
}

Compartilhe com seus amigos

Deixe um comentário

avatar
  Subscribe  
Notify of