Presumably simple PHP if/else statement not working - php

I seem to be having trouble with another piece of what seems to be super basic PHP, but it just won't work for me.
My client (real estate website) needs to be able to have properties with no price to be either “price upon request” OR “auction”. Currently, leaving the price field blank only allows for one.
I tried changing the following code:
$listing_price_labels = array(
‘sold’ => __( ‘Sold’, ‘wpsight’ ),
‘rented’ => __( ‘Rented’, ‘wpsight’ ),
‘request’ => __( ‘Price on request’, ‘wpsight’ ),
‘auction’ => __( ‘Auction’, ‘wpsight’ ), ***– Added this line***
);
And where this code is found…
if( is_admin() )
$listing_price .= ‘<br />’ . wpsight_get_price_value();
} elseif( empty( $listing_price ) ) {
// When no price available Price on request
$listing_price = ‘<span class=”listing-price-on-request”>’ . $listing_price_labels['request'] . ‘</span><!– .listing-price-on-request –>’;
} elseif( $listing_price = ‘auction’ ) {
// When price field contains ‘auction’ (case sensitive)
$listing_price = ‘<span class=”listing-price-on-request”>’ . $listing_price_labels['auction'] . ‘</span><!– .listing-price-on-request –>’;
}
function wpsight_get_price( $post_id = '' ) {
// Get post ID from $post_id
if( empty( $post_id ) )
$post_id = get_the_ID();
// If still empty, return false
if( empty( $post_id ) )
return false;
// Set listing price labels
$listing_price_labels = array(
'sold' => __( 'Sold', 'wpsight' ),
'rented' => __( 'Rented', 'wpsight' ),
'request' => __( 'Price on request', 'wpsight' ),
'auction' => __( 'Auction', 'wpsight' ),
);
$listing_price_labels = apply_filters( 'wpsight_get_price_labels', $listing_price_labels );
// Get listing price
$listing_price = wpsight_get_price_value();
// Get custom fields
$custom_fields = get_post_custom( $post_id );
$listing_status = isset( $custom_fields['_price_status'][0] ) ? $custom_fields['_price_status'][0] : false;
$listing_availability = isset( $custom_fields['_price_sold_rented'][0] ) ? $custom_fields['_price_sold_rented'][0] : false;
// Create price output
if( ! empty( $listing_availability ) ) {
// When listing is not available
$sold_rented = ( $listing_status == 'sale' ) ? $listing_price_labels['sold'] : $listing_price_labels['rented'];
// Display sold/rented bold red in admin
$style = is_admin() ? ' style="color:red;font-weight:bold"' : false;
$listing_price = '<span class="listing-price-sold-rented"' . $style . '>' . $sold_rented . '</span><!-- .listing-price-sold-rented -->';
if( is_admin() )
$listing_price .= '<br />' . wpsight_get_price_value();
} elseif( empty( $listing_price ) ) {
// When no price available Price on request
$listing_price = '<span class="listing-price-on-request">' . $listing_price_labels['request'] . '</span><!-- .listing-price-on-request -->';
} elseif( $listing_price == "auction" ) {
// When price field contains 'auction' (case sensitive)
$listing_price = '<span class="listing-price-on-request">' . $listing_price_labels['auction'] . '</span><!-- .listing-price-on-request -->';
}
return apply_filters( 'wpsight_listing_price', $listing_price );
}
I’m sure my syntax must just be wrong, because with that code in place it makes any property with anything at all written into the price field display “auction”.
Can anyone see what I've done wrong?

try:
if( is_admin() ){
$listing_price .= ‘<br />’ . wpsight_get_price_value();
} elseif( empty( $listing_price ) ) {
// When no price available Price on request
$listing_price = ‘<span class=”listing-price-on-request”>’ . $listing_price_labels['request'] . ‘</span><!– .listing-price-on-request –>’;
}
btw its not recommended to use if( is_admin() ) since its only applicable on 1 line.

Related

Replace zero with FREE for WooCommerce shipping rates on single product page

