wordpress woocommerce - show and modify account fields on checkout page - php

I understand that you can add custom fields on the checkout page of WooCommerce, but what I want to show before the billing details are the account fields, which are already existing as written in the documentation. These fields are named:
account_username
account_password
account_password-2
But they are not shown by default. I only managed to make them visible by putting them at the top of the list in the function for reordering the billing fields like this in my theme's function.php like this
add_filter("woocommerce_checkout_fields", "order_fields");
function order_fields($fields) {
$order = array(
"account_username",
"account_password",
"account_password-2",
"billing_first_name",
"billing_last_name",
// other billing fields go here
);
foreach($order as $field)
{
$ordered_fields[$field] = $fields["billing"][$field];
}
$fields["billing"] = $ordered_fields;
return $fields;
}
This works fine with the functionality of creating an account while checking out, but I am having troubles with modifying its label and placeholder. This is what I tried to do:
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
function custom_override_checkout_fields( $fields ) {
$fields['account']['account_username']['label'] = '* Username: ';
$fields['account']['account_username']['placeholder'] = 'Enter username here...';
}
But it wouldn't let me change the labels and placeholder of the fields so I was thinking that maybe it has something to do with how I am displaying it and/or how I am modifying them.
Ideas, anyone? Thanks in advance.

I've found the answer to this, so if anyone has the same problem, this is the best solution. Instead of trying to make the accounts fields visible, in my case it's more efficient to manually output the fields I need since I won't be needing most of the default fields anyway.
What I did was override the form-billing.php template. I removed the loop for the fields which is this part:
<?php foreach ( $checkout->checkout_fields['billing'] as $key => $field ) : ?>
<?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>
<?php endforeach; ?>
And replaced it with this to individually add them to the page:
<?php
woocommerce_form_field( 'billing_first_name', $checkout->checkout_fields['billing']['billing_first_name'], $checkout->get_value( 'billing_first_name') );
woocommerce_form_field( 'billing_email', $checkout->checkout_fields['billing']['billing_email'], $checkout->get_value( 'billing_email') );
woocommerce_form_field( 'account_username', $checkout->checkout_fields['account']['account_username'], $checkout->get_value( 'account_username') );
woocommerce_form_field( 'account_password', $checkout->checkout_fields['account']['account_password'], $checkout->get_value( 'account_password') );
woocommerce_form_field( 'account_password-2', $checkout->checkout_fields['account']['account_password-2'], $checkout->get_value( 'account_password-2') );
//...other fields that I need
?>
From there, the modifications for the label, placeholder, etc. works just fine. Hope it works for other people with the same issues too. Cheers! :)

Related

Woocommerce - Include custom user meta in order 'filter by registered customer' Ajax search

I am trying to include a users custom meta named 'sageaccountnumber' within the 'filter by registered customer' section of the WooCommerce orders list as shown below:
I already have the custom meta field named 'sageaccountnumber' working with the following PHP code:
add_action( 'personal_options_update', 'sab_save_sageaccount_user_profile_fields' );
add_action( 'edit_user_profile_update', 'sab_save_sageaccount_user_profile_fields' );
function sab_save_sageaccount_user_profile_fields( $user_id ) {
if ( !current_user_can( 'edit_user', $user_id ) ) {
return false;
}
update_user_meta( $user_id, 'sageaccountnumber', $_POST['sageaccountnumber'] );
}
When searching for a registered customer I would like to include the user meta 'sageaccountnumber' within the search and display matching results.
I understand this uses AJAX within the file class-wc-ajax.php. This is the function in question: https://wp-kama.com/plugin/woocommerce/function/WC_AJAX::json_search_customers
I do not know alot about AJAX and I have not been able to find a way to include a custom user meta value in this search. I have not found anyone else doing this.
Any guidance or suggestions would be much appreciated? Thank you.
After getting lost with trying to understand the class-wc-ajax.php file, I completely missed a more obvious and simple solution. Here is the code I am using which works perfectly. I hope this helps others looking for similar solution.
This filter-hook allows you to add an additional meta_query to the existing search parameters. This will also allow your custom user meta to display in AJAX searches from the Orders & Subscriptions pages.
If you have a custom meta field setup for your users, simply change 'sageaccountnumber' to the name of your meta and it will be included in the AJAX search results.
add_filter ('woocommerce_customer_search_customers', 'sab_sageaccount_order_subscription_search', 10, 4);
function sab_sageaccount_order_subscription_search ($filter, $term, $limit, $type){
if ($type == 'meta_query'){ $filter['meta_query'][] = array('key' => 'sageaccountnumber', 'value' => $term, 'compare' => 'LIKE');
}
return $filter;
}
If you need to include the custom meta field in the normal users search, you can use the following code, again changing 'sageaccountnumber' to your custom meta name.
add_action( 'pre_user_query', 'sab_sageaccount_user_search' );
function sab_sageaccount_user_search( $query ) {
global $wpdb;
global $pagenow;
if (is_admin() && 'users.php' == $pagenow) {
if( empty($_REQUEST['s']) ){return;}
$query->query_fields = 'DISTINCT '.$query->query_fields;
$query->query_from .= ' LEFT JOIN '.$wpdb->usermeta.' ON '.$wpdb->usermeta.'.user_id = '.$wpdb->users.'.ID';
$query->query_where = "WHERE 1=1 AND (user_login LIKE '%".$_REQUEST['s']."%' OR ID = '".$_REQUEST['s']."' OR (meta_value LIKE '%".$_REQUEST['s']."%' AND meta_key = 'sageaccountnumber'))";
}
return $query;
}

