• Resolved Erfan MHDi

    (@erfanmhd)


    hello,
    i’m using this condition inside single download page to detect user has purchased current product or not:

    $Purchased = edd_has_user_purchased(get_current_user_id(), get_the_ID()); 
    if ($Purchased) {
        echo 'Purchased';
    } else {
        echo 'NOT Purchased';
    }

    if returns “Purchased” when current product page is Bundle or Single (not included in any bundle), but when i’m inside a single product page that it’s included inside a bundle and user has purchased that bundle it returns “NotPurchased” meaning that user need to purchase a bundle child item again separately.

    is there any chance you guys can help detect if current user has purchased current item from it’s parent bundle and show user the download link of current item inside single download page ?

    Thanks

Viewing 6 replies - 1 through 6 (of 6 total)
  • Hi @erfanmhd

    I have slightly modify the EDD function and created a new version. You can copy this function your theme / child theme functions.php file. I hope it will work for you.

    function __edd_has_user_purchased( $user_id, $downloads, $variable_price_id = null ) {
    
    	if( empty( $user_id ) ) {
    		return false;
    	}
    
    	/**
    	 * @since 2.7.7
    	 *
    	 * Allow 3rd parties to take actions before the history is queried.
    	 */
    	do_action( 'edd_has_user_purchased_before', $user_id, $downloads, $variable_price_id );
    
    	$users_purchases = edd_get_users_purchases( $user_id );
    
    	$return = false;
    
    	if ( ! is_array( $downloads ) ) {
    		$downloads = array( $downloads );
    	}
    
    	if ( $users_purchases ) {
    		foreach ( $users_purchases as $purchase ) {
    			$payment         = new EDD_Payment( $purchase->ID );
    			$purchased_files = $payment->cart_details;
    
    			if ( is_array( $purchased_files ) ) {
    				foreach ( $purchased_files as $download ) {
    					
    					$bundled_products	= edd_get_bundled_products( $download['id'], $variable_price_id );
    					$array_intersect	= array_intersect( $bundled_products, $downloads );
    
    					if( $array_intersect ) {
    						$return = true;
    						break 2;
    					}
    
    					if ( in_array( $download['id'], $downloads ) ) {
    						$variable_prices = edd_has_variable_prices( $download['id'] );
    						if ( $variable_prices && ! is_null( $variable_price_id ) && $variable_price_id !== false ) {
    							if ( isset( $download['item_number']['options']['price_id'] ) && $variable_price_id == $download['item_number']['options']['price_id'] ) {
    								$return = true;
    								break 2; // Get out to prevent this value being overwritten if the customer has purchased item twice
    							} else {
    								$return = false;
    							}
    						} else {
    							$return = true;
    							break 2;  // Get out to prevent this value being overwritten if the customer has purchased item twice
    						}
    					}
    				}
    			}
    		}
    	}
    
    	/**
    	 * @since 2.7.7
    	 *
    	 * Filter has purchased result
    	 */
    	$return = apply_filters( 'edd_has_user_purchased', $return, $user_id, $downloads, $variable_price_id );
    
    	return $return;
    }
    Thread Starter Erfan MHDi

    (@erfanmhd)

    Thanks Bro,

    your new function is recognizing a single item being purchased from a parent bundle now, but as i show the download links inside the product page your new function makes my download links broke. i’m not sure if it’s a problem with your new function or my way of generating download links inside product page.
    but can i ask you for a favor to take a look at this too ?
    here is the code i’m using to show the download links inside product page:

    <?php
    if ( __edd_has_user_purchased( $CurrentUser, $CurrentItem, $variable_price_id = null ) ) {
    	$user_purchases = edd_get_users_purchases( $CurrentUser, -1, false, 'complete' );
    	foreach ( $user_purchases as $purchase ) {
    		$cart_items    = edd_get_payment_meta_cart_details( $purchase->ID );
    		$item_ids = wp_list_pluck( $cart_items, 'id' );
    		if ( in_array( $CurrentItem, $item_ids ) ) {
    			$email       = edd_get_payment_user_email( $purchase->ID );
    			$payment_key = edd_get_payment_key( $purchase->ID );
    		}
    	}
    
    	// Attempt to get the file data associated with this download
    	$download_data = edd_get_download_files( $CurrentItem, null );
    	if ( $download_data ) {
    		$new_purchase_form = '';
    		foreach ( $download_data as $filekey => $file ) {
    			$FileURL = edd_get_download_file_url( $payment_key, $email, $filekey, $download['id'], null );
    			
    			echo $FileURL . '<br>';
    			
    		}
    		
    	} else {
    		echo "No Download file added yet!";
    	}
    }
    ?>
    

    when i use your function __edd_has_user_purchased instead of edd_has_user_purchased, in a purchased single product with no parent bundle download links are shown perfectly but in a purchased product from it’s parent bundle page the product download links are not being generated and i see this Error and notices instead:

    Notice
    : Undefined variable: payment_key in
    /home/user/public_html/wp-content/themes/.../Single/Product.php
    on line
    280
    
    Notice
    : Undefined variable: email in
    /home/user/public_html/wp-content/themes/.../Single/Product.php
    on line
    280
    
    Warning
    : Illegal string offset 'id' in
    /home/user/public_html/wp-content/themes/.../Single/Product.php
    on line
    280
    
    Notice
    : Undefined variable: payment_key in
    /home/user/public_html/wp-content/themes/.../Single/Product.php
    on line
    280
    
    Notice
    : Undefined variable: email in
    /home/user/public_html/wp-content/themes/.../Single/Product.php
    on line
    280
    
    Warning
    : Illegal string offset 'id' in
    /home/user/public_html/wp-content/themes/.../Single/Product.php
    on line

    by the way can i ask you if EDD is not detecting a purchase from parent bundle
    by default? i mean is this a bug from EDD or they want user to purchase single item separately although he/she may purchased a bundle containing it ?!

    Thanks man.

    • This reply was modified 4 years, 5 months ago by Erfan MHDi.
    • This reply was modified 4 years, 5 months ago by Erfan MHDi.

    Hi @erfanmhd

    Your above function needs to be modified. In your custom function, you are not checking bundled products. You are taking bundle id so it will nor work.

    Here is the updated code. Just for your reference you are doing extensive functionality on page load. You are talking all data and then finding among it. It will work for lower data but you should take care of speed and optimization also. I hope you can understand this.

    if ( __edd_has_user_purchased( $CurrentUser, $CurrentItem, $variable_price_id = null ) ) {
    	$user_purchases = edd_get_users_purchases( $CurrentUser, -1, false, 'complete' );
    	foreach ( $user_purchases as $purchase ) {
    		
    		$cart_items		= edd_get_payment_meta_cart_details( $purchase->ID );
    		$item_ids		= array();
    
    		foreach ($cart_items as $cart_item_key => $cart_item_data) {
    			if( edd_is_bundled_product( $cart_item_data['id'] ) ) {
    				$bundled_products	= edd_get_bundled_products( $cart_item_data['id'], $variable_price_id );
    				$item_ids			= array_merge( $item_ids, $bundled_products );
    			} else {
    				$item_ids[] = $cart_item_data['id'];
    			}
    		}
    
    		if ( in_array( $CurrentItem, $item_ids ) ) {
    			$email       = edd_get_payment_user_email( $purchase->ID );
    			$payment_key = edd_get_payment_key( $purchase->ID );
    		}
    	}
    
    	// Attempt to get the file data associated with this download
    	$download_data = edd_get_download_files( $CurrentItem, null );
    	if ( $download_data ) {
    		$new_purchase_form = '';
    		foreach ( $download_data as $filekey => $file ) {
    			$FileURL = edd_get_download_file_url( $payment_key, $email, $filekey, $CurrentItem, null );
    			
    			echo $FileURL . '<br>';
    			
    		}
    		
    	} else {
    		echo "No Download file added yet!";
    	}
    }
    Thread Starter Erfan MHDi

    (@erfanmhd)

    Thanks for your code, it works perfectly.
    about your heads up of page speed i take the code from download history page on EDD and thanks to you modified it in a way i want it.
    these code will only load only if user is logged in and only if user has purchased the items.
    so do you still think i have to change my way of showing download links inside product page ?
    if so can just give me a hint on how can i detect user purchase and show download link without going trough all payment data and find among them ?

    • This reply was modified 4 years, 5 months ago by Erfan MHDi.

    Hi @erfanmhd

    Glad to know that your problem has been solved.

    I can understand that code is taken from download history page. Download history page code only runs when it is viewed.

    We are finding the particular product ID from each purchases made by user. So you can try some hooks while purchasing and store the product ID, Variation ID in user meta and delete them on refund and etc actions. So there will be no need for this loop and etc.

    OR you can implement some caching (Transient) in above code so it will not be executed on each time on each page load.

    I hope you will be more cleared.

    Thread Starter Erfan MHDi

    (@erfanmhd)

    That was crystal clear,
    Thank you so much ! ??

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘if user purchased Current item in Bundle’ is closed to new replies.