Based on the answer on my previous question, Issue display shipping data on WooCommerce single product page, I'm trying to replace the 0 with FREE or whatever word I choose.
Problem is, whatever I do, it does not work. This is my attempt and I need help with it:
add_action('woocommerce_after_add_to_cart_form', 'display_shipping_on_product_page', 10, 0);
function display_shipping_on_product_page(){
// get all zones
$zones = WC_Shipping_Zones::get_zones();
// get the shop base country
$base_country = WC()->countries->get_base_country();
$base_city = WC()->countries->get_base_city();
// start display of table
echo '<div>' . __( '<b>Available Shipping</b>', 'woocommerce' );
echo '<br><small><span class="shipping-time-cutoff">All orders are shipped from the '.$base_country.'. Order before 12AM Mon-Fri for same day delivery within '.$base_city.'. Order before 3PM Mon-Thu for next day delivery.</span></small>';
echo '<small><table class="shipping-and-delivery-table">';
// get name of each zone and each shipping method for each zone
foreach ( $zones as $zone_id => $zone ) {
echo '<tr><td>';
echo '<strong>' . $zone['zone_name'] . '</strong>' . '</td><td>';
$zone_shipping_methods = $zone['shipping_methods'];
foreach ( $zone_shipping_methods as $index => $method ) {
$instance = $method->instance_settings;
if ( isset( $instance['min_amount'] ) ) {
$instance_min_amount = $instance['min_amount'];
} else {
$instance_min_amount = 0;
}
if ( isset( $instance['cost'] ) ) {
$instance_cost = $instance['cost'];
} else {
$instance_cost = str_replace($instance_cost, "FREE" );
}
$cost = $instance_cost ? $instance_cost : $instance_min_amount;
$above = $instance_min_amount ? 'above ' : '';
echo $instance['title'] . ': ' . $above . '<strong>' . wc_price( $cost ) . '</strong>' . '<br>';
}
echo '</td></tr>';
}
echo '</table></small></div>';
}
This is what I tried to add / edit without success:
$instance_cost = str_replace($instance_cost, "FREE" );
To display 'free' instead of 0, you need to change your if/else conditions. Explanation via comment tags added to my answer.
So you get:
function action_woocommerce_after_add_to_cart_form() {
// get all zones
$zones = WC_Shipping_Zones::get_zones();
// get the shop base country
$base_country = WC()->countries->get_base_country();
$base_city = WC()->countries->get_base_city();
// start display of table
echo '<div>' . __( 'Available Shipping', 'woocommerce' );
echo '<br><small><span class="shipping-time-cutoff">All orders are shipped from the '.$base_country.'. Order before 12AM Mon-Fri for same day delivery within '.$base_city.'. Order before 3PM Mon-Thu for next day delivery.</span></small>';
echo '<small><table class="shipping-and-delivery-table">';
// get name of each zone and each shipping method for each zone
foreach ( $zones as $zone_id => $zone ) {
echo '<tr><td>';
echo '<strong>' . $zone['zone_name'] . '</strong>' . '</td><td>';
$zone_shipping_methods = $zone['shipping_methods'];
foreach ( $zone_shipping_methods as $index => $method ) {
$instance = $method->instance_settings;
// Initialize
$above = '';
$output_cost = __( 'Free', 'woocommerce' );
// Cost isset
if ( isset( $instance['cost'] ) ) {
// NOT empty
if ( ! empty ( $instance['cost'] ) ) {
// Output
$output_cost = wc_price( $instance['cost'] );
}
}
// Min amount isset
if ( isset( $instance['min_amount'] ) ) {
// NOT empty
if ( ! empty ( $instance['min_amount'] ) ) {
// Above
$above = __( 'above ', 'woocommerce' );
// Output
$output_cost = wc_price( $instance['min_amount'] );
}
}
echo $instance['title'] . ': ' . $above . '<strong>' . $output_cost . '</strong>' . '<br>';
}
echo '</td></tr>';
}
echo '</table></small></div>';
}
add_action( 'woocommerce_after_add_to_cart_form', 'action_woocommerce_after_add_to_cart_form', 10, 0 );

Replace WooCommerce placeholder image based on product category

