Show WooCommerce custom checkout fields using a WP_Query - php

I use a plugin to create some custom B2B fields. Now I need these custom made fields to be shown at the checkout page.
function add_custom_b2b_fields_checkout( $fields ){
$args = array(
'post_type' => 'afreg_fields',
'post_status' => 'publish',
'posts_per_page' => '99',
'orderby' => 'name',
);
$get_b2b_fields = new WP_Query( $args );
if ($get_b2b_fields->have_posts()) : while ($get_b2b_fields->have_posts()) : $get_b2b_fields->the_post();
$fields['billing'][$get_b2b_fields->post_name] = array(
'type' => 'text',
'label' => get_the_title(),
'placeholder' => __(" ", "woocommerce"),
'class' => array('b2b-field'),
'required' => false,
);
endwhile;
return $fields;
endif;
}
add_filter( 'woocommerce_checkout_fields', 'add_custom_b2b_fields_checkout' );
The code works nice almost. But it shows only the last field, as if the while run correctly but the return $fields shows only the first custom field instead of all of them.
How can I show all the fields instead of just one? I tried adding a .= at the $fields but that didn't work.

There is a little mistake in your code as $get_b2b_fields->post_name is empty.
Simply replace:
$fields['billing'][$get_b2b_fields->post_name] = array(
with:
$fields['billing'][$get_b2b_fields->post->post_name] = array(
Now it will work.

add_filter( 'woocommerce_checkout_fields', 'add_custom_b2b_fields_checkout' );
change it to
add_action( 'woocommerce_checkout_fields', 'add_custom_b2b_fields_checkout' );
and add do_action('woocommerce_checkout_fields'); on the page where you want to show

Related

Add a custom taxonomy filter after product category filter in Woocommerce Admin products list

In my woocommerce storefront child theme, I have added several taxonomies. Now I would like to add a few category filters for those custom taxonomies.
I have added such a filter using this code (credit: Rodolfo Melogli)
add_filter( 'woocommerce_product_filters', 'admin_filter_products_by_din' );
function admin_filter_products_by_din( $output ) {
global $wp_query;
$output .= wc_product_dropdown_categories( array(
'show_option_all' => 'All DIN/ISO/ANSI',
'taxonomy' => 'din-iso-ansi',
'name' => 'din-iso-ansi',
'order' => 'ASC',
'tab_index' => '2',
'selected' => isset( $wp_query->query_vars['din-iso-ansi'] ) ? $wp_query->query_vars['din-iso-ansi'] : '',
) );
return $output;
}
The new category filter displays, but now I want the placement of my new taxonomy filter (DIN/ISO/ANSI) to go after the Product Categories filter.
product admin:
I figured this out with a lot of help from LoicTheAztec, essentially using most of his code, but it appears that we cannot substitute wp_dropdown_categories for wc_product_dropdown_categories so easily. After reviewing the function make-up of wc_product_dropdown_categories, I implemented another way to avoid having this function echo out the results by way of a little php.
add_filter( 'woocommerce_product_filters', 'admin_filter_products_by_din' );
function admin_filter_products_by_din( $output ) {
global $wp_query;
$taxonomy = 'din-iso-ansi';
$selected = isset( $wp_query->query_vars[$taxonomy] ) ? $wp_query->query_vars[$taxonomy] : '';
$info_taxonomy = get_taxonomy($taxonomy);
ob_start(); // buffer the result of wc_product_dropdown_categories silently
wc_product_dropdown_categories( array(
'show_option_none' => __("Select a {$info_taxonomy->label}"), // changed
'taxonomy' => $taxonomy,
'name' => $taxonomy,
//'echo' => false, // <== Needed for in filter hook
'tab_index' => '2',
'selected' => $selected,
'show_count' => true,
'hide_empty' => true,
));
$custom_dropdown = ob_get_clean();
$before = '<select name="product_type"'; //
$output = str_replace( $before, $custom_dropdown . $before, $output );
return $output;
}
Important notes:
wc_product_dropdown_categories() function output is echoed by default, and not convenient in a filter hook where all filtered data is always returned, so we will use the argument 'echo' set to false.
wc_product_dropdown_categories() function uses in fact wp_dropdown_categories() which is more convenient instead, for a custom taxonomy like yours.
To test your code I have used product_tag Woocommerce custom taxonomy to be sure that it works.
The following code will place your custom filter dropdown just after Product category filter:
add_filter( 'woocommerce_product_filters', 'admin_filter_products_by_din' );
function admin_filter_products_by_din( $output ) {
global $wp_query;
$taxonomy = 'din-iso-ansi';
$selected = isset( $wp_query->query_vars[$taxonomy] ) ? $wp_query->query_vars[$taxonomy] : '';
$info_taxonomy = get_taxonomy($taxonomy);
$custom_dropdown = wp_dropdown_categories(array(
'show_option_none' => __("Select a {$info_taxonomy->label}"), // changed
'taxonomy' => $taxonomy,
'name' => $taxonomy,
'order' => 'ASC',
'echo' => false, // <== Needed in a filter hook
'tab_index' => '2',
'selected' => $selected,
'show_count' => true,
'hide_empty' => true,
'value_field' => 'slug',
));
$after = '<select name="product_type"'; // The start of the html output of product type filter dropdown.
$output = str_replace( $after, $custom_dropdown . $after, $output );
return $output;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Wordpress Recent Posts/Projects

Hi I have created my own custom post type within Wordpress to contain projects that i can call via my theme files.
I am new to creating my own themes. I currently am using the following code in my single.php file to call in related articles based on the category of the blog post.
<?php
// Default arguments
$args = array(
'posts_per_page' => 3, // How many items to display
'post__not_in' => array( get_the_ID() ), // Exclude current post
'no_found_rows' => true, // We don't ned pagination so this speeds up the query
);
// Check for current post category and add tax_query to the query arguments
$cats = wp_get_post_terms( get_the_ID(), 'category' );
$cats_ids = array();
foreach( $cats as $wpex_related_cat ) {
$cats_ids[] = $wpex_related_cat->term_id;
}
if ( ! empty( $cats_ids ) ) {
$args['category__in'] = $cats_ids;
}
// Query posts
$wpex_query = new wp_query( $args );
// Loop through posts
foreach( $wpex_query->posts as $post ) : setup_postdata( $post ); ?>
<div class="col-md-4 related-post">
<?php the_post_thumbnail('large'); ?>
<?php the_title(); ?>
</div>
<?php
// End loop
endforeach;
// Reset post data
wp_reset_postdata(); ?>
In my new post type "projects" i would like to call in related projects. Which im assuming would be very similar code except i need to stop it looking for posts and instead look for my projects.
Here is my code for new post type:
// Projects
add_action( 'init', 'create_post_type' );
add_post_type_support( 'bw_projects', 'thumbnail' );
add_post_type_support( 'bw_projects', 'custom-fields' );
function create_post_type() {
register_post_type( 'bw_projects',
array(
'labels' => array(
'name' => __( 'Projects' ),
'singular_name' => __( 'Projects' )
),
'public' => true,
'has_archive' => true,
'taxonomies' => array( 'category','post_tag'),
)
);
}
What would i need to change in my first code snippet in order to look for bw_projects and not look for 'posts' anymore. I tried playing around and changing certain lines myself but i caused more issues and stopped the page loading. Is this even right i can use the same code, slightly altered or would i need something completely different?
Thanks in advance.
You can get any post type that you require using get_posts();
<?php $args = array(
'posts_per_page' => 5,
'offset' => 0,
'category' => '',
'category_name' => '',
'orderby' => 'date',
'order' => 'DESC',
'include' => '',
'exclude' => '',
'meta_key' => '',
'meta_value' => '',
'post_type' => 'projects',
'post_mime_type' => '',
'post_parent' => '',
'author' => '',
'author_name' => '',
'post_status' => 'publish',
'suppress_filters' => true
);
$posts_array = get_posts( $args ); ?>
Simply set the 'post_type' argument to that of you custom post type, to get only these posts. You can also set the number of post, and filter by category etc.
You can find more info in the codex.
Alternatively, if you wanted to keep something similar to your existing code you could try using 'pre_get_posts' to filter the query to just your projects. However you'd need to remember to add / remove this filter so it only operates on the queries that need it.
To display the posts you can use a simple foreach to churn them out. You#d obviously want to do some sort of styling to get the layout correct:
$args = array("posts_per_page" => 10, "orderby" => "comment_count");
$posts_array = get_posts($args);
foreach($posts_array as $post)
{
echo "<h1>" . $post->post_title . "</h1><br>";
echo "<p>" . $post->post_content . "</p><br>";
}
Or a really concise way of doing all of the above would be something like:
$args = array("posts_per_page" => 5, "post_type" => "projects");
$posts_array = get_posts($args);
foreach($posts_array as $post)
{
echo "<h1>" . $post->post_title . "</h1><br>";
echo "<p>" . $post->post_content . "</p><br>";
}

woocommerce custom admin tab breaks variations

I've added the ability to choose from custom post types in the woocommerce product admin tabs with a function as used in this tutorial http://www.remicorson.com/mastering-woocommerce-products-custom-fields/
so I've added a custom field
woocommerce_wp_select(
array(
'id' => '_circuit',
'label' => __( 'choose circuit', 'woocommerce' ),
'options' => get_circuits_as_array()
)
);
now the function looks like this
function get_circuits_as_array(){
$args = array( 'post_type' => 'top', 'posts_per_page' => -1, 'post_status'=>'published' );
$loop = new WP_Query( $args );
$circuits = array('0'=>'--wybierz opcję--');
while ( $loop->have_posts() ) : $loop->the_post();
setup_postdata( $post );
$circuits[get_the_id()] = get_the_title();
endwhile;
wp_reset_query();
return $circuits;
}
The problem is that while uploading the code to the server this function breaks the variations window it shows only the default "add variations message"
The console shows no errors.
I guess this has something to do with ajax requests but cant figure out exactly what, I've tries to move the get function in other files etc. but no luck.
The woocommerce plugin version is 2.2.8
OK so I've figured this out and the workaround is to use a foreach loop with $loop->posts as the array
function get_circuits_as_array(){
$args = array( 'post_type' => 'top', 'posts_per_page' => -1, 'post_status'=>'published' );
$loop = new WP_Query( $args );
$circuits = array('0'=>'--wybierz opcję--');
foreach ($loop->posts as $circuit) {
$circuits[$circuit->ID] = $circuit->post_title;
}
wp_reset_query();
return $circuits;
}

WordPress Getting post data for Post Grid of Visual Composer

I'm using Visual Composer in WordPress and I want to make a custom Post Grid. But the default elements that the post grid supplies are not enough. I want to show the author of the post, the number of comments it has, the category it has and the Tags it has as well. I'm not really familiar with Visual Composer, but I need a point in the right direction for me to get this data? What can I do? I've search their documents but with no luck. If I need to move around the php code I would like to know what I'm moving around is the right thing. Any ideas? If you need any more information please do ask :D
Thanks in advance for the help.
If anybody is still looking to find out how to to get the id in a post grid or create a specific widget for the grid you can use the following snippet I creatd for adding an icon before the post title. You will see inside the first function you can call $post-ID for use on any query.
//** Case Study Title Block Shortcodes ***********
//********************************
add_filter( 'vc_gitem_template_attribute_case_study_title','vc_gitem_template_attribute_case_study_title', 10, 2 );
function vc_gitem_template_attribute_case_study_title( $value, $data ) {
extract( array_merge( array(
'post' => null,
'data' => '',
), $data ) );
$atts_extended = array();
parse_str( $data, $atts_extended );
$atts = $atts_extended['atts'];
// write all your widget code in here using queries etc
$title = get_the_title($post->ID);
$link = get_permalink($post->ID);
$terms = get_the_terms($post->ID, 'case_categories');
$output = "<h4 class=\"case-title\">". get_the_icon($terms[0]->term_id) . $title ."</h4>";
return $output;
}
add_filter( 'vc_grid_item_shortcodes', 'case_study_title_shortcodes' );
function case_study_title_shortcodes( $shortcodes ) {
$shortcodes['vc_case_study_title'] = array(
'name' => __( 'Case Study Title', 'sage' ),
'base' => 'vc_case_study_title',
'icon' => get_template_directory_uri() . '/assets/images/icon.svg',
'category' => __( 'Content', 'sage' ),
'description' => __( 'Displays the case study title with correct icon', 'sage' ),
'post_type' => Vc_Grid_Item_Editor::postType()
);
return $shortcodes;
}
add_shortcode( 'vc_case_study_title', 'vc_case_study_title_render' );
function vc_case_study_title_render($atts){
$atts = vc_map_get_attributes( 'vc_case_study_title', $atts );
return '{{ case_study_title }}';
}
I got the same issue; here is how I solve it:
According to Visual Composer documentation: https://kb.wpbakery.com/docs/developers-how-tos/adding-custom-shortcode-to-grid-builder/
When you add the code below to functions.php, a new component will be added in your custom grid builder (in my example the name will be "Author"). There are a number of values you can get by post data template variable function and one of it not the name of the author but their ID (that's sad but at least you can use this value to get the author name).
The value is 'post_author' => ID of the author (for example '1')
Here is the function where I get the post author and display it (if author component was added to your custom grid in "custom grid builder"). Put it in functions.php of your child theme:
add_filter( 'vc_grid_item_shortcodes', 'my_module_add_grid_shortcodes' );
function my_module_add_grid_shortcodes( $shortcodes ) {
$shortcodes['vc_post_id'] = array(
'name' => __( 'Author', 'my-text-domain' ),
'base' => 'vc_post_id',
'category' => __( 'Content', 'my-text-domain' ),
'description' => __( 'Show current post author', 'my-text-domain' ),
'post_type' => Vc_Grid_Item_Editor::postType(),
);
return $shortcodes;
}
// output function
add_shortcode( 'vc_post_id', 'vc_post_id_render' );
function vc_post_id_render() {
$nn = '{{ post_data:post_author }}'; // usage of template variable post_data with argument "post_author"
return get_the_author($nn);
}
There is a little problem. It works but get_the_author is a deprecated function in WordPress. I'd appreciate any suggestions to make it more modern or if you name other alternatives please suggest.
Also, here is the list of available variables of vc_post_id_render from docs. Here they are:
WP_Post::__set_state(array(
'ID' => 69,
'post_author' => '1',
'post_date' => '2015-04-29 14:15:56',
'post_date_gmt' => '2015-04-29 14:15:56',
'post_content' => 'Your post content',
'post_title' => 'Your post title',
'post_excerpt' => '',
'post_status' => 'publish',
'comment_status' => 'open',
'ping_status' => 'open',
'post_password' => '',
'post_name' => 'post name',
'to_ping' => '',
'pinged' => '',
'post_modified' => '2015-06-17 11:18:41',
'post_modified_gmt' => '2015-06-17 11:18:41',
'post_content_filtered' => '',
'post_parent' => 0,
'guid' => 'http://wp.master/?p=69',
'menu_order' => 0,
'post_type' => 'post',
'post_mime_type' => '',
'comment_count' => '0',
'filter' => 'raw',
'filter_terms' =>
array (
),
))
this is your response
https://kb.wpbakery.com/docs/developers-how-tos/adding-custom-shortcode-to-grid-builder/
at Template variables usage
Exemple, in visual composer template you can use {{ post_date:ID }} to show post ID. I don't know how show tag.

not able to insert term programatically

I am trying to add terms using code but it's not added into wordpress. I am using below code to add
$term = wp_insert_term('Jogger', 'product_style',0);
Every time it return Invalid taxonomy. I have check my db and I don't found any entry for this. Even I have check with term_exists('Jogger', 'pa_style',0); and it also return 0. Can some have any idea about it.
I am able to add other terms like
$term = wp_insert_term('SPORTS', 'product_cat',0);
Use this code in functions.php
add_action( 'init', 'create_new_taxonomy' );
function create_new_taxonomy() {
register_taxonomy(
'product_style',
'products',
array(
'label' => __( 'Product Style' ),
'rewrite' => array( 'slug' => 'product_style' ),
'hierarchical' => true,
)
);
}
You can't insert term here because your taxonomy is not registered. So use the above code register it first. Then insert term.

Categories