$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(); ?>
ID, $args ); ?>
ID ) ) . '" data-timestamp="' . esc_attr( $timestamp ) . '" data-token="' . esc_attr( EDD\Utils\Tokenizer::tokenize( $timestamp ) ) . '" data-action="edd_add_to_cart" data-download-id="' . esc_attr( $download->ID ) . '" ' . $data_variable . ' ' . $type . ' ' . $data_price . ' ' . $button_display . '>' . $args['text'] . ' '; } echo ''; echo '' . $args['checkout'] . ''; ?> is_free( $args['price_id'] ) && ! edd_download_is_tax_exclusive( $download->ID ) ): ?> ' . sprintf( esc_html__( 'Includes %1$s tax', 'easy-digital-downloads' ), esc_html( edd_get_formatted_tax_rate() ) ) . ''; } elseif ( edd_display_tax_rate() && ! edd_prices_include_tax() ) { /* translators: the formatted tax rate */ echo '' . sprintf( esc_html__( 'Excluding %1$s tax', 'easy-digital-downloads' ), esc_html( edd_get_formatted_tax_rate() ) ) . ''; } ?>
is_free( $args['price_id'] ) ) { ?> ID, $args ) ) : ?> ID, $args ); ?>
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 ); ?>
 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 ); $payment_key = edd_get_payment_key( $payment_id ); $email = edd_get_payment_user_email( $payment_id ); $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 ) ) : ?>