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.
Related
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;
}
The MailChimp for WooCommerce plugin is great, but I've just been given a design where the 'Subscribe to our newsletter' checkbox in the WooCommerce checkout is immediately after the email field rather than at the bottom of a particular section:
The plugin allows you to type in an action hook for where you'd like the checkbox to appear; for example woocommerce_checkout_before_customer_details, woocommerce_after_checkout_billing_form, etc. which allows you to put the checkbox before or after a certain section (as long as there's a hook for it), but not in amongst the various fields.
Is there a way to add the MailChimp checkbox to very specific point before or after a certain field?
The checkout fields are outputted within a loop, which uses the woocommerce_form_field() function to echo out each field:
$fields = $checkout->get_checkout_fields( 'billing' );
foreach ( $fields as $key => $field ) {
woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
}
this function has a number of filters for each specific field type (e.g. woocommerce_form_field_email), but no action hooks.
However, you can use one of these filters and just a little trickery to add your own hooks:
///
// Add MailChimp checkbox after email field
///
function vnm_mc_after_email_field($field, $key, $args, $value) {
ob_start();
do_action('vnm_before_email_field');
echo $field;
do_action('vnm_after_email_field');
return ob_get_clean();
}
add_filter('woocommerce_form_field_email', 'vnm_mc_after_email_field', 10, 4);
Since a WordPress filter always has to return a version of the first parameter sent to it (in this case $field), all we do is open the output buffer, add our own actions for before and after the field (vnm_before_email_field, vnm_after_email_field), and then return the output buffer.
Then, in the MailChimp plugin settings under WooCommerce->MailChimp->Audience, just add the hook you've just created for your field:
...and done. Note you could in fact add action hooks around every WooCommerce checkout field if you wanted, just by adding the following (untested):
///
// Add `before` & `after` actions around every WooCommerce checkout field
///
function vnm_wc_form_field_actions($field, $key, $args, $value) {
ob_start();
do_action('vnm_before_' . $args['type'] . '_field');
echo $field;
do_action('vnm_after_' . $args['type'] . '_field');
return ob_get_clean();
}
add_filter('woocommerce_form_field', 'vnm_wc_form_field_actions', 10, 4);
I have just purchased the plugin Checkout Field Editor for WooCommerce from Theme High.
I need to create a custom display rule condition for fields.
They provide the filters hook:
apply_filters( 'thwcfe_show_field', $show, $field_name );
I have tried the following code, but it does not work.
Can someone help?
function display( $field_name='test' ) {
$show =true;
return $show;
}
add_filter('thwcfe_show_field', 'display');
The true / false options works but I can't make it specific to the $field_name = 'test'.
You are not using this filter in a correct way… First there are 2 arguments for the hooked function (one is missing).
To restrict the filter to a specific field name, you need an IF statement and between $field_name and the value to be tested, you need to use == or === comparison operators, but not =.
So your code is going to be:
add_filter('thwcfe_show_field', 'display_test_field', 10, 2 );
function display_test_field( $show, $field_name ) {
if ( 'test' === $field_name ) {
$show = true;
}
return $show;
}
where 10 is the hook priority and 2 the number of arguments for this hook.
It should better work now.
Documented WordPress add_filter() function
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/
I am developing a plugin for that I have to black list users, so I need to be display one more dropdown item called Black List inside the Bulk Actions dropdown in the Users page, after the Delete option. But I'm unable to see from where these two actions are coming from and also how to black list a particular user.
My idea is to add one more field is_blacklisted in user table as Boolean with default value false and when apply Black List action it changes to true. Any other thoughts?
There's a filter, but it's only useful to remove bulk actions.
From this WPSE question, answer and comments, there's the following workaround: add a custom option to the dropdown with jQuery and hook into admin_action_$your-action to catch the submission.
The hook admin_footer-$current_page is used to print our JavaScript on a specific admin page (adjust to use in other screens).
add_action( 'admin_footer-users.php', 'bulk_footer_so_23541269' );
add_action( 'admin_action_black_list', 'bulk_request_so_23541269' );
function bulk_footer_so_23541269()
{
# global $typenow; if( $typenow != 'page' ) return; // if used on edit.php screen
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('<option>').val('black_list').text('Black list')
.appendTo("select[name='action'], select[name='action2']");
});
</script>
<?php
}
function bulk_request_so_23541269()
{
# Array with the selected User IDs
wp_die( '<pre>' . print_r( $_REQUEST['users'], true ) . '</pre>' );
// $_REQUEST['post'] if used on edit.php screen
}
Your doubt about blocking a user deserves another question, but I'd start a research here first.
Proper support with add_filter( 'bulk_actions-screenid', 'register_my_bulk_actions' ) is arriving in Wordpress 4.7 .
Quoting the announcement post:
To add an option in the Bulk Actions dropdown HTML element, register a callback on the bulk_actions-{screen_id} filter that adds the new option onto the array. Replace {screen_id} with the ID of the admin screen to offer the bulk action on.
To add a bulk action “Email to Eric,” we could use the following code:
add_filter( 'bulk_actions-edit-post', 'register_my_bulk_actions' );
function register_my_bulk_actions($bulk_actions)
{
$bulk_actions['email_to_eric'] = __( 'Email to Eric', 'email_to_eric');
return $bulk_actions;
}
To handle a bulk action form submission, register a callback on the handle_bulk_actions-{screen_id} filter for the corresponding screen. The filter expects the redirect URL to be modified, so be sure to modify the passed $redirect_url. This allows us to carry success or failure state into the next request to display a notice to the user. The other callback arguments will differ depending on the screen here to include contextually relevant data.
To add a bulk action handler for emailing the selected posts, we could use the following code:
add_filter( 'handle_bulk_actions-edit-post', 'my_bulk_action_handler', 10, 3 );
function my_bulk_action_handler( $redirect_to, $doaction, $post_ids )
{
if ( $doaction !== 'email_to_eric' ) {
return $redirect_to;
}
foreach ( $post_ids as $post_id ) {
// Perform action for each post.
}
$redirect_to = add_query_arg( 'bulk_emailed_posts', count( $post_ids ), $redirect_to );
return $redirect_to;
}
Showing notices: We could use the existing notice hooks to let the user know what happened, depending on the state we set in the URL:
add_action( 'admin_notices', 'my_bulk_action_admin_notice' );
function my_bulk_action_admin_notice()
{
if ( ! empty( $_REQUEST['bulk_emailed_posts'] ) ) {
$emailed_count = intval( $_REQUEST['bulk_emailed_posts'] );
printf( '<div id="message" class="updated fade">' .
_n( 'Emailed %s post to Eric.',
'Emailed %s posts to Eric.',
$emailed_count,
'email_to_eric'
) . '</div>', $emailed_count );
}
}