Reputation: 1052
I'm trying to display woocommerce download table on the dashboard endpoint. After studying the woocommerce download endpoint file i notice woocommerce uses the below code to display the download table;
$downloads = WC()->customer->get_downloadable_products();
$has_downloads = (bool) $downloads;
do_action( 'woocommerce_before_account_downloads', $has_downloads ); ?>
<?php if ( $has_downloads ) : ?>
<?php do_action( 'woocommerce_before_available_downloads' ); ?>
<?php do_action( 'woocommerce_available_downloads', $downloads ); ?>
<?php do_action( 'woocommerce_after_available_downloads' ); ?>
<?php else : ?>
<div class="woocommerce-Message woocommerce-Message--info woocommerce-info">
<a class="woocommerce-Button button" href="<?php echo esc_url( apply_filters( 'woocommerce_return_to_shop_redirect', wc_get_page_permalink( 'shop' ) ) ); ?>">
<?php esc_html_e( 'Go shop', 'woocommerce' ); ?>
</a>
<?php esc_html_e( 'No downloads available yet.', 'woocommerce' ); ?>
</div>
<?php endif; ?>
<?php do_action( 'woocommerce_after_account_downloads', $has_downloads ); ?>
what I want to achieve is to display the 5 latest downloads in table format. will like to know how to limit this action <?php do_action( 'woocommerce_available_downloads', $downloads ); ?>
to only display the latest 5 downloads.
UPDATE
This is the download table in the Woocommerce Download Endpoint Page
in which I want to display the same exact table structure on the dashboard endpoint page
Upvotes: 3
Views: 3532
Reputation: 1052
Following the code by @LoicTheAztec Second option (Option 2), I then added the WooCommerce Download Template into a shortcode while adding the function in @LoicTheAztec Option 2 to filter the output. Code Below;
function make_customer_download_output_five_products() {
$downloads = WC()->customer->get_downloadable_products();
$downloads = get_customer_latest_downloads($downloads); //Here is the function from Option 2
$has_downloads = (bool) $downloads;
ob_start();
if ( $has_downloads ) {
do_action( 'woocommerce_available_downloads', $downloads );
} else {
?>
<div class="woocommerce-Message woocommerce-Message--info woocommerce-info">
<a class="woocommerce-Button button" href="<?php echo esc_url( apply_filters( 'woocommerce_return_to_shop_redirect', wc_get_page_permalink( 'shop' ) ) ); ?>">
<?php esc_html_e( 'Go shop', 'woocommerce' ); ?>
</a>
<?php esc_html_e( 'No downloads available yet.', 'woocommerce' ); ?>
</div>
<?php
}
return ob_get_clean();
}
add_shortcode('your_downloads', 'make_customer_download_output_five_products');
You can then add the shortcode to any page of choice using do_shortcode(['your_downloads'])
.
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Upvotes: 1
Reputation: 253784
You can use 2 ways:
Option 1 - Using a filter hook (filtering on a specific endpoint):
The filter
woocommerce_customer_get_downloadable_products
is located inside the code fromWC_CUstomer
get_downloadable_products()
method.
The following will give you the 5 latest downloads in a specific endpoint (Here on My Account > downloads
endpoint):
add_filter( 'woocommerce_customer_get_downloadable_products', 'filter_customer_downloadable_products', 10, 1 );
function filter_customer_downloadable_products( $downloads ) {
$limit = 5; // Number of downloads to keep
// Only on My account Downloads section for more than 5 downloads
if( is_wc_endpoint_url( 'downloads' ) && sizeof($downloads) > $limit ) {
$keys_by_order_id = $sorted_downloads = array();
$count = 0;
// Loop through the downloads array
foreach( $downloads as $key => $download ) {
// Store the array key with the order ID
$keys_by_order_id[$key] = $download['order_id'];
}
// Sorting the array by Order Ids in DESC order
arsort($keys_by_order_id);
// Loop through the sorted array
foreach( $keys_by_order_id as $key => $order_id ) {
// Set the corresponding download in a new array (sorted)
$sorted_downloads[] = $downloads[$key];
$count++; // Increase the count
// When the count reaches the limit
if( $count === $limit ) {
break; // We stop the loop
}
}
return $sorted_downloads;
}
return $downloads;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
Option 2 - Using a custom function that filters:
Just use this function, to get from customer $downloads
variable the latest 5 downloads.
It can be used anywhere.
function get_customer_latest_downloads( $downloads, $limit = 5 ) {
// Only on my account pages for more than 5 downloads
if( sizeof($downloads) > $limit ) {
$keys_by_order_id = $sorted_downloads = array();
$count = 0;
// Loop through the downloads array
foreach( $downloads as $key => $download ) {
// Store the array key with the order ID
$keys_by_order_id[$key] = $download['order_id'];
}
// Sorting the array by Order Ids in DESC order
arsort($keys_by_order_id);
// Loop through the sorted array
foreach( $keys_by_order_id as $key => $order_id ) {
// Set the corresponding download in a new array (sorted)
$sorted_downloads[] = $downloads[$key];
$count++; // Increase the count
// When the count reaches the limit
if( $count === $limit ) {
break; // We stop the loop
}
}
return $sorted_downloads;
}
return $downloads;
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
USAGE Example (in a template or a shortcode):
$downloads = WC()->customer->get_downloadable_products();
$downloads = get_customer_latest_downloads( $downloads ); // The 5 latest downloads
// Testing the array raw output
echo '<pre>'; print_r($downloads); echo '</pre>';
Note: Action hooks doesn't filter data.
Upvotes: 2
Reputation: 638
Here is a simple example to illustrate how you would manipulate the downloads list before it is displayed by WooCommerce.
The most effective way would be using a filter. This function simply returns the first five downloads in the array. To ensure that the five downloads it returns are the most recent you will need to do a bit more work.
// Define the callback
function filter_woocommerce_customer_available_downloads($downloads, $customer_id) {
// Manipulate download data here, this example we'll get the first 5 downloads in the array
$downloads = array_slice($downloads, 0, 5);
// Return first five downloads
return $downloads;
};
// Add the filter, this tells wordpress to apply this filter every time available downloads is called
add_filter( 'woocommerce_customer_available_downloads', 'filter_woocommerce_customer_available_downloads', 10, 2 );
Place this at the bottom of your "functions.php" file in your theme. Please keep in mind that this is a quick and dirty example and is untested.
Upvotes: 1