Woocommerce Related Products - show products in price interval - woocommerce

I'm trying to modify related.php in order to randomly show any 3 products from the shop that has a price in the range of plus/minus 100.
I'm using ACF fields and Woocommerce 3.2.
The problem is that although the products are selected correctly, their price is not displayed. Instead, the price of the reference product is displayed for all 3 products.
Here is the code (price_obj is the ACF field for price):
global $product, $woocommerce_loop;
$product = new WC_Product(get_the_ID());
$price_product = get_field('price_obj',get_the_ID());
$args1=array(
'post_type' => 'product',
'posts_per_page' => -1,
'post__not_in' => array( $product->get_id() )
);
$products_in_range = array();
$my_query = new wp_query($args1);
if( $my_query->have_posts() ) {
$val = count($my_query->get_posts());
while ($my_query->have_posts()) {
$my_query->the_post();
$featured_image = wp_get_attachment_image_src( get_post_thumbnail_id(), 'large');
$price = get_field('price_obj');
$id = get_the_ID();
if ((($price_product-100) <= $price) && ($price <= ($price_product+100))){
array_push($products_in_range,$id);
}
}
}
wp_reset_query();
$rand_products = array_rand($products_in_range, 3);
?>
<?php if ($rand_products){ ?>
<div class="related products">
<h2><?php _e( 'Related Products', 'woocommerce' ); ?></h2>
<ul class="products">
<?php
foreach ($rand_products as $prod){
$title = get_the_title($products_in_range[$prod]);
$featured_image = wp_get_attachment_image_src( get_post_thumbnail_id($products_in_range[$prod]), 'large');
$link = get_permalink($products_in_range[$prod]);
$product_prod = new WC_Product($products_in_range[$prod]);
$price = wc_price($product->get_price());
?>
<li class="product type-product status-publish has-post-thumbnail first instock shipping-taxable purchasable product-type-simple">
<a href="<?php echo $link; ?>" class="woocommerce-LoopProduct-link">
<span class="et_shop_image">
<img width="400" height="400"
src="<?php echo $featured_image[0]; ?>"
class="attachment-shop_catalog size-shop_catalog wp-post-image"
alt=""
title="">
<span class="et_overlay"></span>
</span>
<h3><?php echo $title; ?></h3>
<span class="price">
<span class="woocommerce-Price-amount amount">
<?php echo $price; ?>
</span>
</span>
</a>
</li>
<?php } ?>
</ul>
</div>
Many thanks for any help!

get_field() can take three parameters. The first one is mandatory but the last 2 are optional.
get_field($selector, [$post_id], [$format_value]);
Where the $selector is the name of the field.The $post_id is self explanatory, but is defaulted to the current post and the $format_value decides whether you want to apply formatting logic.
Because you are calling the function via get_field('price_obj') and omitting the ID of the post you want it is defaulting to the current post in this case the post of the main item.
This is wrong, because you were inside the WordPress loop the right object was being saved into $price.
As you mentioned below, when you went to access the object via
$price = wc_price($product->get_price());
You were accessing the $product object, which is the main item. But your sub-product were stored in $product_prod, so to access it's price you had to change your code to
$price = wc_price($product_prod->get_price());

Related

Wordpress Category loop cannot retrieve ACF image gives Image Value: NULL

I am trying to get the image from a category but I cannot retrieve the image.
Today I already learned that I had to use
get_field('product', $term->taxonomy . '_' . $term->term_id);
to fetch content.
But when I use this same method to fetch an image URL from an ACF Field linked to my custom post type category, I do not recieve any values.
This is my code (the var_dump is included):
<?php
$args = array(
'post_type' => 'segments-overview',
'orderby' => 'date', // we will sort posts by date
);
$query = new WP_Query( $args );
$all_terms = [];
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
$terms = get_the_terms(get_the_ID(), 'category-segments-overview');
foreach($terms as $term) $all_terms[$term->term_id] = $term;
endwhile;
foreach($terms as $term):
?>
<div class="segments-card">
<div class="img">
<?php
$image = get_field('image', $term->taxonomy . '_' . $term->term_id);
if( !empty( $image ) ): ?>
<img src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>" />
<?php endif; ?>
</div>
<div class="content">
<div class="title"><?php echo $term->name; ?></div>
<!-- <?php print_r($term); ?> -->
<a class="button transparent" href="/segments/<?php echo $term->slug; ?>">
<?php echo __('View All','axia'); ?>
</a>
</div>
</div>
</div>
<?php endforeach;
wp_reset_postdata();
else :
?>
<div class="no-posts-found">
<h2>There were no items found</h2>
<h3>Please try a different search</h3>
</div>
<?php
endif;
?>
I use this var_dump to see if everything is fetched:
$image = get_field('image', $term->taxonomy . '_' . $term->term_id);
echo '<pre>';
echo "Image field value:";
var_dump($image);
echo "Category field value:";
var_dump($term);
echo '</pre>';
The only thing is that I do not get the value from my image in my category that is made in ACF.
You can simply get value by passing term object as second parameters.
$image = get_field('image', $term);
Check the docs here: https://www.advancedcustomfields.com/resources/adding-fields-taxonomy-term/

Thumbnail and price not showing on related products section

Well, I'm trying to create a module with the related products I have in my shop. My template has a file in the route /theme-name/woocommerce/single-product/related.php. In this we can see some code of how it call to the related product. It use the template as the listing product page (same template), but when I tried to shpw the thumbnail or the price it doesn't work. It only show me the title of the product, nothing else.
This is the code I have in my template for the file /related.php
<?php
if ( $related_products ) : ?>
<section id="nm-related" class="related products">
<div class="nm-row">
<div class="col-xs-12">
<h2><?php esc_html_e( 'Related products', 'woocommerce' ); ?></h2>
<?php woocommerce_product_loop_start(); ?>
<?php foreach ( $related_products as $related_product ) : ?>
<?php
$post_object = get_post( $related_product->get_id() );
setup_postdata( $GLOBALS['post'] =& $post_object );
wc_get_template_part( 'content', 'product' ); ?>
<?php endforeach; ?>
<?php woocommerce_product_loop_end(); ?>
</div>
</div>
</section>
<?php endif;
After that I use the "content-product" template like the listing page, where I don't have any problem.
For example, to show the product thumbnail I tried this:
<div class="nm-shop-loop-thumbnail nm-loader">
<a href="<?php echo esc_url( get_permalink() ); ?>" class="nm-shop-loop-thumbnail-link woocommerce-LoopProduct-link">
<?php
$id_pro = get_the_ID();
$pro_2 = get_post_thumbnail_id($id_pro);
$featured_image_url = wp_get_attachment_url( $pro_2 );
if(! empty( $featured_image_url )) { ?>
<?php
/**
* Hook: woocommerce_before_shop_loop_item_title.
*
* #hooked woocommerce_show_product_loop_sale_flash - 10
* #hooked woocommerce_template_loop_product_thumbnail - 10
*/
do_action( 'woocommerce_before_shop_loop_item_title' );
} else { ?>
<img src="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg" data-src="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg" data-srcset="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 350w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 250w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 400w" alt="" sizes="(max-width: 350px) 100vw, 350px" width="350" height="420" class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail wp-post-image lazyloaded" srcset="https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 350w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 250w, https://cdn.mtods.ch/wp-content/uploads/sites/2/20190409092145/nopic.jpg 400w">
<?php
}
?>
</a>
</div>
And as I said, it works for the listing page but not inside single page product in related products section.
The $id_pro variable work in both pages, it shows the id of the product, but when I try to get the thumbnail URL with this id it return me "".
In the first image you can see the example for the listing page, on the other hand, in the second image you can see the example for the related products for the single product page:
I change the functionality and I created a new related product module, but still not working I don't know why...
I tried this:
In my related.php:
// Same category products query
$mproduct = new WP_Query(array(
'post_type' => 'product',
'product_cat' => $cat_slug,
'posts_per_page' => -1,
));
// Get query data
$posts = $mproduct->get_posts();
$num = $mproduct->post_count;
// Create new array with the actual product in it
$array_pro = [];
$array_pro[] = $product_id;
// Function for check if product is in array
function test_function($rand_pro, $array_pro, $posts, $num) {
if (in_array($rand_pro, $array_pro)) {
$new_pro_id = $posts[rand(0,$num-1)]->ID;
return true;
} else {
return false;
}
}
// If array is not full insert next elements
while (count($array_pro) < 5) {
$rand_pro = $posts[rand(0,$num-1)]->ID;
$pro_in_array = test_function($rand_pro, $array_pro, $posts, $num);
if ($pro_in_array == false) {
$array_pro[] = $rand_pro;
}
}
// Remove first element of array
array_shift($array_pro);
?>
<div class="related-products-row">
<?php
foreach( $array_pro as $post ) {
$rel_product_id = $post;
$rel_product_title = get_the_title($rel_product_id);
$rel_product_link = get_the_permalink($rel_product_id);
$rel_product_img_url = get_the_post_thumbnail($rel_product_id);
$_product = wc_get_product( $rel_product_id );
$rel_product_ref = $_product->get_attribute( 'reference' );
?>
<div class="col-md-3">
<p><?php echo $rel_product_img_url; ?></p>
</div>
<?php
}
?>
</div>
If you can see, when I try to getthe name I don't have problems but when I try to get the post_thumbnail_url or ref_number it doesn't show anything I don't know why.

ACF + Isotope: Filter Post Object Data

I'm trying to filter data from a custom post-type called "Clients", based on category. What I need to appear is the logo for each particular client.
I've set up a repeater field of Post Objects, so I can change the order that the logos will be displayed.
What I have currently works, however I cannot figure out how to incorporate the Post Object selector, so that what appears is determined by the instances I've added via the Repeater.
Here is the link to the site. Appreciate any answers!
See below for screenshot of my dashboard setup:
<ul id="filters">
<?php
$terms = get_terms("category", array(
'orderby' => 'slug'
)); // get all categories, but you can use any taxonomy
$count = count($terms); //How many are they?
if ( $count > 0 ){ //If there are more than 0 terms
foreach ( $terms as $term ) { //for each term:
echo "<li><a href='#' data-filter='.".$term->slug."'>" . $term->name . "</a></li>\n";
//create a list item with the current term slug for sorting, and name for label
}
}
?>
</ul>
<?php $the_query = new WP_Query(array(
'post_type' => 'clients',
'posts_per_page' => '-1',
'order' => 'ASC'
)); //Check the WP_Query docs to see how you can limit which posts to display ?>
<?php if ( $the_query->have_posts() ) : ?>
<div class="isotope-list-container">
<div id="isotope-list" class="row small-up-1 medium-up-2 large-up-3">
<?php while ( $the_query->have_posts() ) : $the_query->the_post();
$termsArray = get_the_terms( $post->ID, "category" ); //Get the terms for this particular item
$termsString = ""; //initialize the string that will contain the terms
foreach ( $termsArray as $term ) { // for each term
$termsString .= $term->slug.' '; //create a string that has all the slugs
}
?>
<div class="<?php echo $termsString; ?> portfolio columns"> <?php // 'portfolio' is used as an identifier (see Setp 5, line 6) ?>
<div class="portfolio-item-container">
<?php
$image = get_field('logo');
if( !empty($image) ): ?>
<img src="<?php echo $image['url']; ?>" alt="<?php echo $image['alt']; ?>" />
<?php endif; ?>
</div>
</div> <!-- end portfolio item -->
<?php endwhile; ?>
</div> <!-- end isotope-list -->
</div>
<?php endif; ?>
<?php wp_reset_query(); ?>
I was able to make this considerably simpler by using the Post Types Order plugin to reorder my posts.
https://wordpress.org/plugins/post-types-order/

Prevent Post Duplication

I am in charge of managing this site F9 Properties which is built in WordPress. On the home page there is a featured properties section. I noticed that if you listed a property with two different "Status" such as "For Sale or For Lease, the property appeared twice in the carousel. Below is the code for listing the featured properties. I can see that it filters out the properties with the Status "Leased". Can anyone help me add a bit of code to list only one property per post regardless of how many different property status it has?
<?php
/* Featured Properties Query Arguments */
$featured_properties_args = array(
'post_type' => 'property',
'posts_per_page' => 100,
'meta_query' => array(
array(
'key' => 'REAL_HOMES_featured',
'value' => 1,
'compare' => '=',
'type' => 'NUMERIC'
)
)
);
$featured_properties_query = new WP_Query( $featured_properties_args );
if ( $featured_properties_query->have_posts() ) :
?>
<section class="featured-properties-carousel clearfix">
<?php
$featured_prop_title = get_option('theme_featured_prop_title');
$featured_prop_text = get_option('theme_featured_prop_text');
if(!empty($featured_prop_title)){
?>
<div class="narrative">
<h3><?php echo $featured_prop_title; ?></h3>
<?php
if(!empty($featured_prop_text)){
?><p><?php echo $featured_prop_text; ?></p><?php
}
?>
</div>
<?php
}
?>
<div class="carousel es-carousel-wrapper">
<div class="es-carousel">
<ul class="clearfix">
<?php
while ( $featured_properties_query->have_posts() ) :
$featured_properties_query->the_post();
?>
<?php
$status_terms = get_the_terms( $post->ID,"property-status" );
if(!empty( $status_terms )){
foreach( $status_terms as $status_term ){
if($status_term->name=="Leased"){}else{
?>
<li>
<figure>
<a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>">
<?php
the_post_thumbnail('property-thumb-image',array(
'alt' => get_the_title($post->ID),
'title' => get_the_title($post->ID)
));
?>
</a>
</figure>
<h4><?php the_title(); ?></h4>
<p><?php framework_excerpt(8); ?> <?php _e('Know More','framework'); ?> </p>
<span class="price"><?php property_price(); ?></span>
</li>
<?
}
}
}
?>
<?php
endwhile;
wp_reset_query();
?>
</ul>
</div>
</div>
I might be misunderstanding your setup, but I wonder why you're looping over the terms.
I think you should instead consider excluding the leased term within the WP_Query() part (hopefully you can share it).
Then your carousel would be simplified to:
<div class="carousel es-carousel-wrapper">
<div class="es-carousel">
<ul class="clearfix">
<?php while ( $featured_properties_query->have_posts() ) : $featured_properties_query->the_post(); ?>
<li><!-- YOUR POST ITEM HERE --></li>
<?php endwhile; ?>
</ul>
</div>
</div>
You can add the post ID to an array every time an iteration occurs, and check the array if the post has already been rendered:
$shown = array(); // new array
while ( $featured_properties_query->have_posts() ) :
$featured_properties_query->the_post();
$status_terms = get_the_terms( $post->ID, 'property-status' );
if( ! empty( $status_terms ) ){
foreach( $status_terms as $status_term ){
if( $status_term->name == "Leased" || in_array( $post->ID, $shown ){
continue; // post has term "Leased" or already rendered, skip
}
$shown[] = $post->ID; // add post ID to array
?>
<!-- HTML here -->
<?php
}
}
endwhile;

Twitter API 1.1 to display latest tweets

I was using the following code to get latest tweets of my account to my wordpress website. As soon as twitter launched its new API 1.1, it all broke completely. How to proceed.
<?php // Get RSS Feed(s)
include_once( ABSPATH . WPINC . '/feed.php' );
// Get a SimplePie feed object from the specified feed source.
$rss = fetch_feed( 'https://api.twitter.com/1/statuses/user_timeline.rss?screen_name='.$cvt_twitter );
if ( ! is_wp_error( $rss ) ) : // Checks that the object is created correctly
// Figure out how many total items there are, but limit it to 5.
$maxitems = $rss->get_item_quantity( 5 );
// Build an array of all the items, starting with element 0 (first element).
$rss_items = $rss->get_items( 0, $maxitems );
endif;
?>
<ul style="list-style:none;">
<?php if ( $maxitems == 0 ) : ?>
<li><?php _e( 'No items', 'my-text-domain' ); ?></li>
<?php else : ?>
<?php // Loop through each feed item and display each item as a hyperlink.
foreach ( $rss_items as $item ) : ?>
<li>
<div class="row">
<div class="span2">
<a class="thumb" href="<?php echo esc_url( $item->get_permalink() ); ?>" target="_blank">
<img width="100" height="auto" src="<?=$cvt_logo?>">
</a>
</div>
<div class="span9">
<a href="<?php echo esc_url( $item->get_permalink() ); ?>"
title="<?php printf( __( 'Posted %s', 'my-text-domain' ), $item->get_date('j F Y | g:i a') ); ?>" target="_blank">
<?php $string = esc_html( $item->get_title() );
$word = substr($string, 0, strpos($string, ':')+1);
echo str_replace($word, "", $string); ?>
</a>
</div></div>
</li>
<?php endforeach;
endif; ?>
</ul>
Try using the Twitter API 1.1 Client for WordPress.
It's very easy to implement and all you need is your consumer_key and consumer_secret.
Example (from the README):
<?php
// Include Twitter API Client
require_once( 'class-wp-twitter-api.php' );
// Set your personal data retrieved at https://dev.twitter.com/apps
$credentials = array(
'consumer_key' => 'xxxxxxxxxxxxxxxx',
'consumer_secret' => 'xxxxxxxxxxxxxxxx'
);
// Let's instantiate Wp_Twitter_Api with your credentials
$twitter_api = new Wp_Twitter_Api( $credentials );
// Example a - Retrieve last 5 tweets from my timeline (default type statuses/user_timeline)
$query = 'count=5&include_entities=true&include_rts=true&screen_name=micc1983';
var_dump( $twitter_api->query( $query ) );

Resources