woocommerce custom admin tab breaks variations - php

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;
}

Related

How to update values of a specific custom field for every woocommerce product at once

I want to update a value to a specific custom field in all Woocommerce products at once.
But this is not working
function update_products_by_x(){
$products_ids = get_posts( array(
'post_type' => 'product', // or ['product','product_variation'],
'post_status' => 'publish',
'fields' => 'ids'
) );
foreach ( $products_ids as $product_id ) {
$product = wc_get_product($product_id);
update_post_meta($product_id, 'field_name_here', esc_attr('field_value_here'));
}
}
add_action('wp_footer', 'update_products_by_x');
Use WP_Query to retrieve all products and hook your function to init:
add_action('init', 'update_products_by_x');
function update_products_by_x(){
if(isset($_GET['update_woo_products'])){
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
);
$loop = new WP_Query( $args );
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
update_post_meta($product->ID, 'field_name_here', esc_attr('field_value_here'));
endwhile;
wp_reset_query();
die('done');
}
}
If you notice there is a small condition to make sure that this only run if requested, so to run this function you'd need to visit the website and make sure you add the parameter update_woo_products as a query string (eg: https://example.com/?update_woo_products=1 )
This will run the function and show a white page with the message done, which means that the condition was met and the function was executed successfully.

Wordpress short code to display all child page by parents ID

I'm working on a short code for loop through parents ID and display all child page, but I'm not quite sure how to make the loop and make it more custom.
Here's my code:
add_shortcode( 'home-page-listing', 'get_list' );
function get_list( $atts ) {
ob_start();
$atts = shortcode_atts( array(
'ids' => ''
), $atts );
if($atts['ids']!='')
{
$id_array = explode(',',$atts['ids']);
$homePages = new WP_Query( array(
'post_type' => 'page',
'post__in'=>$id_array,
'order' => 'ASC',
'orderby' => 'post__in',
'posts_per_page' => -1
) );
if ($homePages->have_posts()){?>
<div class="">
<?php while ( $homePages->have_posts() ) : $homePages->the_post(); ?>
//here's html template code
<?php endwhile;
wp_reset_postdata(); ?>
</div>
}
}
}
Right now I can use [home-page-listing id=1,2,3,4] to display all select page ID, but I would like to make like this:
[home-page-listing parentID=4]
loop through all child page and display to the font, instead go check all the page id to display.
Thanks!
it's simple used post_parent Arguments of WP_Query. Please check below example
$homePages = new WP_Query( array(
'post_type' => 'page',
'post_parent'=>$parentID,
'order' => 'ASC',
'orderby' => 'parent',
'posts_per_page' => -1
) );
For more information of WP_Query click here

Get featured products in Woocommerce 3

I want to add Featured products for upsell (or Recent Products OR Best Selling Products) in New order Email template. It works like Upsell with email marketing. How do I add it to woocommerce email template so that there is a section in the end of the email which shows my featured/Recent/best selling products. I tried using this code in my New order Email template but nothing works. I use all latest version of wordpress n woocommerce.
$args = array(
'post_type' => 'product',
'meta_key' => '_featured',
'meta_value' => 'yes',
'posts_per_page' => 1
);
$featured_query = new WP_Query( $args );
if ($featured_query->have_posts()) :
while ($featured_query->have_posts()) :
$featured_query->the_post();
$product = get_product( $featured_query->post->ID );
// Output product information here
endwhile;
endif;
wp_reset_query(); // Remember to reset
Since Woocommerce 3, the products following properties:
"featured",
"stock status",
"catalog visibility"
"rating system"
are now stored like a post term under 'product_visibility' taxonomy, for better performances. So old postmeta data doesn't work anymore.
To make your code working you need instead to make a tax_query this way:
function custom_featured_products(){
$query = new WP_Query( array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1 ,
'tax_query' => array( array(
'taxonomy' => 'product_visibility',
'field' => 'term_id',
'terms' => 'featured',
'operator' => 'IN',
) )
) );
$featured_product_names = array();
if ( $query->have_posts() ): while ( $query->have_posts() ): $query->the_post();
$product = wc_get_product( $query->post->ID );
$featured_product_names[] = $product->get_title();
endwhile; wp_reset_query();endif;
// Testing output
echo '<p>Featured products: ' . implode(', ', $featured_product_names) . '</p>';
}
// Displaying the featured products names in new order email notification
add_action ('woocommerce_email_customer_details', 'new_order_featured_products_display', 30, 4 );
function new_order_featured_products_display( $order, $sent_to_admin, $plain_text, $email ){
// Only for "New Order" email notification
if( 'new_order' != $email->id ) return;
custom_featured_products(); // calling the featured products function output
}
This code goes on function.php file of your active child theme (or theme).
Tested and works.
Updated related to your comments…
Added the code in a function that is called via a hooked function in "New order" email notification.
To get the product image use: $product->get_image( 'shop_thumbnail' );
To get the product link use : $product->get_permalink();
<ul class="products">
<?php
$args = array(
'post_type' => 'product',
'posts_per_page' => 12,
'tax_query' => array(
array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
),
),
);
$loop = new WP_Query( $args );
if ( $loop->have_posts() ) {
while ( $loop->have_posts() ) : $loop->the_post();
echo '<p>'.get_the_title().'</p>';
endwhile;
} else {
echo __( 'No products found' );
}
wp_reset_postdata();
?>
</ul><!--/.products-->

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>";
}

View Woocommerce data in Wordpress

I am using this code to try and get products and categories from woocommerce
function get_me_list_of($atts, $content = null)
{
$args = array( 'post_type' => 'product', 'posts_per_page' => 10, 'product_cat' => $atts[0], 'orderby' => 'rand' );
$loop = new WP_Query( $args );
echo '<h1 class="upp">Style '.$atts[0].'</h1>';
echo "<ul class='mylisting'>";
while ( $loop->have_posts() ) : $loop->the_post();
global $product;
echo '<li>'.get_the_post_thumbnail($loop->post->ID, 'thumbnail').'</li>';
endwhile;
echo "</ul>";
wp_reset_query();
}
I put this in a file and named it "template-prods.php" in the wordpress theme being used. I then created a new page and used the Template "prods". But nothing shows up on the page.
Is there something wrong with the code or is it the way I tried to view the data (ie creating an template and using it in a new page)?

Categories