$download_id ) );
}
}
add_action( 'edd_after_download_content', 'edd_append_purchase_link' );
/**
* Get Purchase Link
*
* Builds a Purchase link for a specified download based on arguments passed.
* This function is used all over EDD to generate the Purchase or Add to Cart
* buttons. If no arguments are passed, the function uses the defaults that have
* been set by the plugin. The Purchase link is built for simple and variable
* pricing and filters are available throughout the function to override
* certain elements of the function.
*
* $download_id = null, $link_text = null, $style = null, $color = null, $class = null
*
* @since 1.0
* @param array $args Arguments for display
* @return string $purchase_form
*/
function edd_get_purchase_link( $args = array() ) {
global $post, $edd_displayed_form_ids;
$purchase_page = edd_get_option( 'purchase_page', false );
if ( ! $purchase_page || $purchase_page == 0 ) {
global $no_checkout_error_displayed;
if ( ! is_null( $no_checkout_error_displayed ) ) {
return false;
}
edd_set_error(
'set_checkout',
sprintf(
__( 'No checkout page has been configured. Visit Settings to set one.', 'easy-digital-downloads' ),
esc_url( edd_get_admin_url( array(
'page' => 'edd-settings',
'tab' => 'general',
'section' => 'pages',
) ) )
)
);
edd_print_errors();
$no_checkout_error_displayed = true;
return false;
}
$post_id = is_object( $post ) ? $post->ID : 0;
$button_behavior = edd_get_download_button_behavior( $post_id );
$defaults = apply_filters( 'edd_purchase_link_defaults', array(
'download_id' => $post_id,
'price' => (bool) true,
'price_id' => isset( $args['price_id'] ) ? $args['price_id'] : false,
'direct' => $button_behavior == 'direct' ? true : false,
'text' => $button_behavior == 'direct' ? edd_get_option( 'buy_now_text', __( 'Buy Now', 'easy-digital-downloads' ) ) : edd_get_option( 'add_to_cart_text', __( 'Purchase', 'easy-digital-downloads' ) ),
'checkout' => edd_get_option( 'checkout_button_text', _x( 'Checkout', 'text shown on the Add to Cart Button when the product is already in the cart', 'easy-digital-downloads' ) ),
'style' => edd_get_option( 'button_style', 'button' ),
'color' => edd_get_button_color_class(),
'class' => 'edd-submit',
) );
$args = wp_parse_args( $args, $defaults );
// Override the straight_to_gateway if the shop doesn't support it
if ( ! edd_shop_supports_buy_now() ) {
$args['direct'] = false;
}
$download = new EDD_Download( $args['download_id'] );
if( empty( $download->ID ) ) {
return false;
}
if( 'publish' !== $download->post_status && ! current_user_can( 'edit_product', $download->ID ) ) {
return false; // Product not published or user doesn't have permission to view drafts
}
$options = array();
$variable_pricing = $download->has_variable_prices();
$data_variable = $variable_pricing ? ' data-variable-price="yes"' : 'data-variable-price="no"';
$type = $download->is_single_price_mode() ? 'data-price-mode=multi' : 'data-price-mode=single';
$show_price = $args['price'] && $args['price'] !== 'no';
$data_price_value = 0;
$price = false;
if ( $variable_pricing && false !== $args['price_id'] ) {
$price_id = $args['price_id'];
$prices = $download->prices;
$options['price_id'] = $args['price_id'];
$found_price = isset( $prices[$price_id] ) ? $prices[$price_id]['amount'] : false;
$data_price_value = $found_price;
if ( $show_price ) {
$price = $found_price;
}
} elseif ( ! $variable_pricing ) {
$data_price_value = $download->price;
if ( $show_price ) {
$price = $download->price;
}
}
$data_price = 'data-price="' . $data_price_value . '"';
$button_text = ! empty( $args['text'] ) ? ' – ' . $args['text'] : '';
if ( false !== $price ) {
if ( 0 == $price ) {
$args['text'] = __( 'Free', 'easy-digital-downloads' ) . $button_text;
} else {
$args['text'] = edd_currency_filter( edd_format_amount( $price ) ) . $button_text;
}
}
$button_display = '';
$checkout_display = 'style="display:none;"';
if ( edd_item_in_cart( $download->ID, $options ) && ( ! $variable_pricing || ! $download->is_single_price_mode() ) ) {
$button_display = 'style="display:none;"';
$checkout_display = '';
}
// Collect any form IDs we've displayed already so we can avoid duplicate IDs
if ( isset( $edd_displayed_form_ids[ $download->ID ] ) ) {
$edd_displayed_form_ids[ $download->ID ]++;
} else {
$edd_displayed_form_ids[ $download->ID ] = 1;
}
$form_id = ! empty( $args['form_id'] ) ? $args['form_id'] : 'edd_purchase_' . $download->ID;
// If we've already generated a form ID for this download ID, append -#
if ( $edd_displayed_form_ids[ $download->ID ] > 1 ) {
$form_id .= '-' . $edd_displayed_form_ids[ $download->ID ];
}
$args = apply_filters( 'edd_purchase_link_args', $args );
ob_start();
?>
1 ) {
$form_id .= '-' . $edd_displayed_form_ids[ $download_id ];
}
$variable_pricing = edd_has_variable_prices( $download_id );
if ( ! $variable_pricing ) {
return;
}
$prices = apply_filters( 'edd_purchase_variable_prices', edd_get_variable_prices( $download_id ), $download_id );
// If the price_id passed is found in the variable prices, do not display all variable prices.
if ( false !== $args['price_id'] && isset( $prices[ $args['price_id'] ] ) ) {
return;
}
$type = edd_single_price_option_mode( $download_id ) ? 'checkbox' : 'radio';
$mode = edd_single_price_option_mode( $download_id ) ? 'multi' : 'single';
// Filter the class names for the edd_price_options div
$css_classes_array = apply_filters( 'edd_price_options_classes', array(
'edd_price_options',
'edd_' . esc_attr( $mode ) . '_mode'
), $download_id );
// Sanitize those class names and form them into a string
$css_classes_string = implode( ' ', array_map( 'sanitize_html_class', $css_classes_array ) );
if ( edd_item_in_cart( $download_id ) && ! edd_single_price_option_mode( $download_id ) ) {
return;
}
do_action( 'edd_before_price_options', $download_id ); ?>
$price ) :
echo '- ';
echo '';
do_action( 'edd_after_price_option', $key, $price, $download_id );
echo '
';
endforeach;
endif;
do_action( 'edd_after_price_options_list', $download_id, $prices, $type );
?>
x
post_type && is_singular( 'download' ) && is_main_query() && ! post_password_required() ) {
ob_start();
do_action( 'edd_before_download_content', $post->ID );
$content = ob_get_clean() . $content;
}
return $content;
}
add_filter( 'the_content', 'edd_before_download_content' );
/**
* After Download Content
*
* Adds an action to the end of download post content that can be hooked to by
* other functions.
*
* @since 1.0.8
* @global $post
*
* @param $content The the_content field of the download object
* @return string the content with any additional data attached
*/
function edd_after_download_content( $content ) {
global $post;
if ( $post && $post->post_type == 'download' && is_singular( 'download' ) && is_main_query() && !post_password_required() ) {
ob_start();
do_action( 'edd_after_download_content', $post->ID );
$content .= ob_get_clean();
}
return $content;
}
add_filter( 'the_content', 'edd_after_download_content' );
/**
* Get Button Colors
*
* Returns an array of button colors.
*
* @since 1.0
* @return array $colors Button colors
*/
function edd_get_button_colors() {
$colors = array(
'white' => array(
'label' => __( 'White', 'easy-digital-downloads' ),
'hex' => '#ffffff'
),
'gray' => array(
'label' => __( 'Gray', 'easy-digital-downloads' ),
'hex' => '#f0f0f0'
),
'blue' => array(
'label' => __( 'Blue', 'easy-digital-downloads' ),
'hex' => '#428bca'
),
'red' => array(
'label' => __( 'Red', 'easy-digital-downloads' ),
'hex' => '#d9534f'
),
'green' => array(
'label' => __( 'Green', 'easy-digital-downloads' ),
'hex' => '#5cb85c'
),
'yellow' => array(
'label' => __( 'Yellow', 'easy-digital-downloads' ),
'hex' => '#f0ad4e'
),
'orange' => array(
'label' => __( 'Orange', 'easy-digital-downloads' ),
'hex' => '#ed9c28'
),
'dark-gray' => array(
'label' => __( 'Dark Gray', 'easy-digital-downloads' ),
'hex' => '#363636'
),
'inherit' => array(
'label' => __( 'Inherit', 'easy-digital-downloads' ),
'hex' => ''
)
);
return apply_filters( 'edd_button_colors', $colors );
}
/**
* Get Button Styles
*
* Returns an array of button styles.
*
* @since 1.2.2
* @return array $styles Button styles
*/
function edd_get_button_styles() {
$styles = array(
'button' => __( 'Button', 'easy-digital-downloads' ),
'plain' => __( 'Plain Text', 'easy-digital-downloads' )
);
return apply_filters( 'edd_button_styles', $styles );
}
/**
* Default formatting for download excerpts
*
* This excerpt is primarily used in the [downloads] shortcode
*
* @since 1.0.8.4
* @param string $excerpt Content before filtering
* @return string $excerpt Content after filtering
* @return string
*/
function edd_downloads_default_excerpt( $excerpt ) {
return do_shortcode( wpautop( $excerpt ) );
}
add_filter( 'edd_downloads_excerpt', 'edd_downloads_default_excerpt' );
/**
* Default formatting for full download content
*
* This is primarily used in the [downloads] shortcode
*
* @since 1.0.8.4
* @param string $content Content before filtering
* @return string $content Content after filtering
*/
function edd_downloads_default_content( $content ) {
return do_shortcode( wpautop( $content ) );
}
add_filter( 'edd_downloads_content', 'edd_downloads_default_content' );
/**
* Gets the download links for each item purchased
*
* @since 1.1.5
* @param int $payment_id The ID of the payment to retrieve download links for
* @return string
*/
function edd_get_purchase_download_links( $payment_id = 0 ) {
$downloads = edd_get_payment_meta_cart_details( $payment_id, true );
$order = edd_get_order( $payment_id );
$links = '';
foreach ( $downloads as $download ) {
$links .= '- ';
$links .= '
' . esc_html( get_the_title( $download['id'] ) ) . '
';
$price_id = isset( $download['options'] ) && isset( $download['options']['price_id'] ) ? $download['options']['price_id'] : null;
$files = edd_get_download_files( $download['id'], $price_id );
if ( is_array( $files ) ) {
foreach ( $files as $filekey => $file ) {
$links .= '';
}
}
$links .= ' ';
}
$links .= '
';
return $links;
}
/**
* Returns the path to the EDD templates directory
*
* @since 1.2
* @return string
*/
function edd_get_templates_dir() {
return EDD_PLUGIN_DIR . 'templates';
}
/**
* Returns the URL to the EDD templates directory
*
* @since 1.3.2.1
* @return string
*/
function edd_get_templates_url() {
return EDD_PLUGIN_URL . 'templates';
}
/**
* Retrieves a template part
*
* @since v1.2
*
* Taken from bbPress
*
* @param string $slug
* @param string $name Optional. Default null
* @param bool $load
*
* @return string
*
* @uses edd_locate_template()
* @uses load_template()
* @uses get_template_part()
*/
function edd_get_template_part( $slug, $name = null, $load = true ) {
// Execute code for this part
do_action( 'get_template_part_' . $slug, $slug, $name );
$load_template = apply_filters( 'edd_allow_template_part_' . $slug . '_' . $name, true );
if ( false === $load_template ) {
return '';
}
// Setup possible parts
$templates = array();
if ( isset( $name ) )
$templates[] = $slug . '-' . $name . '.php';
$templates[] = $slug . '.php';
// Allow template parts to be filtered
$templates = apply_filters( 'edd_get_template_part', $templates, $slug, $name );
// Return the part that is found
return edd_locate_template( $templates, $load, false );
}
/**
* Only allow the pending verification message to display once
* @since 2.7.8
* @param $load_template
*
* @return bool
*/
function edd_load_verification_template_once( $load_template ) {
static $account_pending_loaded;
if ( ! is_null( $account_pending_loaded ) ) {
return false;
}
$account_pending_loaded = true;
return $load_template;
}
add_filter( 'edd_allow_template_part_account_pending', 'edd_load_verification_template_once', 10, 1 );
/**
* Retrieve the name of the highest priority template file that exists.
*
* Searches in the STYLESHEETPATH before TEMPLATEPATH so that themes which
* inherit from a parent theme can just overload one file. If the template is
* not found in either of those, it looks in the theme-compat folder last.
*
* Taken from bbPress
*
* @since 1.2
*
* @param string|array $template_names Template file(s) to search for, in order.
* @param bool $load If true the template file will be loaded if it is found.
* @param bool $require_once Whether to require_once or require. Default true.
* Has no effect if $load is false.
* @return string The template filename if one is located.
*/
function edd_locate_template( $template_names, $load = false, $require_once = true ) {
// No file found yet
$located = false;
// Try to find a template file
foreach ( (array) $template_names as $template_name ) {
// Continue if template is empty
if ( empty( $template_name ) )
continue;
// Trim off any slashes from the template name
$template_name = ltrim( $template_name, '/' );
// try locating this template file by looping through the template paths
foreach( edd_get_theme_template_paths() as $template_path ) {
if( file_exists( $template_path . $template_name ) ) {
$located = $template_path . $template_name;
break;
}
}
if( $located ) {
break;
}
}
if ( ( true == $load ) && ! empty( $located ) )
load_template( $located, $require_once );
return $located;
}
/**
* Returns a list of paths to check for template locations
*
* @since 1.8.5
* @return mixed|void
*/
function edd_get_theme_template_paths() {
$template_dir = edd_get_theme_template_dir_name();
$file_paths = array(
1 => trailingslashit( get_stylesheet_directory() ) . $template_dir,
10 => trailingslashit( get_template_directory() ) . $template_dir,
100 => edd_get_templates_dir()
);
$file_paths = apply_filters( 'edd_template_paths', $file_paths );
// sort the file paths based on priority
ksort( $file_paths, SORT_NUMERIC );
return array_map( 'trailingslashit', $file_paths );
}
/**
* Returns the template directory name.
*
* Themes can filter this by using the edd_templates_dir filter.
*
* @since 1.6.2
* @return string
*/
function edd_get_theme_template_dir_name() {
return trailingslashit( apply_filters( 'edd_templates_dir', 'edd_templates' ) );
}
/**
* Add no-index and no-follow to EDD checkout and purchase confirmation pages
*
* @since 2.0
*
* @return void
*/
function edd_checkout_meta_tags() {
$pages = array();
$pages[] = edd_get_option( 'success_page' );
$pages[] = edd_get_option( 'failure_page' );
$pages[] = edd_get_option( 'purchase_history_page' );
if( ! edd_is_checkout() && ! is_page( $pages ) ) {
return;
}
echo '' . "\n";
echo '' . "\n";
}
add_action( 'wp_head', 'edd_checkout_meta_tags' );
/**
* Adds EDD Version to the tag
*
* @since 1.4.2
* @return void
*/
function edd_version_in_header(){
echo '' . "\n";
}
add_action( 'wp_head', 'edd_version_in_header' );
/**
* Determines if we're currently on the Purchase History page.
*
* @since 2.1
* @return bool True if on the Purchase History page, false otherwise.
*/
function edd_is_purchase_history_page() {
$ret = edd_get_option( 'purchase_history_page', false );
$ret = $ret ? is_page( $ret ) : false;
return apply_filters( 'edd_is_purchase_history_page', $ret );
}
/**
* Adds body classes for EDD pages
*
* @since 2.1
* @param array $class current classes
* @return array Modified array of classes
*/
function edd_add_body_classes( $class ) {
$classes = (array) $class;
if( edd_is_checkout() ) {
$classes[] = 'edd-checkout';
$classes[] = 'edd-page';
}
if( edd_is_success_page() ) {
$classes[] = 'edd-success';
$classes[] = 'edd-page';
}
if( edd_is_failed_transaction_page() ) {
$classes[] = 'edd-failed-transaction';
$classes[] = 'edd-page';
}
if( edd_is_purchase_history_page() ) {
$classes[] = 'edd-purchase-history';
$classes[] = 'edd-page';
}
if( edd_is_test_mode() ) {
$classes[] = 'edd-test-mode';
}
$classes[] = 'edd-js-none';
return array_unique( $classes );
}
add_filter( 'body_class', 'edd_add_body_classes' );
/**
* Adds post classes for downloads
*
* @since 2.1
* @param array $classes Current classes
* @param string|array $class
* @param int $post_id The ID of the current post
* @return array Modified array of classes
*/
function edd_add_download_post_classes( $classes, $class = '', $post_id = false ) {
if( ! $post_id || get_post_type( $post_id ) !== 'download' || is_admin() ) {
return $classes;
}
$download = edd_get_download( $post_id );
if( $download ) {
$classes[] = 'edd-download';
// Add category slugs
$categories = get_the_terms( $post_id, 'download_category' );
if( ! empty( $categories ) ) {
foreach( $categories as $key => $value ) {
$classes[] = 'edd-download-cat-' . $value->slug;
}
}
// Add tag slugs
$tags = get_the_terms( $post_id, 'download_tag' );
if( ! empty( $tags ) ) {
foreach( $tags as $key => $value ) {
$classes[] = 'edd-download-tag-' . $value->slug;
}
}
// Add edd-download
if( is_singular( 'download' ) ) {
$classes[] = 'edd-download';
}
}
return $classes;
}
add_filter( 'post_class', 'edd_add_download_post_classes', 20, 3 );
/**
* Adds Download product price to oembed display
*
* @since 2.6
* @return void
*/
function edd_add_oembed_price() {
if( 'download' !== get_post_type( get_the_ID() ) ) {
return;
}
$show = ! get_post_meta( get_the_ID(), '_edd_hide_purchase_link', true );
if ( apply_filters( 'edd_show_oembed_purchase_links', $show ) ) {
echo '';
echo '';
if ( edd_has_variable_prices( get_the_ID() ) ) {
echo edd_price_range( get_the_ID() );
} else {
edd_price( get_the_ID(), true );
}
echo '
';
}
}
add_action( 'embed_content', 'edd_add_oembed_price' );
/**
* Remove comments button for download embeds
*
* @since 2.6
* @return void
*/
function edd_remove_embed_comments_button() {
global $post;
$hide_comments = apply_filters( 'edd_embed_hide_comments', true, $post );
if ( ! empty( $post ) && $post->post_type == 'download' && true === $hide_comments ) {
remove_action( 'embed_content_meta', 'print_embed_comments_button' );
}
}
add_action( 'embed_content_meta', 'edd_remove_embed_comments_button', 5 );
/**
* Get a fully formatted title of a bundle item
*
* @since 2.7
*
* @param array $bundle_item Bundle item.
* @return string Bundle item title.
*/
function edd_get_bundle_item_title( $bundle_item ) {
$bundle_item_pieces = explode( '_', $bundle_item );
$bundle_item_id = $bundle_item_pieces[0];
$bundle_price_id = isset( $bundle_item_pieces[1] ) ? $bundle_item_pieces[1] : null;
$prices = edd_get_variable_prices( $bundle_item_id );
$bundle_title = get_the_title( $bundle_item_id );
if ( null !== $bundle_price_id ) {
$bundle_title .= ' - ' . $prices[ $bundle_price_id ]['name'];
}
return $bundle_title;
}
/**
* Retrieve the ID of an item in a bundle.
*
* @since 2.7
*
* @param array $bundle_item Bundle item.
* @return string Bundle item ID.
*/
function edd_get_bundle_item_id( $bundle_item ) {
$bundle_item_pieces = explode( '_', $bundle_item );
$bundle_item_id = $bundle_item_pieces[0];
return $bundle_item_id;
}
/**
* Retrieve the price ID of a bundle item.
*
* @since 2.7
*
* @param array $bundle_item Bundle item.
* @return string Bundle item ID.
*/
function edd_get_bundle_item_price_id( $bundle_item ) {
$bundle_item_pieces = explode( '_', $bundle_item );
$bundle_item_id = $bundle_item_pieces[0];
$bundle_price_id = isset( $bundle_item_pieces[1] ) ? $bundle_item_pieces[1] : null;
return $bundle_price_id;
}
/**
* Load a template file for a single download item.
*
* This is a wrapper function for backwards compatibility so the
* shortcode's attributes can be passed to the template file via
* a global variable.
*
* @since 2.8.0
*
* @param array $atts The [downloads] shortcode attributes.
* @param int $i The current item count.
*/
function edd_download_shortcode_item( $atts, $i ) {
global $edd_download_shortcode_item_atts, $edd_download_shortcode_item_i;
/**
* The variables are registered as part of the global scope so the template can access them.
*/
$edd_download_shortcode_item_atts = $atts;
$edd_download_shortcode_item_i = $i;
edd_get_template_part( 'shortcode', 'download' );
}
add_action( 'edd_download_shortcode_item', 'edd_download_shortcode_item', 10, 2 );
/**
* Output full content for a download item in the [downloads] shortcode.
*
* Strips the [downloads] shortcode to avoid recursion.
*
* @since 3.0
*
* @return string
*/
function edd_download_shortcode_full_content() {
$pattern = get_shortcode_regex( array( 'downloads' ) );
$content = preg_replace( "/$pattern/", '', get_the_content( '' ) );
/**
* Filters the full content output for an individual download in [downloads] shortcode.
*
* @since 1.2
*
* @param string $content Download content.
*/
return apply_filters( 'edd_downloads_content', $content );
}
/**
* Output an excerpt for a download item in the [downloads] shortcode.
*
* @since 3.0
*
* @return string
*/
function edd_download_shortcode_excerpt() {
// Adjust excerpt lengths.
add_filter( 'excerpt_length', 'edd_download_shortcode_excerpt_length' );
// Ensure we use `the_excerpt` filter (for length).
ob_start();
the_excerpt();
$excerpt = ob_get_clean();
/**
* Filters the excerpt output for an individual download in [downloads] shortcode.
*
* @since 1.2
*
* @param string $excerpt Download excerpt.
*/
$excerpt = apply_filters( 'edd_downloads_excerpt', $excerpt );
// Let other excerpt lengths act independently again.
remove_filter( 'excerpt_length', 'edd_download_shortcode_excerpt_length' );
return $excerpt;
}
/**
* Callback for the [downloads] shortcode excerpt length.
*
* Added as a callable function so it can be removed after the downloads are output.
*
* @since 3.0
*
* @return int
*/
function edd_download_shortcode_excerpt_length() {
$length = 30;
/**
* Filters the length of the generated excerpts in the [downloads] shortcode.
*
* @since 3.0
*
* @param int $length Length of the excerpt (in words).
*/
return apply_filters( 'edd_download_shortcode_excerpt_length', $length );
}
/**
* Load the pagination for the [downloads] shortcode.
*
* @since 2.9.8
*
* @param array $atts The [downloads] shortcode attributes.
* @param object $downloads The WP_Query.
* @param array $query EDD's array of attributes used to construct the main WP_Query.
*/
function edd_downloads_pagination( $atts, $downloads, $query ) {
if ( filter_var( $atts['pagination'], FILTER_VALIDATE_BOOLEAN ) ) {
$args = array(
'type' => 'download',
'format' => '?paged=%#%',
'current' => max( 1, $query['paged'] ),
'total' => $downloads->max_num_pages
);
if ( is_single() ) {
$args['base'] = get_permalink() . '%#%';
} else {
$big = 999999;
$search_for = array( $big, '#038;' );
$replace_with = array( '%#%', '&' );
$args['base'] = str_replace( $search_for, $replace_with, get_pagenum_link( $big ) );
}
$args = apply_filters( 'edd_download_pagination_args', $args, $atts, $downloads, $query );
echo edd_pagination( $args );
}
}
add_action( 'edd_downloads_list_after', 'edd_downloads_pagination', 10, 3 );
/**
* Build pagination
*
* @since 2.9.8
*
* @param array $args The arguments used to build the pagination.
*/
function edd_pagination( $args = array() ) {
$big = 999999;
$defaults = array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'current' => max( 1, get_query_var( 'paged' ) ),
'type' => '',
'total' => '',
);
$args = wp_parse_args( $args, $defaults );
/**
* Filter pagination args.
*
* @since 3.0
*
* @param array $args Pagination arguments.
*/
$args = apply_filters( 'edd_pagination_args', $args );
$type = $args['type'];
$total = $args['total'];
// Type and total must be specified.
if ( empty( $type ) || empty( $total ) ) {
return false;
}
$pagination = paginate_links(
array(
'base' => $args['base'],
'format' => $args['format'],
'current' => $args['current'],
'total' => $total
)
);
if ( ! empty( $pagination ) ) : ?>