Get custom Fields from registration to Woocommerce Checkout

Hi i am using a plugin to allow employers to register and post jobs. In the registration I have created custom fields they are also in the admin and in the Profile (VAT IDs they I need for billing). I can automaticaly fill and save them also update in the Profile or admin back-end. But I have to include them in the billing fields (not so important where maybe after company name) where they are generated into the invoice. I am not a programmer I only know html and css little bit. I am trying now for 12 hours and no chance to get it there.
I would also like to make them not-editable from user profile.
This are my fields saved in the child-theme functions.php I have done this with the help from Plugin author but he will not help me more because of no support. Plugin guide
add_action('iwj_employer_form_after_general',function ($job){
$post_id = $job ? $job->get_id() : '';
?>
<?php
iwj_field_text( '_ico_company', 'IČO spoločnosti*', true, $post_id, null, 'true', '', __( '' ) );
?>
<?php
});
add_action('iwj_admin_employer_form_after_general',function ($post_id){
?>
<?php
iwj_field_text( '_ico_company', 'IČO spoločnosti*', true, $post_id, null, 'true', '', __( '' ) );
?>
<?php
});
add_action('save_post', function($post_id){
if($post_id && get_post_type($post_id) == 'iwj_employer'){
$custom_field_value = sanitize_text_field($_POST['_ico_company']);
update_post_meta($post_id, '_ico_company', $custom_field_value);
}
}, 99);
add_action('iwj_register_process', function($uid){
$user = IWJ_User::get_user($uid);
$post_id = 0;
if($user->is_employer()){
$emp = $user->get_employer();
$post_id = $emp->get_id();
}
if($post_id){
//Add you custom field name process here
update_post_meta($post_id, '_ico_company', sanitize_text_field($_POST['_ico_company']));
}
});
I would be mega happy if someone could help me out with this :)
This will help you to have the fields in the checkout. I added a mock function get_vat_field, because I don't know yet how you are going to get the VAT field in the checkout.
Generally, it adds an additional field to the checkout, and when the checkout is completed, it adds it to the order. Which then is displayed in the order meta of the order. You can find that in the order itself in the admin panel (order edit page).
Simply add this to your functions.php of your child theme.
// Our hooked in function – $fields is passed via the filter!
function add_vat_to_checkout_fields( $fields ) {
$fields['billing']['vat'] = array(
'type' => 'text',
'label' => __('VAT', 'woocommerce'),
'placeholder' => _x('VAT', 'placeholder', 'woocommerce'),
'required' => true,
'class' => array('form-row-wide hidden'),
'clear' => true,
'value' => get_vat_field('') // this is the function that gets the field from the user account or job post.
);
return $fields;
}
/**
* 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 );
function my_custom_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('VAT').':</strong> ' . get_post_meta( $order->get_id(), 'vat', true ) . '</p>';
}

How can I store the values from a WPForm in WordPress to a MySQL database?

How can I store the values from a WPForm in WordPress to a MySQL database?When we use WPForms where I have to add PHP part to store data? Can we store form data to tables when we are using free version of WPForms without buying it?
If you are using WP Forms Lite you can't do this directly, either you'll need to upgrade to PRO version or build your own custom save actions.
If you decide to go with your own custom version, some details below on how to intersect form submission on WP Forms.
WPForms has some actions you can use to do you own custom actions after form submission:
wpforms_process_complete
do_action( 'wpforms_process_complete', $this->fields, $entry, $form_data, $entry_id );
By using on your own template or plugin the wordpress hook add_action for any of the events described, you are able to get form data and do the handling you need.
Reference for wordpress add_action can be seen on the official documentation.
https://developer.wordpress.org/reference/functions/add_action/
Did a quick snippet that will help you get started:
add_action("wpforms_process_complete", 'function_save_custom_form_data');
function function_save_custom_form_data($params) {
foreach($params as $idx=>$item) {
$field_name = $item['name'];
$fiel_value = $item['value'];
// Do whatever you need
}
return true;
}
Please let me know if you need any further details.
WPForms store all form data in two tables within the native WordPress database. They are:
wp_wpforms_entries: In this table, the field values for entries are stored.
wp_wpforms_entry_meta: This table contains meta information about your entries such as IDs associated and the date that entries were submitted.
After publishing the form, make sure to add a form entry, so we can access the entry from your WordPress dashboard. Additionally, in your form builder, go to Settings » General and make sure that entry storing in WordPress is not disabled.
Create custom tables for example wpforms_entries and wpforms_entry_meta in your database to store form data. Use the provided action hook wpforms_process_complete to store the form entries.
add_action( 'wpforms_process_complete', 'process_entry', 5, 4 );
function process_entry( $form_fields, $entry, $form_data, $entry_id ) {
global $wpdb;
$form_id = $form_data['id'];
$entry_data = array(
'form_id' => $form_id,
'status' => 'publish',
'referer' => $_SERVER['HTTP_REFERER'],
'date_created' => current_time( 'mysql' )
);
// Insert into wpforms_entries custom table.
$success = $wpdb->insert( $wpdb->prefix . 'wpforms_entries', $entry_data );
$entry_id = $wpdb->insert_id;
// Create meta data.
if ( $entry_id ) {
foreach ( $form_fields as $field ) {
$field = apply_filters( 'wpforms_process_entry_field', $field, $form_data, $entry_id );
if ( isset( $field['value'] ) && '' !== $field['value'] ) {
$field_value = is_array( $field['value'] ) ? serialize( $field['value'] ) : $field['value'];
$entry_metadata = array(
'entry_id' => $entry_id,
'meta_key' => $field['name'],
'meta_value' => $field_value,
);
// Insert entry meta.
$wpdb->insert( $wpdb->prefix . 'wpforms_entrymeta', $entry_metadata );
}
}
}
}
Refrence: https://github.com/sanzeeb3/entries-for-wpforms/blob/master/includes/functions-wpfe-core.php#L59
Alternatively, the plugin itself is available: https://wordpress.org/plugins/entries-for-wpforms/
Free version of WPForms does not save the entry details captured in form. Therefore, you will need to write custom code to save the values in your custom DB table and then display them.
Below hook of WPForms can be used for saving data being entered in WPForms
/*hook to save entries coming from WPforms into database*/
add_action( 'wpforms_process_entry_save', array( $this, 'ank_wpforms_save_entries' ), 10, 4 );
public function ank_wpforms_save_entries( $fields, $entry, $form_id, $form_data ) {
//no need to sanitize data coming from WPForms as it is being sanitized in WPForms plugin before this hook using
//wpforms_process_validate_{$field_type} in class-process.php
$data = array();
$data['form_id'] = $form_id;
$data['entry_details'] = $fields;
//additional sanity checks are also performed while json encoding in "add" before adding in database
ank_wpforms_entry()->get_class_instance( 'entry-db' )->add( $data );
}
Alternatively , You can use this free plugin to save entries coming from WPForms into wordpress database and then display them in Wordpress Dashboard - https://wordpress.org/plugins/add-entries-functionality-to-wpforms/