I'm trying to change default image placeholder for products with no images to images according to their product category.
I'm using:
add_filter( 'woocommerce_placeholder_img_src', 'my_custom_woocommerce_placeholder', 10 );
// Function to return new placeholder image URL.
function my_custom_woocommerce_placeholder( $image_url )
{
if ($product_category == 'category1') {
$image_url = 'http://website.com/imageforCategory.png';
}
elseif ($product_category == 'category2') {
$image_url = 'http://website.com/imageforCategory.png';
}
else
{
$image_url = 'http://website.com/defaultImage.png';
}
return $image_url;
}
I'm stuck at getting product category ($product_category) detected in functions.php file of my theme.
In content-single-product.php page I'm just defining
global $product
and then just using
$product->get_categories();
to get the category of product.
How do I do it in functions.php of my theme?
You could use has_term() - Checks if the current post has any of given terms.
So you get:
// Single product page
function filter_woocommerce_placeholder_img_src( $src ) {
// Get the global product object
global $product;
// Is a WC product
if ( is_a( $product, 'WC_Product' ) ) {
// Has term (product category)
if ( has_term( 'categorie-1', 'product_cat', $product->get_id() ) ) {
$src = 'http://website.com/imageforCategory1.png';
} elseif ( has_term( array('categorie-2', 'categorie-3'), 'product_cat', $product->get_id() ) ) {
$src = 'http://website.com/imageforCategory2.png';
}
}
return $src;
}
add_filter( 'woocommerce_placeholder_img_src', 'filter_woocommerce_placeholder_img_src', 10, 1 );
// Archive/Shop page
function filter_woocommerce_placeholder_img ( $image_html, $size, $dimensions ) {
$dimensions = wc_get_image_size( $size );
$default_attr = array(
'class' => 'woocommerce-placeholder wp-post-image',
'alt' => __( 'Placeholder', 'woocommerce' ),
);
$attr = wp_parse_args( '', $default_attr );
$image = wc_placeholder_img_src( $size );
$hwstring = image_hwstring( $dimensions['width'], $dimensions['height'] );
$attributes = array();
foreach ( $attr as $name => $value ) {
$attribute[] = esc_attr( $name ) . '="' . esc_attr( $value ) . '"';
}
$image_html = '<img src="' . esc_url( $image ) . '" ' . $hwstring . implode( ' ', $attribute ) . '/>';
return $image_html;
}
add_filter( 'woocommerce_placeholder_img', 'filter_woocommerce_placeholder_img', 10, 3 );
Note: the woocommerce_placeholder_img hook, used on archive/shop page returns $image_html. That string can be adapted to your needs. Such as image src, class, alt, size, etc ..

Change wc_cart_totals_shipping_method_label function in Woocommerce

