Adding a class to all inputs in WooCommerce - php

I am trying to add the Bootstrap form-control to all input elements in WooCommerce. I did some searching on google and came up with the found code.
add_filter('woocommerce_checkout_fields', 'addBootstrapToCheckoutFields' );
function addBootstrapToCheckoutFields($fields) {
foreach ($fields as &$fieldset) {
foreach ($fieldset as &$field) {
// add form-control to the actual input
$field['input_class'][] = 'form-control';
}
}
return $fields;
}
The problem is that this code only does what I want for the fields on the checkout pages. Is there a simple way to use a filter to do this for all WooCommerce fields? Obviously, I could go through every file that has fields and place the code manually, but I'd like to avoid that.
Thanks!

Related

Unset some WooCommerce checkout billing fields and One Page Checkout plugin

I am using WooCommerce Subscription and One Page Checkout plugins.
I am able to unset billing first name and last name (and even set 'required' attribute to false, so both fields are successively removed from my One page checkout.
But when I fill all other fields and I place order, it displays a validation error notice: "Billing First Name and Last Name are required" and I am not really sure how to solve this problem?
Maybe it has been set again from some functions or so? How I can solve this?
To remove billing first name and last name without any issues in checkout page, try to use the following instead:
// 1. Make required fields optional
add_filter( 'woocommerce_default_address_fields', 'customize_default_address_checkout_fields', 1000 );
function customize_default_address_checkout_fields( $fields ) {
if( is_checkout() ) {
$fields['first_name']['required'] = $fields['last_name']['required'] = false;
}
return $fields;
}
// 2. Remove unneeded billing fields
add_filter( 'woocommerce_billing_fields', 'customize_billing_checkout_fields', 1000 );
function customize_billing_checkout_fields( $fields ) {
if( is_checkout() ) {
unset($fields['billing_first_name'], $fields['billing_last_name']);
}
return $fields;
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works…
It should works with One Page Checkout plugin too.
Have you tried removing it manually via child function.php as below?
add_filter( 'woocommerce_checkout_fields' , ' custom_remove_checkout_fields ' );
function custom_remove_checkout_fields( $fields ) {
unset($fields['billing']['billing_first_name']);
unset($fields['billing']['billing_last_name']);
return $fields;
}
I have solved the issue already.
The root cause is because one plugin always required Billing First Name and Last Name so I use this tip below to passby the problem:
I included this code into function.php of the theme:
add_filter('woocommerce_billing_fields', 'my_woocommerce_billing_fields');
function my_woocommerce_billing_fields($fields) {
$fields['billing_first_name']['default'] = 'newSubscriber';
$fields['billing_first_name']['custom_attributes']['readonly'] = TRUE;
$fields['billing_last_name']['default'] = 'newSubscriber';
$fields['billing_last_name']['custom_attributes']['readonly'] = TRUE;
return $fields;
}
So now your first name and your last name is always set as 'newSubscriber', it will pass the validation and now you hide it from dislaying using css:
p#billing_first_name_field, p#billing_last_name_field {
display: none;
}
paste these css into appearance -> Theme-> yourtheme-> additional css and save it.
So now everything would work as charm.
Hope it would help somebody struggling with the problem.

Hide certain Advanced Custom Fields from non admins

I've used ACF's "Flexible Content" to create a fairly advanced "page builder" where authors can create a "section" (basically just a wrapping element with a CSS class name and ID) and then add all my flexible content (images, wysiwyg etc) to it.
What I'd like to do is hide some fields for non admins. I don't want any old editor to be able to go in and change a section's ID or class names (as it would mess up the layout).
I'm aware of the "Rules" panel in the ACF admin where you can choose to only display a certain field group to one type of user role, but what I want is that same thing but for individual fields.
It doesn't appear to be doable from the admin interface, but I'm wondering if someone knows how it could be done from my functions.php file? Perhaps some filter or action I can hook into and disable certain fields based on the current user's role?
I've attached two screenshots showing what I'd like hidden:
I'd like to hide these choices from the "Add row" menu:
And I'd like these panels to be invisible to non admins:
Edit: While we're at it, I wouldn't mind hiding individual fields from a repeatable too. You'll notice a "Modifiers" field in the first screenshot, that too would be nice to hide from non admins. I guess the solution would be pretty much the same for both problems?
As of ACF 5.0.0 there is an easier way to do this without having to disable the field or output CSS. If you use the acf/prepare_field hook and return false the field will not render.
<?php
function so37111468_hide_field( $field ) {
// hide the field if the current user is not able to save options within the admin
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
return $field;
}
add_filter( 'acf/prepare_field/key=MYFIELDKEY', 'so37111468_hide_field' );
?>
The documentation for that filter can be found here: https://www.advancedcustomfields.com/resources/acf-prepare_field/
I haven't managed to actually hide the fields, but I have managed to disable them. Unfortunately simply setting them to disabled in the acf/load_field action wasn't enough to remove them from the dropdown menu so I also added some CSS to the admin page to visually hide them at least. This is good enough seeing as the editors of the site won't exactly do their best to break it.
<?php
/**
* Hide some "ACF Section" related custom fields
*/
add_action('acf/load_field', 'sleek_hide_acf_section_fields', 10, 1);
function sleek_hide_acf_section_fields ($field) {
$hide = array('section_name', 'section_modifiers', 'modifiers');
global $current_user;
if ((isset($field['_name']) and in_array($field['_name'], $hide)) and (is_admin() && is_user_logged_in() && !in_array('administrator', $current_user->roles))) {
$field['disabled'] = true;
}
return $field;
}
add_action('admin_head', 'sleek_hide_acf_section_fields_css');
function sleek_hide_acf_section_fields_css () {
$hide = array('section_name', 'section_modifiers', 'modifiers');
global $current_user;
if (is_admin() && is_user_logged_in() && !in_array('administrator', $current_user->roles)) {
echo '<style>';
foreach ($hide as $h) {
echo 'div.acf-fc-popup a[data-layout="' . $h . '"]{display: none}';
}
echo '</style>';
}
}

Woocommerce: remove all form labels at once

I'm using WooCommerce to build a webshop.
The determined format for forms is that there's no labels, only placeholders. I've been removing the labels like so:
<?php
// WooCommerce Checkout Fields Hook
add_filter( 'woocommerce_checkout_fields' , 'custom_wc_checkout_fields' );
// Change the format of fields with type, label, placeholder, class, required, clear, label_class, options
function custom_wc_checkout_fields( $fields ) {
//BILLING
$fields['billing']['billing_first_name']['label'] = false;
return $fields;
}
?>
But since I want no labels anywhere, I was wondering if there's a way to remove all of them at once. Instead of going through them all individually. Does anybody have an idea?
Thanks!
EDIT:
I realize this is possible by just adding some css(display none), but since this is not a very clean solution, I was wondering if there is some other way to accomplish this.
You can remove any $field->property with unset.
Good reading and references can be found here: Customizing checkout fields using actions and filters
Now, for your question in how to do it globally, you can use a loop, something like:
// WooCommerce Checkout Fields Hook
add_filter('woocommerce_checkout_fields','custom_wc_checkout_fields_no_label');
// Our hooked in function - $fields is passed via the filter!
// Action: remove label from $fields
function custom_wc_checkout_fields_no_label($fields) {
// loop by category
foreach ($fields as $category => $value) {
// loop by fields
foreach ($value as $field => $property) {
// remove label property
unset($fields[$category][$field]['label']);
}
}
return $fields;
}
Online example: http://codepad.org/drvBYYS8
Related with good advise in acepted answer: WooCommerce Change Form Labels and Remove Fields
You can do this with css by adding the below, other than this I don't know of a way to remove all the labels at once.
.woocommerce form.checkout label
{
display: none;
}

Filtering 'the_content', but with Advanced Custom Fields

I'm using a str_replace to change the_content, using WordPress' default 'the_content'.
However, this does not seem to affect anything that has been submitted through the Advanced Custom Fields plugin.
My original function, that works with default WordPress editor:
function same_youtube_options($content) {
return str_replace("rel=0&", "rel0&theme=light&autohide=1&showinfo=0&controls=1&", $content);
}
add_filter('the_content', 'same_youtube_options');
And this, adjusted for the Advanced Custom Fields:
function same_youtube_options_controls_acf($field) {
$field = get_sub_field('iframe_url');
return str_replace("rel=0&", "rel0&&autohide=1&showinfo=0&controls=1&", $field);
}
add_filter('acf/load_field/name=iframe_url', 'same_youtube_options_controls_acf');
However, the latter does not work. It simply removes the field from the page. Would anyone know how to use these filters correctly?
Try this:--
function same_youtube_options_controls_acf($value, $post_id, $field )
{
// run the_content filter on all textarea values
$value = apply_filters('the_content',$value);
return $value;
}
add_filter('acf/load_value/name=iframe_url', 'same_youtube_options_controls_acf', 10, 3);
This hook will replace you custom field value with the_content filter.

Getting Input Fields from Gravity Forms on Woocommerce

Gravity Forms Product Add-ons for Woocommerce displays the form inputs of a user in the cart and checkout. I want to display these form fields in the user's Account page with their orders. I've been trying for a week and can't seem to get the right php code put together. How can I do this?
My code as it stands is like so:
$form_id = RGFormsModel::get_form_id('Domains');
$form = GFFormsModel::get_form_meta($form_id);
$field = GFFormsModel::get_field($form, 1);
$leads = RGFormsModel::get_leads($form['id']);
foreach($leads as $lead)
{
foreach($field as $field_id)
{
$value = rgar($lead, (string) $field_id);
echo $value;
}
}
This returns all entries for the field I want, however, I only want to return the entry that was submitted with that particular product. Help?
Here's a quick example for clarity on what I'm looking for. A user buys a shirt and selects size large from a Gravity Form that was attached to the product. On the cart and checkout pages, it says beneath the product title "Size: Large". I want to add that same text to the "My Account" page with their order.
The way I solved a similar problem may not be the best in coding practices but it works. It takes custom data associated with the order from Gravity Forms and displays it under the shipping address in WooCommerce individual order page:
<?php
add_action('woocommerce_admin_order_data_after_shipping_address', 'ips_show_signs_in_admin_under_shipping', 10, 1);
/*
function to put in functions.php of the theme to add custom gravityforms data to customer order page in admin area.
*/
function ips_show_signs_in_admin_under_shipping($order)
{
global $woocommerce, $post;
$order_items = $order->get_items(apply_filters('woocommerce_admin_order_item_types', array( 'line_item')));
foreach($order_items as $item_id => $item)
{
if ($metadata = $order->has_meta($item_id)) //not a comparison, so one equal sign. so if there is any data in there it would assign it and thus making it true, if no data it would be false
{
foreach($metadata as $meta)
{
// Skip hidden woocommerce core fields just in case
if (in_array($meta['meta_key'], apply_filters('woocommerce_hidden_order_itemmeta', array(
'_qty',
'_tax_class',
'_product_id',
'_variation_id',
'_line_subtotal',
'_line_subtotal_tax',
'_line_total',
'_line_tax',
)))) continue;
if (is_serialized($meta['meta_value'])) continue; // Skip serialised meta since we dont need it incase its in there
$meta['meta_key'] = esc_attr($meta['meta_key']); //just to make sure there is no surprises in there
$meta['meta_value'] = esc_textarea($meta['meta_value']); // using a textarea check for surprises (sql injection)
if ("Signpost Address" === $meta['meta_key']) //here comes the custom data from gravity forms
{
echo $meta['meta_value']; //this is what i was after from gravity forms collected with order
}
} //closes --- foreach($metadata as $meta)
} //closes --- if ($metadata = $order->has_meta($item_id))
} //closes --- foreach($order_items as $item_id => $item)
} //closes --- function
?>
Edit: This code searches the order meta data
I have added the above code in my functions.php file and unfortunately this hasn't worked for me. I have looked all over for a solution to this and this seems to exactly be what I'm after. Do i simply replace "Signpost Address" with say "Blanket Size" if that were one of my gravity form options?

Categories