WooCommerce Custom Checkbox Checked by default

I am trying to 'check' a checkbox by default in the WooCommerce checkout page.
I'm using the official WooCommerce Checkout Field Editor plugin to add a checkbox but it doesn't give me the ability to have the checkbox 'checked' by default.
I've tried using this code but it's not working:
function custom_override_checkout_fields ( $fields ) {
$fields['additional']['uncheck-to-opt-out-of-our-quarterly-newsletter-neuroscience-matters_field']['default'] = 1;
return $fields;
}
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );
Any help would be greatly appreciated. Thanks
You should add checkbox on checkout page using below code:
<?php
/**
* Add checkbox field to the checkout
**/
add_action('woocommerce_after_order_notes', 'my_custom_checkout_field');
function my_custom_checkout_field( $checkout ) {
$checked = $checkout->get_value( 'my_checkbox1' ) ? $checkout->get_value( 'my_checkbox1' ) : 1;
echo '<div id="my-new-field"><h3>'.__('My Checkbox: ').'</h3>';
woocommerce_form_field( 'my_checkbox1', array(
'type' => 'checkbox',
'class' => array('input-checkbox'),
'label' => __('I have read and agreed.'),
'required' => true,
), $checked);
echo '</div>';
}
To define the default value of a custom WooCommerce field set up using the woocommerce_checkout_fields hook, it's best to hook another filter function to woocommerce_checkout_get_value or default_checkout_<your_field_name> hooks.
woocommerce_checkout_get_value:
This one is a short circuit filter, which means if you use this, the $value will always start from null and if the returned $value is not null it prevents any attempt to read user's metadata for any previously defined user preferences.
In a sense it is kind of a hard default: for each checkout it uses the value defined in this filter.
add_filter( 'woocommerce_checkout_get_value', 'custom_override_checkout_get_value', 10, 2 );
public function custom_override_checkout_get_value( $value, $field ) {
// $value is null or the result of previous filters
if ( 'uncheck-to-opt-out-of-our-quarterly-newsletter-neuroscience-matters_field' === $field ) {
$value = 1;
}
return $value;
}
default_checkout_<your_field_name>:
This behaves similar to the one above, however this is called after the default value is read from a logged in user's defaults, which may have been set previously as metadata for the given user (e.g. saved during the last checkout if the user has already made a purchase before).
This can be considered a soft default, as with appropriate checks (like below: only set $value if null), the default is only applied if there is no existing user preference.
Also since this uses a dedicated hook name defined by the field name, there's no need to check which field the function is being called for.
add_filter( 'default_checkout_uncheck-to-opt-out-of-our-quarterly-newsletter-neuroscience-matters_field', 'custom_override_default_checkout_field' );
public function custom_override_checkout_get_value( $value ) {
// $value is read from logged in user's meta or null or the result of previous filters
if ( is_null($value) ) {
// Only use default if null, aka. if user has no previous preference saved.
$value = 1;
}
return $value;
}
For more context check out WC_Checkout::get_value() method in wp-content/plugins/woocommerce/includes/class-wc-checkout.php which calls both of these filters.