Inside Woocommerce plugin on the includes subfolder, there's a file wc-cart-functions.php.
I would like to change the function wc_cart_totals_shipping_method_label(), but I am not allowed to copy the function to my theme's functions.php. I believe I have to use a custom action/filter to change this core function, but no idea how to do that.
Original function:
function wc_cart_totals_shipping_method_label( $method ) {
$label = $method->get_label();
$has_cost = 0 < $method->cost;
$hide_cost = ! $has_cost && in_array( $method->get_method_id(), array( 'free_shipping', 'local_pickup' ), true );
if ( $has_cost && ! $hide_cost ) {
if ( WC()->cart->display_prices_including_tax() ) {
$label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() );
if ( $method->get_shipping_tax() > 0 && ! wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$label .= ': ' . wc_price( $method->cost );
if ( $method->get_shipping_tax() > 0 && wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}
return apply_filters( 'woocommerce_cart_shipping_method_full_label', $label, $method );
}
What the function should be:
function wc_cart_totals_shipping_method_label( $method ) {
$label = $method->get_label();
$has_cost = 0 < $method->cost;
$hide_cost = ! $has_cost && in_array( $method->get_method_id(), array( 'free_shipping', 'local_pickup' ), true );
if ( $has_cost && ! $hide_cost ) {
if ( WC()->cart->display_prices_including_tax() ) {
$label .= ': ' . wc_price( $method->cost + $method->get_shipping_tax() );
if ( $method->get_shipping_tax() > 0 && ! wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->inc_tax_or_vat() . '</small>';
}
} else {
$label .= ': ' . wc_price( $method->cost );
if ( $method->get_shipping_tax() > 0 && wc_prices_include_tax() ) {
$label .= ' <small class="tax_label">' . WC()->countries->ex_tax_or_vat() . '</small>';
}
}
}
/* Here's the code I want added */
elseif ( ! $has_cost && ! $hide_cost ) {
$label .= ': Free';
}
return apply_filters( 'woocommerce_cart_shipping_method_full_label', $label, $method );
}
What I want to do:
Shipping methods that have zero cost should have "Free" added to their label. Right now there's nothing shown beside the method title.
How can I make the necessary changes to this function, without overwriting Woocommerce core files?
As you can see in this function you can use woocommerce_cart_shipping_method_full_label filter hook, to manage that change, this way:
add_filter( 'woocommerce_cart_shipping_method_full_label', 'change_cart_shipping_method_full_label', 10, 2 );
function change_cart_shipping_method_full_label( $label, $method ) {
$has_cost = 0 < $method->cost;
$hide_cost = ! $has_cost && in_array( $method->get_method_id(), array( 'free_shipping', 'local_pickup' ), true );
if ( ! $has_cost && ! $hide_cost ) {
$label = $method->get_label() . ': Free';
}
return $label;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Show "Out Of Stock" next to product variation in Woocommerce

I want to make some modification of my site, but for some reason, can get it. i tryed to use this function that found into this thread of Stack :
add_filter( 'woocommerce_variation_option_name',
'customizing_variations_terms_name', 10, 1 );
function customizing_variations_terms_name( $term_name ){
if(is_admin())
return $term_name;
global $product;
$second_loop_stoped = false;
// Get available product variations
$product_variations = $product->get_available_variations();
// Iterating through each available product variation
foreach($product_variations as $variation){
$variation_id = $variation['variation_id'];
$variation_obj = new WC_Product_Variation( $variation_id );
## WOOCOMMERCE RETRO COMPATIBILITY ##
if ( version_compare( WC_VERSION, '3.0', '<' ) ) # BEFORE Version 3 (older)
{
$stock_status = $variation_obj->stock_status;
$stock_qty = intval($variation_obj->stock);
// The attributes WC slug key and slug value for this variation
$attributes_arr = $variation_obj->get_variation_attributes();
}
else # For newest verions: 3.0+ (and Up)
{
$stock_status = $variation_obj->get_stock_status();
$stock_qty = $variation_obj->get_stock_quantity();
// The attributes taxonomy key and slug value for this variation
$attributes_arr = $variation_obj->get_attributes();
}
if(count($attributes_arr) != 1) // Works only for 1 attribute set in the product
return $term_name;
// Get the terms for this attribute
foreach( $attributes_arr as $attr_key => $term_slug){
// Get the attribute taxonomy
$term_key = str_replace('attribute_', '', $attr_key );
// get the corresponding term object
$term_obj = get_term_by( 'slug', $term_slug, $term_key );
if( $term_obj->name == $term_name ){ // If the term name matches we stop the loops
$second_loop_stoped = true;
break;
}
}
if($second_loop_stoped)
break;
}
if( $stock_qty>0 )
return $term_name .= ' - ' . $stock_status . ' ('.$stock_qty.')';
else
return $term_name .= ' - ' . $stock_status;
}
but for some reason when insert into functions, show me "outofstock" next to every variation. I dont use standard Woocommerce dropdown variation style, and use WC Variations Radio Buttons to show radio buttons next to each variation, instead of dropdown. The problem is that i want to show only "Out Of Stock" , next to each variation. not "In Stock", so customer will know that wanted variation is not in stock before press Add to Cart button. SO seems that issue is this code:
if( $stock_qty>0 )
return $term_name .= ' - ' . $stock_status . ' ('.$stock_qty.')';
else
return $term_name .= ' - ' . $stock_status;
}
function looks like return
return $term_name .= ' - ' . $stock_status;
all the time. Any help ? Preview from my issue can be seen here. Thanks.
EDIT: This is the code from variable.php Radio Button Plugin where print variations as radio buttons:
<td class="value">
<?php
if ( ! empty( $options ) ) {
if ( taxonomy_exists( $name ) ) {
// Get terms if this is a taxonomy - ordered. We need the names too.
$terms = wc_get_product_terms( $product->get_id(), $name, array( 'fields' => 'all' ) );
foreach ( $terms as $term ) {
if ( ! in_array( $term->slug, $options ) ) {
continue;
}
print_attribute_radio( $checked_value, $term->slug, $term->name, $sanitized_name );
}
} else {
foreach ( $options as $option ) {
print_attribute_radio( $checked_value, $option, $option, $sanitized_name );
}
}
}
echo end( $attribute_keys ) === $name ?
apply_filters( 'woocommerce_reset_variations_link', '<a
class="reset_variations" href="#">' . __( 'Clear', 'woocommerce' ) . '</a>'
) : '';
?>
</td>
Maybe need to update something there to show properly?
do this instead
if( $stock_qty>0 )
//return $term_name .= ' - ' . $stock_status . ' ('.$stock_qty.')';
return $term_name;
else
//return $term_name .= ' - ' . $stock_status;
return $term_name .= ' - Out Of Stock';

Send some product data at publish time in Woocommerce

I am trying to develop a plugin for Woocommerce which it sends new published product's information to a Telegram channel. I need to get the price and image of product when it is published. but my code returns empty.
my code :
add_action('transition_post_status', 'btb_send_telegram_post', 10, 3);
function btb_send_telegram_post( $new_status, $old_status, $post ) {
if(
$old_status != 'publish'
&& $new_status == 'publish'
&& !empty($post->ID)
&& in_array( $post->post_type,array( 'product'))
) {
// product is new published.
$product = wc_get_product ( $post->ID );
$message = $product->get_short_description()."\r\n";
$message .= "price : ". $product->get_price()."\r\n";
$message .= " regular price : ". $product->get_regular_price() ."\r\n";
$message .= "sale price : ". $product->get_sale_price()."\r\n";
btb_send_message($message);
}
I think it is because the changing status of product to publish occurs before it completely saved in database. because when I save a draft before publish it returns correct prices. for that matter I need to do one of these two approaches:
Save product as a draft by my code before publish .
Use another action which it triggers after product meta is saved completely.
And now I don't have any idea how to do both of above approaches.
any advice will be appreciated.
Thank you.
Update 2 (the product data is not anymore empty)
You could try this custom function hooked in save_post action hook:
// Only on WooCommerce Product edit pages (Admin)
add_action( 'save_post', 'send_telegram_post', 50, 3 );
function send_telegram_post( $post_id, $post, $update ) {
if ( $post->post_type != 'product') return; // Only products
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id; // Exit if it's an autosave
if ( $post->post_status != 'publish' )
return $post_id; // Exit if not 'publish' post status
if ( ! current_user_can( 'edit_product', $post_id ) )
return $post_id; // Exit if user is not allowed
// Check if product message has already been sent (avoiding repetition)
$message_sent = get_post_meta( $post_id, '_message_sent', true );
if( ! empty($message_sent) )
return $post_id; // Exit if message has already been sent
## ------------ MESSAGE ------------ ##
// Get active price or "price" (we check if sale price exits)
$price = empty( $_POST['_sale_price'] ) ? $_POST['_regular_price'] : $_POST['_sale_price'];
$message = '';
$rn = "\r\n";
// Title
if( ! empty( $_POST['post_title'] ) )
$message .= 'Title : ' . $_POST['post_title'] . $rn;
// Short description
if( ! empty( $_POST['excerpt'] ) )
$message .= 'Description : ' . $_POST['excerpt'] . $rn;
// Active price
if( ! empty( $price ) )
$message .= 'Price : ' . $price . "\r\n";
// Regular price
if( ! empty( $_POST['_regular_price'] ) )
$message .= 'Regular price : ' . $_POST['_regular_price'] . $rn;
// Sale price
if( ! empty( $_POST['_sale_price'] ) )
$message .= 'Sale price : ' . $_POST['_sale_price'] . $rn;
// Send message custom function
btb_send_message( $message );
// Just for testing (uncomment below to enable):
// update_post_meta( $post_id, '_message_content', $message ); // Message in database
// add custom meta field to mark this product as "message sent"
update_post_meta( $post_id, '_message_sent', '1' );
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.

Categories