I have a problem with Woo-commerce and i think i m pretty close to find solution,
but have a bug :
My task is to make changes to woocommerce product default prices based on : username , specific product id and product category .
code is here :
`if ( is_user_logged_in() ) {
add_filter('woocommerce_get_price','change_price', 10, 2);
add_filter('woocommerce_get_regular_price','change_price', 10, 2);
add_filter('woocommerce_get_sale_price','change_price', 10, 2);
}
function change_price($price, $productd){
$vrednost=$productd->get_sku( );
$current_user = wp_get_current_user(); //uzimam trenutno logovanog korisnika
global $wpdb;
global $mydb;
global $cena;
$cena=$productd->price;
$mydb= new wpdb('root','','wordpress123','localhost');
$mydb->show_errors();
$userna=$current_user->user_login;
$paypal_id = $mydb->get_results("select sifra_kupca from wp_prodajno_mjesto WHERE user ='$userna'");
foreach ($paypal_id as $objs) {
$sifrovani=$objs->sifra_kupca;
}
$standard_rabat=$mydb->get_results("select standardni_rabat from wp_kupac WHERE sifra_kupca ='$sifrovani'");
foreach ($standard_rabat as $objs) {
$ispis=$objs->standardni_rabat;
}
$konacnorabat=$ispis;
$price =intval($productd->price)-((intval($ispis)/100)*$productd->price);
$ima=$mydb->get_results("select sifra_kupca from wp_cjenik_kupca WHERE sifra_kupca ='$sifrovani'");
foreach ($ima as $objs) {
$ispis7=$objs->sifra_kupca;
}
if ($ispis7==NULL)
{
return $price;
exit;
}
$grupa=$mydb->get_results("select grupa_artikala from wp_cjenik_kupca WHERE sifra_kupca ='$sifrovani'");
foreach ($grupa as $objs) {
$ispis4=$objs->grupa_artikala;
}
if (!($ispis4==NULL))
{
global $post;
$args = array( 'taxonomy' => 'product_cat',);
$terms = wp_get_post_terms($post->ID,'product_cat', $args);
$count = count($terms);
if ($count > 0) {
foreach ($terms as $term) {
$cata=$term->name;
}
}
$sifbaza=$productd->get_sku( );
$nc=$mydb->get_results("select cjenik_cijena from wp_cjenik_kupca WHERE (sifra_kupca ='$sifrovani' AND sifra_artikla='$sifbaza')");
foreach ($nc as $objs2) {
$novacen=$objs2->cjenik_cijena;
}
if (!($novacen==NULL))
{
$konacnoprice=$novacen;
$rabat2=$mydb->get_results("select cjenik_rabat from wp_cjenik_kupca WHERE (sifra_kupca ='$sifrovani' AND sifra_artikla='$sifbaza') ");
foreach ($rabat2 as $objs5) {
$konacnorabat=$objs5->cjenik_rabat;
}
}
else {
$konacnoprice=$productd->price;
$rabat3=$mydb->get_results("select cjenik_rabat from wp_cjenik_kupca WHERE (sifra_kupca ='$sifrovani' AND grupa_artikala='$cata') ");
foreach ($rabat3 as $objs5) {
$konacnirabat=$objs5->cjenik_rabat;
}
}
if (!($konacnirabat==NULL))
{$price='5000';return $price;
exit;}
else {$price=(intval($konacnoprice)-((intval($konacnorabat)/100)*intval($konacnoprice)));}
return $price;
exit;
}
}
`
Now i have problem in one case :
`if (!($konacnirabat==NULL))
{$price='5000';return $price;
exit;}`
So all the prices are correctly changed on shop page, but when i Add to Cart specific product where field $konacnirabat is not null , it gives me wrong price result in cart.
Here are also screenshots with database tables needed for this :
LINK
I faced the same problem in last few days and I have found solution - you should use different filters - one when product is adding to cart and one when price is getting from cart session. Here is where I found answer: source
Related
I got this code in my function.php which shows available sizes on all the products in the category view of woocommerce.
The problem is that it takes a lot of resources and makes the site slow.
My question is, if I should save the data for each product in a transient cache to speed up the site? But it would require a lot of transients, as each product should have a transitent – Is it a good way to do it like I think or is it bad pratice to have so many transients?
My thought was to make each product have a transient key like:
$key = 'my_transient_key' . $product->get_id();
The function code as it is now:
add_action( 'woocommerce_after_shop_loop_item_title', 'display_instock_sizes', 5 );
function display_instock_sizes() {
global $product;
if ( $product->is_type('variable') ) {
$taxonomy = 'stoerrelse'; // The product attribute taxonomy
$sizes_array = []; // Initializing
// Loop through available variation Ids for the variable product
foreach( $product->get_children() as $child_id ) {
$variation = wc_get_product( $child_id ); // Get the WC_Product_Variation object
if( $variation->is_purchasable() && $variation->is_in_stock() ) {
$term_name = $variation->get_attribute( $taxonomy );
$sizes_array[$term_name] = [$term_name => 'instock'];
}else{
$term_name = $variation->get_attribute( $taxonomy );
$sizes_array[$term_name] = [$term_name => 'outofstock'];
}
}
foreach ($sizes_array as $key => $value) {
if (empty($value)) {
unset($sizes_array[$key]);
}
}
if(empty($sizes_array)){
return;
}
ksort($sizes_array);
echo '<div class="attribute-size-wrapper">';
foreach ($sizes_array as $key => $value) {
foreach ($value as $key => $value) {
echo '<span class="attribute-size"><span class="'.$value.'">' . $key . '</span></span>';
}
}
echo '</div>';
}
}
I am trying to modify the custom wordpress search by using pre_get_posts hook, so that a specific words won't be searched in product description.
add_action( 'pre_get_posts', 'exclude_search_content' );
function exclude_search_content( $Q ) {
$search_phrase = $Q->query['s'];
if( $Q->is_search() ) {
/** Dont search for $search_phrase in excerpt and product description
* search only product title, a meta key and a taxonomy.
*/
}
}
It seems to be more complex than I expected. Any ideas?
if you check posts_search reference you will find some of Contribute already wrote similar function, so i just test it and it's working fine.
function search_by_title_only($search, $wp_query)
{
global $wpdb;
if (empty($search)) {
return $search; // skip processing - no search term in query
}
$q = $wp_query->query_vars;
$n = !empty($q['exact']) ? '' : '%';
$search =
$searchand = '';
foreach ((array) $q['search_terms'] as $term) {
$term = esc_sql($wpdb->esc_like($term));
$search .= "{$searchand}($wpdb->posts.post_title LIKE '{$n}{$term}{$n}')";
$searchand = ' AND ';
}
if (!empty($search)) {
$search = " AND ({$search}) ";
if (!is_user_logged_in()) {
$search .= " AND ($wpdb->posts.post_password = '') ";
}
}
return $search;
}
add_filter('posts_search', 'search_by_title_only', 20, 2);
i was wondering if someone had some experience with the following scenario.
I'm using WooCommerce to have my products listed, ready for sale. Some products (about 20) have a massive amount of variations, so i decided to have the product data in separated tables, and via SKU (simple query to get the data) to load them into woocommerce. So far, everything works great. These products are working fine. Their variations are showing up, and the user can select them, to add them to cart.
Thing is, i have setup these 20 products as single products, and gave them a price of $1, just to show the add to cart button (.single_add_to_cart_button), but when im selecting my variations (from the outside table/tables) the product gets added fine into the cart, but it shows for every product in that case, a price of $1, with all the custom fields included (which is nice). As far as i know, these custom fields are from the sessions). Below is all my code that im using in my functions.php (not mine, found on the net, fixed it to work with my case)
// Step 1: Add Data in a Custom Session, on ‘Add to Cart’ Button Click
add_action('wp_ajax_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');
add_action('wp_ajax_nopriv_wdm_add_user_custom_data_options', 'wdm_add_user_custom_data_options_callback');
function wdm_add_user_custom_data_options_callback()
{
$product_id = $_POST['id'];
$product_category = $_POST['product_category'];
$custom_data_1 = $_POST['custom_data_1'];
$custom_data_2 = $_POST['custom_data_2'];
$custom_data_3 = $_POST['custom_data_3'];
$custom_data_4 = $_POST['custom_data_4'];
$custom_data_5 = $_POST['custom_data_5'];
session_start();
$_SESSION['custom_data_1'] = $custom_data_1;
$_SESSION['custom_data_2'] = $custom_data_2;
$_SESSION['custom_data_3'] = $custom_data_3;
$_SESSION['custom_data_4'] = $custom_data_4;
$_SESSION['custom_data_5'] = $custom_data_5;
die();
}
// Step 2: Add Custom Data in WooCommerce Session
add_filter('woocommerce_add_cart_item_data','wdm_add_item_data',1,2);
if(!function_exists('wdm_add_item_data'))
{
function wdm_add_item_data($cart_item_data,$product_id)
{
global $woocommerce;
session_start();
$new_value = array();
if (isset($_SESSION['custom_data_1'])) {
$option1 = $_SESSION['custom_data_1'];
$new_value['custom_data_1'] = $option1;
}
if (isset($_SESSION['custom_data_2'])) {
$option2 = $_SESSION['custom_data_2'];
$new_value['custom_data_2'] = $option2;
}
if (isset($_SESSION['custom_data_3'])) {
$option3 = $_SESSION['custom_data_3'];
$new_value['custom_data_3'] = $option3;
}
if (isset($_SESSION['custom_data_4'])) {
$option4 = $_SESSION['custom_data_4'];
$new_value['custom_data_4'] = $option4;
}
if (isset($_SESSION['custom_data_5'])) {
$option5 = $_SESSION['custom_data_5'];
$new_value['custom_data_5'] = $option5;
}
if( empty($option1) && empty($option2) && empty($option3) && empty($option4) && empty($option5) )
return $cart_item_data;
else
{
if(empty($cart_item_data))
return $new_value;
else
return array_merge($cart_item_data,$new_value);
}
unset($_SESSION['custom_data_1']);
unset($_SESSION['custom_data_2']);
unset($_SESSION['custom_data_3']);
unset($_SESSION['custom_data_4']);
unset($_SESSION['custom_data_5']);
}
}
// Step 3: Extract Custom Data from WooCommerce Session and Insert it into Cart Object
add_filter('woocommerce_get_cart_item_from_session', 'wdm_get_cart_items_from_session', 1, 3 );
if(!function_exists('wdm_get_cart_items_from_session'))
{
function wdm_get_cart_items_from_session($item,$values,$key)
{
if (array_key_exists( 'custom_data_1', $values ) )
{
$item['custom_data_1'] = $values['custom_data_1'];
}
if (array_key_exists( 'custom_data_2', $values ) )
{
$item['custom_data_2'] = $values['custom_data_2'];
}
if (array_key_exists( 'custom_data_3', $values ) )
{
$item['custom_data_3'] = $values['custom_data_3'];
}
if (array_key_exists( 'custom_data_4', $values ) )
{
$item['custom_data_4'] = $values['custom_data_4'];
}
if (array_key_exists( 'custom_data_5', $values ) )
{
$item['custom_data_5'] = $values['custom_data_5'];
}
return $item;
}
}
// Step 4: Display User Custom Data on Cart and Checkout page
add_filter('woocommerce_checkout_cart_item_quantity','wdm_add_user_custom_option_from_session_into_cart',1,3);
add_filter('woocommerce_cart_item_price','wdm_add_user_custom_option_from_session_into_cart',1,3);
if(!function_exists('wdm_add_user_custom_option_from_session_into_cart'))
{
function wdm_add_user_custom_option_from_session_into_cart($product_name, $values, $cart_item_key )
{
if(count($values['custom_data_1']) > 0)
{
$return_string = $product_name . "";
$return_string .= "";
$return_string .= "SKU : " . $values['custom_data_1'] . "";
//$return_string .= "Code : " . $values['custom_data_2'] . "";
$return_string .= "Width : " . $values['custom_data_3'] . " cm";
$return_string .= "Height : " . $values['custom_data_4'] . " cm";
$return_string .= "Price : € " . $values['custom_data_5'] . "";
$return_string .= "";
return $return_string;
}
else
{
return $product_name;
}
}
}
// Step 5: Add Custom Data as Metadata to the Order Items
add_action('woocommerce_add_order_item_meta','wdm_add_values_to_order_item_meta',1,2);
if(!function_exists('wdm_add_values_to_order_item_meta'))
{
function wdm_add_values_to_order_item_meta($item_id, $values)
{
global $woocommerce,$wpdb;
$user_custom_values = $values['wdm_user_custom_data_value'];
if(!empty($user_custom_values))
{
wc_add_order_item_meta($item_id,'wdm_user_custom_data',$user_custom_values);
}
$custom_data_1 = $values['custom_data_1'];
if(!empty($custom_data_1))
{
wc_add_order_item_meta($item_id,'custom_data_1',$custom_data_1);
}
$custom_data_2 = $values['custom_data_2'];
if(!empty($custom_data_2))
{
wc_add_order_item_meta($item_id,'custom_data_2',$custom_data_2);
}
$custom_data_3 = $values['custom_data_3'];
if(!empty($custom_data_3))
{
wc_add_order_item_meta($item_id,'custom_data_3',$custom_data_3);
}
$custom_data_4 = $values['custom_data_4'];
if(!empty($custom_data_4))
{
wc_add_order_item_meta($item_id,'custom_data_4',$custom_data_4);
}
$custom_data_5 = $values['custom_data_5'];
if(!empty($custom_data_5))
{
wc_add_order_item_meta($item_id,'custom_data_5',$custom_data_5);
}
}
}
// Step 6: Remove User Custom Data, if Product is Removed from Cart
add_action('woocommerce_before_cart_item_quantity_zero','wdm_remove_user_custom_data_options_from_cart',1,1);
if(!function_exists('wdm_remove_user_custom_data_options_from_cart'))
{
function wdm_remove_user_custom_data_options_from_cart($cart_item_key)
{
global $woocommerce;
// Get cart
$cart = $woocommerce->cart->get_cart();
// For each item in cart, if item is upsell of deleted product, delete it
foreach( $cart as $key => $values)
{
if ( $values['wdm_user_custom_data_value'] == $cart_item_key )
unset( $woocommerce->cart->cart_contents[ $key ] );
}
}
}
i tried to include the following code
add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {
$custom_price = 999; // This is the custom price
foreach ( $cart_object->cart_contents as $key => $value ) {
$value['data']->price = $custom_price;
}
}
it changes the price to 999, since its fixed, but in my case, i am not able to include the value
$custom_data_5 = $_POST['custom_data_5']; // thats my unit price which needs to replace the $1 value of the simple product value from the product
any help would be appreciated on my side, since I'm running out of options right now, and this solution seems to be to correct one for me.
Jan
all right, i think i got it done, searching and searching on stackoverflow.com of course ....
this i what i did :
function ipe_add_to_cart_link() {
global $product;
$custom_price = 30;
echo sprintf( '%s',
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
$myCustomPrice, // Thats the value im getting from my add_to_cart_button - hidden
esc_attr( $product->id ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button' ),
esc_html( $product->add_to_cart_text() )
);
}
add_filter('woocommerce_loop_add_to_cart_link','ipe_add_to_cart_link');
function ipe_product_custom_price( $cart_item_data, $product_id ) {
if( isset( $_POST['myCustomPrice'] ) && !empty($_POST['myCustomPrice'])) {
$cart_item_data[ "myCustomPrice" ] = $_POST['myCustomPrice'];
}
return $cart_item_data;
}
add_filter( 'woocommerce_add_cart_item_data', 'ipe_product_custom_price', 99, 2 );
function ipe_apply_custom_price_to_cart_item( $cart_object ) {
if( !WC()->session->__isset( "reload_checkout" )) {
foreach ( $cart_object->cart_contents as $key => $value ) {
if( isset( $value["myCustomPrice"] ) ) {
$value['data']->price = $value["myCustomPrice"];
}
}
}
}
add_action( 'woocommerce_before_calculate_totals', 'ipe_apply_custom_price_to_cart_item', 99 );
and placed everything in functions.php - worked like a charm. Hope that this solution is helping someone out there.
Jan
I am developing site in WordPress using woo-commerce
I want to achieve the functionality that on single page price will be displayed by counting 50% discount on single product page
I had implemented the below code, it is working nicely on the simple products but not working on variable product
Please help me how can I achieve the custom price filtering on variable product
OR suggest me which filter to used to variable products
add_filter('woocommerce_get_price', 'custom_price_WPA111772', 10, 2);
function custom_price_WPA111772($price, $product) {
global $product;
$pid = get_the_ID();
$user = wp_get_current_user();
if(!is_user_logged_in()) return $price;
if( has_term( 'sale', 'product_cat' ,$product->ID) || has_term( 'Gift Ideas', 'product_cat' ,$product->ID))
{
$price = $price;
}
else
{
$price = $price * 50 / 100;
}
return $price;
}
I got the answer why my variable product is not showing custom price
i added this in function.php and its works
add_filter('woocommerce_variable_price_html', 'custom_variation_price', 10, 2);
function custom_variation_price( $price, $product ) {
foreach($product->get_available_variations() as $pav){
$def=true;
foreach($product->get_variation_default_attributes() as $defkey=>$defval){
if($pav['attributes']['attribute_'.$defkey]!=$defval){
$def=false;
}
}
if($def){
$price = $pav['display_price'];
}
}
return woocommerce_price($price);
}
Let me tell you the scenario first say the structure of the categories in wordpress is like this
Level 1: Top
Level 2: -Nextme_1
Level 3: --Nextme_2
--Nextme_3
Level 4: ---Nextme_4
---Nextme_5
Now I require to check what is the level of the category? Say I catch a category of level 3 so I have to use different template and if its level 4. Then I need to use another template?
Anybody can give me some hint?
Thanks
Rahul
If you don't have many categories you can try to edit their slug from admin, and then in your page you get the category slug this way:
if (is_category()) {
$cat = get_query_var('cat');
$category = get_category($cat);
echo 'your slug is '. $category->slug;
}
Now, when you're editing the categories slugs try naming them after their level: cat-lvl-1, cat-lvl-2. Then in your page you extract the number from category slug using some php string function, and then you check that number:
if ($category->slug == 1 ) {
//load the template for the category of level 1
}
if ($category->slug == 2 ) {
//load the template for the category of level 2
}
and so on.
Later edit:
Try this:
function get_level($category, $level = 0)
{
if ($category->category_parent == 0) {
return $level;
} else {
$level++;
$category = get_category($category->category_parent);
get_level($category, $level);
}
}
if (is_category()) {
$cat = get_query_var('cat');
$yourcat = get_category($cat);
echo get_level($yourcat);
}
You can call the get_ancestors() function to get an array containing the parents of the given object. Then you need to count elements in the result.
function get_the_level($id, $type = 'category') {
return count( get_ancestors($id, $type) );
}
if( is_category() ) {
$level = get_the_level( $cat );
}
elseif( is_product_category() ) {
$level = get_the_level( $wp_query->get_queried_object()->term_id, 'product_cat' );
}
Thanks a lot. This is superb with slight a change the code that you have written is fine but its not returning any value.(i,e the $level) although its calculating correct. A minor change i did and its work fine now with a slight editing of you code given below..
`
function get_level($category, $level = 0)
{
if ($category->category_parent == 0) {
return $level;
} else {
$level++;
$category = get_category($category->category_parent);
return get_level($category, $level);
}
}
if (is_category()) {
$cat = get_query_var('cat');
$yourcat = get_category($cat);
echo get_level($yourcat);
}
`
Thanks #zuzuleinen
I visited this page months back. I came back today, arrow up on the above solution then still went digging. Although it is a good solution, Wordpress often offers better or close.
get_category_parents()
This function does as Rahul has typed basically. It also calls itself which seems the most logical approach and that is why Rahul gets a point from me on this. Do not use $link, return a string of categories, explode() them then count or I suppose we could count the number of times the separator has been used and add 1.
function get_category_parents( $id, $link = false, $separator = '/', $nicename = false, $visited = array() ) {
$chain = '';
$parent = get_term( $id, 'category' );
if ( is_wp_error( $parent ) )
return $parent;
if ( $nicename )
$name = $parent->slug;
else
$name = $parent->name;
if ( $parent->parent && ( $parent->parent != $parent->term_id ) && !in_array( $parent->parent, $visited ) ) {
$visited[] = $parent->parent;
$chain .= get_category_parents( $parent->parent, $link, $separator, $nicename, $visited );
}
if ( $link )
$chain .= ''.$name.'' . $separator;
else
$chain .= $name.$separator;
return $chain;
}