woo commerece short codes not working on all posts

I have created a short code to display short description in woo commerce but it is not working on all posts. It is displaying the short description on some posts and not on others.
Function to create that short code in functions.php
function product_shortdesc_shortcode( $atts ){
// use shortcode_atts() to set defaults then extract() to variables
extract( shortcode_atts( array( 'id' => false ), $atts ) );
// if an $id was passed, and we could get a Post for it, and it's a product....
if ( ! empty( $id ) && null != ( $product = get_post( $id ) ) && $product->post_type = 'product' ){
// apply woocommerce filter to the excerpt
echo apply_filters( 'woocommerce_short_description', $product->post_excerpt );
}
}
// process [product_shortdesc] using product_shortdesc_shortcode()
add_shortcode( 'product_shortdesc', 'product_shortdesc_shortcode' );
The way i am getting the data in my single.php file
$custom = get_post_custom(get_the_ID());
$my_custom_field = $custom['woo_id'];
foreach ( $my_custom_field as $key => $value ) {
echo do_shortcode('[product_shortdesc id='.$value.']');
}
PS: in my normal post i have a custom field which has the value of product id of the product in woo commerece.
Your issue is that you are expecting shortcodes to function which no longer exist. On new installs, these pages won't be created, but if you are updating you may already have those pages in place.
Although the upgrade script does attempt to trash them for you, this might not have happened if they were customised. Delete them. Delete edit-account and change password, then go to your 'my account' page and click the change password/edit account links. You'll be taken to and endpoint which offers the same functionality.
Thanks
Short Code must not echo code instead return the things that needs to be rendered
Change this
echo apply_filters( 'woocommerce_short_description', $product->post_excerpt );
to
return apply_filters( 'woocommerce_short_description', $product->post_excerpt );

Categories