installed plugin Easy Digital Downloads version 3.1.0.3

This commit is contained in:
2022-11-27 15:03:07 +00:00
committed by Gitium
parent 555673545b
commit c5dce2cec6
1200 changed files with 238970 additions and 0 deletions

View File

@ -0,0 +1,121 @@
<?php
/**
* Email Actions
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.0.8.2
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Triggers Purchase Receipt to be sent after the payment status is updated
*
* @since 1.0.8.4
* @since 2.8 - Add parameters for EDD_Payment and EDD_Customer object.
*
* @param int $payment_id Payment ID.
* @param EDD_Payment $payment Payment object for payment ID.
* @param EDD_Customer $customer Customer object for associated payment.
* @return void
*/
function edd_trigger_purchase_receipt( $payment_id = 0, $payment = null, $customer = null ) {
// Make sure we don't send a purchase receipt while editing a payment
if ( isset( $_POST['edd-action'] ) && 'edit_payment' == $_POST['edd-action'] ) {
return;
}
if ( null === $payment ) {
$payment = new EDD_Payment( $payment_id );
}
if ( $payment->order instanceof \EDD\Orders\Order && 'refund' === $payment->order->type ) {
return;
}
// Send email with secure download link
edd_email_purchase_receipt( $payment_id, true, '', $payment, $customer );
}
add_action( 'edd_complete_purchase', 'edd_trigger_purchase_receipt', 999, 3 );
/**
* Resend the Email Purchase Receipt. (This can be done from the Payment History page)
*
* @since 1.0
* @param array $data Payment Data
* @return void
*/
function edd_resend_purchase_receipt( $data ) {
$purchase_id = absint( $data['purchase_id'] );
if( empty( $purchase_id ) ) {
return;
}
if( ! current_user_can( 'edit_shop_payments' ) ) {
wp_die( __( 'You do not have permission to edit this payment record', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
$email = ! empty( $_GET['email'] ) ? sanitize_email( $_GET['email'] ) : '';
if( empty( $email ) ) {
$customer = new EDD_Customer( edd_get_payment_customer_id( $purchase_id ) );
$email = $customer->email;
}
$sent = edd_email_purchase_receipt( $purchase_id, false, $email );
// Grab all downloads of the purchase and update their file download limits, if needed
// This allows admins to resend purchase receipts to grant additional file downloads
$downloads = edd_get_payment_meta_cart_details( $purchase_id, true );
if ( is_array( $downloads ) ) {
foreach ( $downloads as $download ) {
$limit = edd_get_file_download_limit( $download['id'] );
if ( ! empty( $limit ) ) {
edd_set_file_download_limit_override( $download['id'], $purchase_id );
}
}
}
edd_redirect(
add_query_arg(
array(
'edd-message' => $sent ? 'email_sent' : 'email_send_failed',
'edd-action' => false,
'purchase_id' => false,
)
)
);
}
add_action( 'edd_email_links', 'edd_resend_purchase_receipt' );
/**
* Trigger the sending of a Test Email
*
* @since 1.5
* @param array $data Parameters sent from Settings page
* @return void
*/
function edd_send_test_email( $data ) {
if ( ! wp_verify_nonce( $data['_wpnonce'], 'edd-test-email' ) ) {
return;
}
// Send a test email
edd_email_test_purchase_receipt();
$url = edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'emails',
'section' => 'purchase_receipts',
'edd-message' => 'test-purchase-email-sent',
)
);
edd_redirect( $url );
}
add_action( 'edd_send_test_email', 'edd_send_test_email' );

View File

@ -0,0 +1,149 @@
<?php
/**
* Easy Digital Downloads API for creating Email template tags
*
* Email tags are wrapped in { }
*
* A few examples:
*
* {download_list}
* {name}
* {sitename}
*
*
* To replace tags in content, use: edd_do_email_tags( $content, payment_id );
*
* To add tags, use: edd_add_email_tag( $tag, $description, $func ). Be sure to wrap edd_add_email_tag()
* in a function hooked to the 'edd_add_email_tags' action
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.9
* @author Barry Kooij
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
class EDD_Email_Template_Tags {
/**
* Container for storing all tags
*
* @since 1.9
*/
private $tags = array();
/**
* Payment ID
*
* @since 1.9
*/
private $payment_id;
/**
* Add an email tag
*
* @since 1.9
*
* @param string $tag Email tag to be replace in email.
* @param string $label Human readable tag label.
* @param string $description Description of the tag.
* @param callable $func Hook to run when email tag is found.
*/
public function add( $tag, $description, $func, $label = null ) {
if ( is_callable( $func ) ) {
$this->tags[ $tag ] = array(
'tag' => $tag,
'label' => ! empty( $label ) ? $label : ucwords( str_replace( '_', ' ', $tag ) ),
'description' => $description,
'func' => $func,
);
}
}
/**
* Remove an email tag
*
* @since 1.9
*
* @param string $tag Email tag to remove hook from
*/
public function remove( $tag ) {
unset( $this->tags[ $tag ] );
}
/**
* Check if $tag is a registered email tag
*
* @since 1.9
*
* @param string $tag Email tag that will be searched
*
* @return bool
*/
public function email_tag_exists( $tag ) {
return array_key_exists( $tag, $this->tags );
}
/**
* Returns a list of all email tags
*
* @since 1.9
*
* @return array
*/
public function get_tags() {
return (array) $this->tags;
}
/**
* Search content for email tags and filter email tags through their hooks
*
* @param string $content Content to search for email tags
* @param int $payment_id The payment id
*
* @since 1.9
*
* @return string Content with email tags filtered out.
*/
public function do_tags( $content, $payment_id ) {
// Check if there is at least one tag added.
if ( empty( $this->tags ) || ! is_array( $this->tags ) ) {
return $content;
}
$this->payment_id = $payment_id;
$new_content = preg_replace_callback( '/{([A-z0-9\-\_]+)}/s', array( $this, 'do_tag' ), $content );
$this->payment_id = null;
return $new_content;
}
/**
* Do a specific tag, this function should not be used. Please use edd_do_email_tags instead.
*
* @since 1.9
*
* @param $m message
*
* @return mixed
*/
public function do_tag( $m ) {
// Get tag
$tag = $m[1];
// Return tag if tag not set
if ( ! $this->email_tag_exists( $tag ) ) {
return $m[0];
}
return call_user_func( $this->tags[ $tag ]['func'], $this->payment_id, $tag );
}
}

View File

@ -0,0 +1,381 @@
<?php
/**
* Emails
*
* This class handles all emails sent through EDD
*
* @package EDD
* @subpackage Classes/Emails
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.1.php GNU Public License
* @since 2.1
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* EDD_Emails Class
*
* @since 2.1
*/
class EDD_Emails {
/**
* Holds the from address
*
* @since 2.1
*/
private $from_address;
/**
* Holds the from name
*
* @since 2.1
*/
private $from_name;
/**
* Holds the email content type
*
* @since 2.1
*/
private $content_type;
/**
* Holds the email headers
*
* @since 2.1
*/
private $headers;
/**
* Whether to send email in HTML
*
* @since 2.1
*/
private $html = true;
/**
* The email template to use
*
* @since 2.1
*/
private $template;
/**
* The header text for the email
*
* @since 2.1
*/
private $heading = '';
/**
* Get things going
*
* @since 2.1
*/
public function __construct() {
if ( 'none' === $this->get_template() ) {
$this->html = false;
}
add_action( 'edd_email_send_before', array( $this, 'send_before' ) );
add_action( 'edd_email_send_after', array( $this, 'send_after' ) );
}
/**
* Set a property
*
* @since 2.1
*/
public function __set( $key, $value ) {
$this->$key = $value;
}
/**
* Get a property
*
* @since 2.6.9
*/
public function __get( $key ) {
return $this->$key;
}
/**
* Get the email from name
*
* @since 2.1
*/
public function get_from_name() {
if ( ! $this->from_name ) {
$this->from_name = edd_get_option( 'from_name', get_bloginfo( 'name' ) );
}
return apply_filters( 'edd_email_from_name', wp_specialchars_decode( $this->from_name ), $this );
}
/**
* Get the email from address
*
* @since 2.1
*/
public function get_from_address() {
if ( ! $this->from_address ) {
$this->from_address = edd_get_option( 'from_email' );
}
if( empty( $this->from_address ) || ! is_email( $this->from_address ) ) {
$this->from_address = get_option( 'admin_email' );
}
return apply_filters( 'edd_email_from_address', $this->from_address, $this );
}
/**
* Get the email content type
*
* @since 2.1
*/
public function get_content_type() {
if ( ! $this->content_type && $this->html ) {
$this->content_type = apply_filters( 'edd_email_default_content_type', 'text/html', $this );
} else if ( ! $this->html ) {
$this->content_type = 'text/plain';
}
return apply_filters( 'edd_email_content_type', $this->content_type, $this );
}
/**
* Get the email headers
*
* @since 2.1
*/
public function get_headers() {
if ( ! $this->headers ) {
$this->headers = "From: {$this->get_from_name()} <{$this->get_from_address()}>\r\n";
$this->headers .= "Reply-To: {$this->get_from_address()}\r\n";
$this->headers .= "Content-Type: {$this->get_content_type()}; charset=utf-8\r\n";
}
return apply_filters( 'edd_email_headers', $this->headers, $this );
}
/**
* Retrieve email templates
*
* @since 2.1
*/
public function get_templates() {
$templates = array(
'default' => __( 'Default Template', 'easy-digital-downloads' ),
'none' => __( 'No template, plain text only', 'easy-digital-downloads' )
);
return apply_filters( 'edd_email_templates', $templates );
}
/**
* Get the enabled email template
*
* @since 2.1
*
* @return string|null
*/
public function get_template() {
if ( ! $this->template ) {
$this->template = edd_get_option( 'email_template', 'default' );
}
return apply_filters( 'edd_email_template', $this->template );
}
/**
* Get the header text for the email
*
* @since 2.1
*/
public function get_heading() {
return apply_filters( 'edd_email_heading', $this->heading );
}
/**
* Parse email template tags
*
* @since 2.1
* @param string $content
*/
public function parse_tags( $content ) {
// The email tags are parsed during setup for purchase receipts and sale notifications
// Onoce tags are not restricted to payments, we'll expand this. See https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues/2151
return $content;
}
/**
* Build the final email
*
* @since 2.1
* @param string $message
*
* @return string
*/
public function build_email( $message ) {
if ( false === $this->html ) {
return apply_filters( 'edd_email_message', wp_strip_all_tags( $message ), $this );
}
$message = $this->text_to_html( $message );
ob_start();
edd_get_template_part( 'emails/header', $this->get_template(), true );
/**
* Hooks into the email header
*
* @since 2.1
*/
do_action( 'edd_email_header', $this );
if ( has_action( 'edd_email_template_' . $this->get_template() ) ) {
/**
* Hooks into the template of the email
*
* @param string $this->template Gets the enabled email template
* @since 2.1
*/
do_action( 'edd_email_template_' . $this->get_template() );
} else {
edd_get_template_part( 'emails/body', $this->get_template(), true );
}
/**
* Hooks into the body of the email
*
* @since 2.1
*/
do_action( 'edd_email_body', $this );
edd_get_template_part( 'emails/footer', $this->get_template(), true );
/**
* Hooks into the footer of the email
*
* @since 2.1
*/
do_action( 'edd_email_footer', $this );
$body = ob_get_clean();
$message = str_replace( '{email}', $message, $body );
return apply_filters( 'edd_email_message', $message, $this );
}
/**
* Send the email
* @param string $to The To address to send to.
* @param string $subject The subject line of the email to send.
* @param string $message The body of the email to send.
* @param string|array $attachments Attachments to the email in a format supported by wp_mail()
*
* @return bool Whether the email was sent successfully.
* @since 2.1
*/
public function send( $to, $subject, $message, $attachments = '' ) {
if ( ! did_action( 'init' ) && ! did_action( 'admin_init' ) ) {
_doing_it_wrong( __FUNCTION__, __( 'You cannot send email with EDD_Emails until init/admin_init has been reached', 'easy-digital-downloads' ), null );
return false;
}
/**
* Hooks before the email is sent
*
* @since 2.1
*/
do_action( 'edd_email_send_before', $this );
$subject = $this->parse_tags( $subject );
$message = $this->parse_tags( $message );
$message = $this->build_email( $message );
$attachments = apply_filters( 'edd_email_attachments', $attachments, $this );
$sent = wp_mail( $to, $subject, $message, $this->get_headers(), $attachments );
$log_errors = apply_filters( 'edd_log_email_errors', true, $to, $subject, $message );
if( ! $sent && true === $log_errors ) {
if ( is_array( $to ) ) {
$to = implode( ',', $to );
}
$log_message = sprintf(
__( "Email from Easy Digital Downloads failed to send.\nSend time: %s\nTo: %s\nSubject: %s\n\n", 'easy-digital-downloads' ),
date_i18n( 'F j Y H:i:s', current_time( 'timestamp' ) ),
$to,
$subject
);
error_log( $log_message );
}
/**
* Hooks after the email is sent
*
* @since 2.1
*/
do_action( 'edd_email_send_after', $this );
return $sent;
}
/**
* Add filters / actions before the email is sent
*
* @since 2.1
*/
public function send_before() {
add_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
add_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
add_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
}
/**
* Remove filters / actions after the email is sent
*
* @since 2.1
*/
public function send_after() {
remove_filter( 'wp_mail_from', array( $this, 'get_from_address' ) );
remove_filter( 'wp_mail_from_name', array( $this, 'get_from_name' ) );
remove_filter( 'wp_mail_content_type', array( $this, 'get_content_type' ) );
// Reset heading to an empty string
$this->heading = '';
}
/**
* Converts text to formatted HTML. This is primarily for turning line breaks into <p> and <br/> tags.
*
* @since 2.1
*/
public function text_to_html( $message ) {
if ( 'text/html' == $this->content_type || true === $this->html ) {
$message = apply_filters( 'edd_email_template_wpautop', true ) ? wpautop( $message ) : $message;
$message = apply_filters( 'edd_email_template_make_clickable', true ) ? make_clickable( $message ) : $message;
$message = str_replace( '&#038;', '&amp;', $message );
}
return $message;
}
}

View File

@ -0,0 +1,297 @@
<?php
/**
* Email Summary Blurb Class.
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2022, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
use \EDD\Utils\EnvironmentChecker;
/**
* EDD_Email_Summary_Blurb Class.
*
* Takes care of fetching the available blurbs and determines
* which blurb meets the conditions and is next to be sent.
*
* @since 3.1
*/
class EDD_Email_Summary_Blurb {
/**
* URL of the endpoint for the blurbs JSON.
*
* @since 3.1
*
* @const string
*/
const BLURBS_ENDPOINT_URL = 'https://plugin.easydigitaldownloads.com/wp-content/summaries.json';
/**
* Environment Checker class.
*
* @var EnvironmentChecker
*/
protected $environment_checker;
/**
* Class constructor.
*
* @since 3.1
*/
public function __construct() {
// Load plugin.php so that we can use is_plugin_active().
require_once ABSPATH . 'wp-admin/includes/plugin.php';
$this->environment_checker = new EnvironmentChecker();
}
/**
* Fetch all blurbs from remote endpoint.
*
* @since 3.1
*
* @return array
*/
public function fetch_blurbs() {
$blurbs = array();
$request_body = false;
$request = wp_safe_remote_get( self::BLURBS_ENDPOINT_URL );
// @todo - Detect first response code, before redirect!
if ( ! is_wp_error( $request ) && 200 === wp_remote_retrieve_response_code( $request ) ) {
$request_body = wp_remote_retrieve_body( $request );
$blurbs = json_decode( $request_body, true );
}
if ( empty( $request_body ) ) {
// HTTP Request for blurbs is empty, fallback to local .json file.
$fallback_json = wp_json_file_decode( EDD_PLUGIN_DIR . 'includes/admin/promos/email-summary/blurbs.json', array( 'associative' => true ) );
if ( ! empty( $fallback_json ) ) {
$blurbs = $fallback_json;
}
}
return $blurbs;
}
/**
* Get the next blurb that can be sent.
*
* @since 3.1
*
* @return array
*/
public function get_next() {
$all_data = $this->fetch_blurbs();
$blurbs = array();
$blurbs_sent = get_option( 'email_summary_blurbs_sent', array() );
$next_blurb = false;
if ( empty( $all_data['blurbs'] ) ) {
return false;
}
// Loop through the fetched blurbs and filter out all that meet the conditions.
foreach ( $all_data['blurbs'] as $key => $blurb ) {
if ( $this->does_blurb_meet_conditions( $blurb ) ) {
$blurbs[] = $blurb;
}
}
// Find first blurb that was not yet sent.
foreach ( $blurbs as $blurb ) {
$blurb_hash = $this->get_blurb_hash( $blurb );
if ( is_array( $blurbs_sent ) && ! in_array( $blurb_hash, $blurbs_sent, true ) ) {
$next_blurb = $blurb;
break;
}
}
// If all of the available blurbs were already sent out, choose random blurb.
if ( ! $next_blurb && ! empty( $blurbs ) ) {
$next_blurb = $blurbs[ array_rand( $blurbs ) ];
}
return $next_blurb;
}
/**
* Save blurb as sent to the options.
*
* @since 3.1
*
* @param array $blurb Blurb data.
* @return void
*/
public function mark_blurb_sent( $blurb ) {
$blurbs_sent = get_option( 'email_summary_blurbs_sent', array() );
if ( ! empty( $blurb ) ) {
$blurb_hash = $this->get_blurb_hash( $blurb );
if ( ! in_array( $blurb_hash, $blurbs_sent, true ) ) {
$blurbs_sent[] = $blurb_hash;
}
}
update_option( 'email_summary_blurbs_sent', $blurbs_sent );
}
/**
* Hash blurb array
*
* @since 3.1
*
* @param array $blurb Blurb data.
* @return string MD5 hashed blurb.
*/
public function get_blurb_hash( $blurb ) {
if ( empty( $blurb ) ) {
return false;
}
// We want to sort the array, so that we can get reliable hash everytime even if array properties order changed.
array_multisort( $blurb );
return md5( wp_json_encode( $blurb ) );
}
/**
* Check if store pass matches the condition from the blurb.
*
* @since 3.1
*
* @param string $condition Pass details.
* @return bool
*/
public function check_blurb_current_pass( $condition ) {
return $this->environment_checker->meetsCondition( $condition );
}
/**
* Check if store has all requested plugins active.
*
* @since 3.1
*
* @param array $active_plugins An array of plugins that all need to be active.
* @return bool
*/
public function check_blurb_active_plugins( $active_plugins ) {
foreach ( $active_plugins as $plugin_name ) {
if ( ! is_plugin_active( $plugin_name ) ) {
return false;
}
}
return true;
}
/**
* Check if store has certain plugins inactive.
*
* @since 3.1
*
* @param array $inactive_plugins An array of plugins that needs to be inactive.
* @return bool
*/
public function check_blurb_inactive_plugins( $inactive_plugins ) {
foreach ( $inactive_plugins as $plugin_name ) {
if ( is_plugin_active( $plugin_name ) ) {
return false;
}
}
return true;
}
/**
* Check if store has specific products/downloads active.
*
* @since 3.1
*
* @param array $conditions An array of predefined conditions.
* @return bool
*/
public function check_blurb_has_downloads( $conditions ) {
foreach ( $conditions as $condition_name ) {
// Check if store has any products that are free.
if ( 'free' === $condition_name ) {
$args = array(
'post_type' => 'download',
'posts_per_page' => 1,
'fields' => 'ids',
'no_found_rows' => true,
'meta_query' => array(
array(
'key' => 'edd_price',
'value' => '0.00',
),
),
);
$downloads = new WP_Query( $args );
if ( 0 === $downloads->post_count ) {
return false;
}
}
}
return true;
}
/**
* Check if blurb meets conditions.
*
* @since 3.1
*
* @param array $blurb Blurb data.
* @return bool
*/
public function does_blurb_meet_conditions( $blurb ) {
if ( isset( $blurb['conditions'] ) && ! empty( $blurb['conditions'] ) ) {
foreach ( $blurb['conditions'] as $condition_name => $condition ) {
if ( empty( $condition ) ) {
continue;
}
// Pass check.
if ( 'current_pass' === $condition_name ) {
if ( ! $this->check_blurb_current_pass( $condition ) ) {
return false;
}
}
// Active plugins check.
if ( 'active_plugins' === $condition_name ) {
if ( ! $this->check_blurb_active_plugins( $condition ) ) {
return false;
}
}
// Inactive plugins check.
if ( 'inactive_plugins' === $condition_name ) {
if ( ! $this->check_blurb_inactive_plugins( $condition ) ) {
return false;
}
}
// Check for specific product/downloads.
if ( 'has_downloads' === $condition_name ) {
if ( ! $this->check_blurb_has_downloads( $condition ) ) {
return false;
}
}
}
}
return true;
}
}

View File

@ -0,0 +1,164 @@
<?php
/**
* Email Summary Cron Class.
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2022, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* EDD_Email_Summary_Cron Class.
*
* Takes care of scheduling and sending Email Summaries.
*
* @since 3.1
*/
class EDD_Email_Summary_Cron {
/**
* Name of the Email Summary cron hook.
*
* @since 3.1
*
* @const string
*/
const CRON_EVENT_NAME = 'edd_email_summary_cron';
/**
* Class constructor.
*
* @since 3.1
*/
public function __construct() {
// Register daily check.
add_action( 'edd_daily_scheduled_events', array( $this, 'schedule_cron_events' ) );
// User settings changed.
add_action( 'updated_option', array( $this, 'settings_changed' ), 10, 3 );
// Prepare and run cron.
add_action( self::CRON_EVENT_NAME, array( $this, 'run_cron' ) );
}
/**
* Get the current status of email summary.
*
* @since 3.1
*
* @return bool True if email summary is enabled, false if disabled.
*/
public function is_enabled() {
return (bool) ! edd_get_option( 'disable_email_summary', false );
}
/**
* Determine when the next cron event
* should be and schedule it.
*
* @since 3.1
*
* @return void
*/
public function schedule_cron_events() {
// Exit if email summary is disabled or event is already scheduled.
if ( ! $this->is_enabled() || wp_next_scheduled( self::CRON_EVENT_NAME ) ) {
return;
}
// Get the event date based on user settings.
$days = EDD()->utils->date()->getDays();
$email_frequency = edd_get_option( 'email_summary_frequency', 'weekly' );
$week_start_day = $days[ (int) get_option( 'start_of_week' ) ];
if ( 'monthly' === $email_frequency ) {
$next_time_string = 'first day of next month 8am';
} else {
$next_time_string = "next {$week_start_day} 8am";
}
$date = new \DateTime( $next_time_string, new DateTimeZone( edd_get_timezone_id() ) );
wp_schedule_single_event( $date->getTimestamp(), self::CRON_EVENT_NAME );
}
/**
* Clear all cron events related to email summary.
*
* @since 3.1
*
* @return void
*/
public function clear_cron_events() {
wp_clear_scheduled_hook( self::CRON_EVENT_NAME );
}
/**
* Detect when settings that affect the
* schedule of email summaries are updated.
*
* @since 3.1
*
* @param string $option_name WordPress option that was changed.
* @param string $old_value Old option value.
* @param string $new_value New option value.
*
* @return void
*/
public function settings_changed( $option_name, $old_value, $new_value ) {
if ( ! in_array( $option_name, array( 'edd_settings', 'start_of_week', 'timezone_string', 'gmt_offset' ), true ) ) {
return;
}
// If `edd_settings` were changed, listen
// only to changes in specific fields.
if ( 'edd_settings' === $option_name ) {
$change_detected = false;
$field_listeners = array( 'email_summary_frequency', 'disable_email_summary' );
foreach ( $field_listeners as $field ) {
if ( ( empty( $old_value[ $field ] ) || empty( $new_value[ $field ] ) ) || ( $old_value[ $field ] !== $new_value[ $field ] ) ) {
$change_detected = true;
break;
}
}
if ( ! $change_detected ) {
return;
}
// Reload EDD options so that we have the newest values in class methods.
global $edd_options;
$edd_options = get_option( 'edd_settings' );
}
$this->clear_cron_events();
$this->schedule_cron_events();
}
/**
* Initialize the cron with all the proper checks.
*
* @since 3.1
*
* @return void
*/
public function run_cron() {
// This is not cron, abort!
if ( ! wp_doing_cron() ) {
return;
}
$email = new EDD_Email_Summary();
$email->send_email();
// Schedule the next event.
$this->schedule_cron_events();
}
}

View File

@ -0,0 +1,407 @@
<?php
/**
* Email Summary Class.
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2022, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.1
*/
// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;
/**
* EDD_Email_Summary Class.
*
* Takes care of preparing the necessary dataset, building the
* email template and sending the Email Summary.
*
* @since 3.1
*/
class EDD_Email_Summary {
/**
* Are we in a test mode.
*
* @since 3.1
*
* @var bool
*/
private $test_mode;
/**
* Email options.
*
* @since 3.1
*
* @var string
*/
private $email_options;
/**
* Class constructor.
*
* @since 3.1
*/
public function __construct( $test_mode = false ) {
$this->test_mode = $test_mode;
$this->email_options = array(
'email_summary_frequency' => edd_get_option( 'email_summary_frequency', 'weekly' ),
'email_summary_start_of_week' => jddayofweek( (int) get_option( 'start_of_week' ) - 1, 1 ),
);
}
/**
* Get site URL.
*
* @since 3.1
*
* @return string Host of the site url.
*/
public function get_site_url() {
$site_url = get_site_url();
$site_url_parsed = wp_parse_url( $site_url );
$site_url = isset( $site_url_parsed['host'] ) ? $site_url_parsed['host'] : $site_url;
return $site_url;
}
/**
* Get email subject.
*
* @since 3.1
*
* @return string Email subject.
*/
public function get_email_subject() {
/* Translators: Site domain name */
$email_subject = sprintf( __( 'Easy Digital Downloads Summary - %s', 'easy-digital-downloads' ), $this->get_site_url() );
if ( $this->test_mode ) {
$email_subject = '[TEST] ' . $email_subject;
}
return $email_subject;
}
/**
* Get email recipients.
*
* @since 3.1
*
* @return array Recipients to receive the email.
*/
public function get_email_recipients() {
$recipients = array();
if ( 'admin' === edd_get_option( 'email_summary_recipient', 'admin' ) ) {
$recipients[] = get_option( 'admin_email' );
} else {
$emails = edd_get_option( 'email_summary_custom_recipients', '' );
$emails = array_map( 'trim', explode( "\n", $emails ) );
foreach ( $emails as $email ) {
if ( is_email( $email ) ) {
$recipients[] = $email;
}
}
}
if ( empty( $recipients ) ) {
edd_debug_log( __( 'Missing email recipients for Email Summary', 'easy-digital-downloads' ), true );
}
return apply_filters( 'edd_email_summary_recipients', $recipients );
}
/**
* Get report start date.
*
* @since 3.1
*
* @return EDD\Utils\Date An array of start date and its relative counterpart as the EDD date object set at the UTC equivalent time.
*/
public function get_report_start_date() {
$date = EDD()->utils->date( 'now', edd_get_timezone_id(), false );
if ( 'monthly' === $this->email_options['email_summary_frequency'] ) {
$start_date = $date->copy()->subMonth( 1 )->startOfMonth();
$relative_start_date = $date->copy()->subMonth( 2 )->startOfMonth();
} else {
$start_date = $date->copy()->subDay( 7 )->startOfDay();
$relative_start_date = $date->copy()->subDay( 14 )->startOfDay();
}
return array(
'start_date' => $start_date,
'relative_start_date' => $relative_start_date,
);
}
/**
* Get report end date.
*
* @since 3.1
*
* @return EDD\Utils\Date An array of end date and its relative counterpart as the EDD date object set at the UTC equivalent time.
*/
public function get_report_end_date() {
$date = EDD()->utils->date( 'now', edd_get_timezone_id(), false );
if ( 'monthly' === $this->email_options['email_summary_frequency'] ) {
$end_date = $date->copy()->subMonth( 1 )->endOfMonth();
$relative_end_date = $date->copy()->subMonth( 2 )->endOfMonth();
} else {
$end_date = $date->copy()->endOfDay();
$relative_end_date = $date->copy()->subDay( 7 )->endOfDay();
}
return array(
'end_date' => $end_date,
'relative_end_date' => $relative_end_date,
);
}
/**
* Get report date range.
*
* @since 3.1
*
* @return array Array of start and end date objects in \EDD\Utils\Date[] format.
*/
public function get_report_date_range() {
// @todo - Check if we have to convert this to UTC because of DB?
return array_merge(
$this->get_report_start_date(),
$this->get_report_end_date()
);
}
/**
* Retrieve ! TEST ! dataset for email content.
*
* @since 3.1
*
* @return array Data and statistics for the period.
*/
public function get_test_report_dataset() {
$stats = new EDD\Stats();
$args = array(
'post_type' => 'download',
'posts_per_page' => 5,
'fields' => 'ids',
'no_found_rows' => true,
);
$downloads = new WP_Query( $args );
$top_selling_products = array();
foreach ( $downloads->posts as $post ) {
$download = new EDD_Download( $post );
$product = new stdClass();
$product->object = $download;
$product->total = 100;
$top_selling_products[] = $product;
}
$data = array(
'earnings_gross' => array(
'value' => 5000,
'relative_data' => $stats->generate_relative_data( 5000, 4000 ),
),
'earnings_net' => array(
'value' => 4500,
'relative_data' => $stats->generate_relative_data( 4500, 3500 ),
),
'average_order_value' => array(
'value' => 29,
'relative_data' => $stats->generate_relative_data( 20, 35 ),
),
'new_customers' => array(
'value' => 25,
'relative_data' => $stats->generate_relative_data( 25, 20 ),
),
'top_selling_products' => $top_selling_products,
'order_count' => array( 'value' => 172 ),
);
return $data;
}
/**
* Retrieve dataset for email content.
*
* @since 3.1
*
* @return array Data and statistics for the period.
*/
public function get_report_dataset() {
if ( $this->test_mode ) {
return $this->get_test_report_dataset();
}
$date_range = $this->get_report_date_range();
$start_date = $date_range['start_date']->format( 'Y-m-d H:i:s' );
$end_date = $date_range['end_date']->format( 'Y-m-d H:i:s' );
$relative_start_date = $date_range['relative_start_date']->format( 'Y-m-d H:i:s' );
$relative_end_date = $date_range['relative_end_date']->format( 'Y-m-d H:i:s' );
$stats = new EDD\Stats(
array(
'output' => 'array',
'start' => $start_date,
'end' => $end_date,
'relative' => true,
'relative_start' => $relative_start_date,
'relative_end' => $relative_end_date,
)
);
$earnings_gross = $stats->get_order_earnings(
array(
'function' => 'SUM',
'exclude_taxes' => false,
'revenue_type' => 'gross',
)
);
$earnings_net = $stats->get_order_earnings(
array(
'function' => 'SUM',
'exclude_taxes' => true,
'revenue_type' => 'net',
)
);
$average_order_value = $stats->get_order_earnings(
array(
'function' => 'AVG',
'exclude_taxes' => false,
)
);
$new_customers = $stats->get_customer_count();
$top_selling_products = $stats->get_most_valuable_order_items(
array(
'number' => 5,
)
);
$order_count = $stats->get_order_count();
return compact(
'earnings_gross',
'earnings_net',
'average_order_value',
'new_customers',
'top_selling_products',
'order_count'
);
}
/**
* Generate HTML for relative markup.
*
* @since 3.1
*
* @param array $relative_data Calculated relative data.
*
* @return string HTML for relative markup.
*/
private function build_relative_markup( $relative_data ) {
$arrow = $relative_data['positive_change'] ? 'icon-arrow-up.png' : 'icon-arrow-down.png';
$output = __( 'No data to compare', 'easy-digital-downloads' );
if ( $relative_data['no_change'] ) {
$output = __( 'No Change', 'easy-digital-downloads' );
} elseif ( $relative_data['comparable'] ) {
$output = $relative_data['formatted_percentage_change'] . '%';
}
ob_start();
?>
<?php if ( $relative_data['comparable'] ) : ?>
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/' . $arrow ); ?>" width="12" height="10" style="outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; width: 12px; height: 10px; max-width: 100%; clear: both; vertical-align: text-top;">
<?php endif; ?>
<span style="padding-left: 1px;">
<?php echo esc_html( $output ); ?>
</span>
<?php
return ob_get_clean();
}
/**
* Build email template.
*
* @since 3.1
*
* @param array|bool $blurb Structured blurb data.
*
* @return string|bool The string of the email template or false if the email template couldn't be built.
*/
public function build_email_template( $blurb = false ) {
$dataset = $this->get_report_dataset();
// If there were no sales, do not build an email template.
if ( empty( $dataset['order_count'] ) || 0 === $dataset['order_count'] ) {
return false;
}
$date_range = $this->get_report_date_range();
$site_url = get_site_url();
$view_more_url = edd_get_admin_url(
array(
'page' => 'edd-reports',
'range' => ( 'monthly' === $this->email_options['email_summary_frequency'] ) ? 'last_month' : 'last_week',
'relative_range' => 'previous_period',
)
);
$wp_date_format = get_option( 'date_format' );
$period_name = ( 'monthly' === $this->email_options['email_summary_frequency'] ) ? __( 'month', 'easy-digital-downloads' ) : __( 'week', 'easy-digital-downloads' );
/* Translators: period name (e.g. week) */
$relative_text = sprintf( __( 'vs previous %s', 'easy-digital-downloads' ), $period_name );
ob_start();
include EDD_PLUGIN_DIR . 'includes/emails/email-summary/edd-email-summary-template.php';
return ob_get_clean();
}
/**
* Prepare and send email.
*
* @since 3.1
*
* @return bool True if email was sent, false if there was an error.
*/
public function send_email() {
// Get next blurb.
$email_blurbs = new EDD_Email_Summary_Blurb();
$next_blurb = false;
if ( ! $this->test_mode ) {
$next_blurb = $email_blurbs->get_next();
}
// Prepare email.
$email_body = $this->build_email_template( $next_blurb );
// If there is no email body, we cannot continue.
if ( ! $email_body ) {
edd_debug_log( __( 'Email body for Email Summary was empty.', 'easy-digital-downloads' ), true );
return false;
}
$email_subject = $this->get_email_subject();
$email_recipients = $this->get_email_recipients();
$email_headers = array( 'Content-Type: text/html; charset=UTF-8' );
// Everything is ok, send email.
$email_sent = wp_mail( $email_recipients, $email_subject, $email_body, $email_headers );
if ( $email_sent ) {
$email_blurbs->mark_blurb_sent( $next_blurb );
}
return $email_sent;
}
}

View File

@ -0,0 +1,418 @@
<!DOCTYPE html>
<html>
<head>
<title><?php echo esc_html( $this->get_email_subject() ); ?></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--<![endif]-->
<style>
@media only screen and (max-width: 480px) {
body {
max-width: 320px;
}
.push-down-25 {
margin-bottom: 25px;
}
.pull-down-8 {
margin-top: 8px !important;
}
.pull-down-5 {
margin-top: 5px !important;
}
h1 {
font-size: 20px !important;
line-height: 26px !important;
}
h2 {
font-size: 16px !important;
line-height: 22px !important;
}
p {
font-size: 12px !important;
line-height: 17px !important;
}
p.bigger {
font-size: 12px !important;
line-height: 16px !important;
}
.email-header-holder {
max-height: 50px !important;
height: 50px !important;
}
.logo-holder {
padding: 10px 22px 5px 22px !important;
}
.logo-holder .edd-logo {
max-width: 175px !important;
max-height: 28px !important;
}
.content-holder {
padding: 22px 22px 0px 22px !important;
}
.content-holder.pro-tip-section {
padding: 0px 22px 27px 22px !important;
}
.period-date {
font-size: 12px !important;
line-height: 15px !important;
}
.link-style {
font-size: 12px !important;
line-height: 15px !important;
}
.link-style.bigger {
font-size: 12px !important;
line-height: 15px !important;
}
.stats-totals-wrapper {
margin-top: 38px !important;
}
.stats-totals-wrapper td {
font-size: 12px !important;
border-collapse: collapse !important;
}
.stats-total-item {
width: 145px;
display: inline-table;
min-width: 145px;
}
.stats-total-item-inner {
font-size: 12px !important;
border-collapse: collapse !important;
}
.stats-total-item-title {
font-size: 16px !important;
line-height: 19px !important;
margin-bottom: 10px !important;
}
.stats-total-item-value {
line-height: 18px !important;
font-size: 16px !important;
margin: 0 0 11px 0px !important;
}
.stats-total-item-percent {
line-height: 11px !important;
font-size: 11px !important;
white-space: nowrap;
}
.stats-total-item-percent span.comparison {
font-style: normal;
font-weight: lighter;
font-size: 11px !important;
line-height: 15px !important;
margin-top: 5px !important;
}
.stats-total-item-percent img {
width: 8px !important;
height: 6px !important;
vertical-align: baseline !important;
}
.table-top-title {
font-size: 12px !important;
line-height: 15px !important;
}
table.top-products tr th {
padding: 8px 0px !important;
font-size: 12px !important;
line-height: 15px !important;
}
table.top-products tr td {
font-size: 12px !important;
padding: 10px 0px !important;
border-bottom: 1px solid #F0F1F4;
}
table.top-products tr td:nth-child(2) {
font-size: 12px !important;
}
.pro-tip-holder {
background: #F3F8FE;
border-radius: 8px !important;
padding: 24px 24px !important;
}
.pro-tip-section-title {
font-size: 14px !important;
line-height: 15px !important;
}
.pro-tip-section-title img {
margin-right: 3px !important;
}
.pro-tip-title {
font-size: 14px !important;
line-height: 18px !important;
}
.cta-btn {
padding: 6px 15px;
font-weight: 600;
font-size: 16px;
line-height: 20px;
background: #2794DA;
display: inline-block;
color: #FFFFFF;
text-decoration: none;
}
}
</style>
</head>
<body style="margin: 0px auto; max-width: 450px;">
<!-- PREVIEW TEXT -->
<div style="display: none; max-height: 0px; overflow: hidden;">
<?php echo esc_html( __( 'Store performance summary', 'easy-digital-downloads' ) ); ?> <?php echo esc_html( $date_range['start_date']->format( $wp_date_format ) ); ?> - <?php echo esc_html( $date_range['end_date']->format( $wp_date_format ) ); ?>
</div>
<!-- HEADER HOLDER -->
<div class="email-header-holder" style="background: #343A40; max-height: 60px; height: 60px;">
<div class="email-container" style="max-width: 450px; margin: 0 auto; font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; color: #1F2937;">
<div class="logo-holder" style="padding: 12px 31px 7px 31px; display: inline-block;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/edd-logo-white-2x.png' ); ?>" class="edd-logo" width="216" height="35" style="width: 100%; max-width: 100%; height: auto; max-width: 216px; max-height: 35px;">
</div>
</div>
</div>
<div class="email-container" style="max-width: 450px; margin: 0 auto; font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; color: #1F2937;">
<!-- MAIN EMAIL CONTENT HOLDER -->
<div class="content-box" style="background: #FFF;">
<div class="content-holder" style="padding: 22px 31px 0px 31px;">
<h1 style="margin: 0px; color: #1F2937;font-weight: 700;font-size: 24px;line-height: 24px;"><?php echo esc_html( __( 'Your eCommerce Summary', 'easy-digital-downloads' ) ); ?></h1>
<div class="period-date pull-down-8" style="margin-top: 8px; font-weight: 400; font-size: 14px; line-height: 18px; color: #4B5563;">
<?php echo esc_html( $date_range['start_date']->format( $wp_date_format ) ); ?> - <?php echo esc_html( $date_range['end_date']->format( $wp_date_format ) ); ?>
</div>
<a href="<?php echo esc_url( $site_url ); ?>" class="link-style pull-down-8" style="margin-top: 8px; font-weight: 400; font-size: 14px; text-decoration-line: underline; display: inline-block; color: inherit; text-decoration: none;">
<?php echo esc_url( $site_url ); ?>
</a>
<div class="pull-down-20" style="margin-top: 20px;">
<h2 style="margin: 0px; font-weight: 700; font-size: 18px; line-height: 23px; letter-spacing: -0.02em; color: #1F2937;"><?php echo esc_html( __( 'Hey there!', 'easy-digital-downloads' ) ); ?></h2>
</div>
<p class="pull-down-5" style="margin: 0px; font-weight: 400; font-size: 14px; line-height: 18px; color: #4B5563; margin-top: 5px;">
<?php
/* Translators: period name (e.g. week) */
echo esc_html( sprintf( __( 'Below is a look at how your store performed in the last %s.', 'easy-digital-downloads' ), $period_name ) );
?>
</p>
<!-- DATA LISTING -->
<table class="stats-totals-wrapper" style="border-collapse: collapse; border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; width: 100%; margin-top: 48px;" width="100%" valign="top" align="left">
<tr style="padding: 0; vertical-align: top; text-align: left;" valign="top" align="left">
<td class="stats-totals-item-wrapper" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" valign="top" align="center">
<table class="stats-total-item" width="145" style="border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; width: 145px; display: inline-table; min-width: 145px;" valign="top" align="center">
<tr style="padding: 0; vertical-align: top; text-align: left;" valign="top" align="left">
<td class="stats-total-item-inner" style="width: 100%; min-width: 100%; word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" width="100%" valign="top" align="center">
<p class="stats-total-item-icon-wrapper" style="font-weight: 400; font-size: 14px; line-height: 18px; margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #809EB0; padding: 0; text-align: center; mso-line-height-rule: exactly; margin-bottom: 1px; height: 32px;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-gross.png' ); ?>" alt="#" title="#" width="28" height="28">
</p>
<p class="stats-total-item-title" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #1F2937; padding: 0; text-align: center; mso-line-height-rule: exactly; font-weight: 600; font-size: 14px; line-height: 18px; font-style: normal; margin-bottom: 5px; white-space: nowrap;">
<?php echo esc_html( __( 'Gross Revenue', 'easy-digital-downloads' ) ); ?>
</p>
<p class="stats-total-item-value dark-white-color" style="margin: 0 0 6px 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: bold; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 32px; font-size: 32px;">
<?php echo esc_html( edd_currency_filter( edd_format_amount( $dataset['earnings_gross']['value'] ) ) ); ?>
</p>
<p class="stats-total-item-percent" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #777777; font-weight: normal; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 14px; font-size: 10px; white-space: nowrap;">
<?php echo $this->build_relative_markup( $dataset['earnings_gross']['relative_data'] ); ?>
<span class="comparison" style="font-style: normal; font-weight: lighter; font-size: 12px; line-height: 14px; text-align: center; color: #6B7280; display: block; margin-top: 6px;">
<?php echo esc_html( $relative_text ); ?>
</span>
</p>
</td>
</tr>
</table>
</td>
<td class="stats-totals-item-wrapper" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" valign="top" align="center">
<table class="stats-total-item" width="145" style="border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; width: 145px; display: inline-table; min-width: 145px;" valign="top" align="center">
<tr style="padding: 0; vertical-align: top; text-align: left;" valign="top" align="left">
<td class="stats-total-item-inner" style="width: 100%; min-width: 100%; word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" width="100%" valign="top" align="center">
<p class="stats-total-item-icon-wrapper" style="font-weight: 400; font-size: 14px; line-height: 18px; margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #809EB0; padding: 0; text-align: center; mso-line-height-rule: exactly; margin-bottom: 1px; height: 32px;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-net.png' ); ?>" alt="#" title="#" width="28" height="28">
</p>
<p class="stats-total-item-title" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #1F2937; padding: 0; text-align: center; mso-line-height-rule: exactly; font-weight: 600; font-size: 14px; line-height: 18px; font-style: normal; margin-bottom: 5px; white-space: nowrap;">
<?php echo esc_html( __( 'Net Revenue', 'easy-digital-downloads' ) ); ?>
</p>
<p class="stats-total-item-value dark-white-color" style="margin: 0 0 6px 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: bold; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 32px; font-size: 32px;">
<?php echo esc_html( edd_currency_filter( edd_format_amount( $dataset['earnings_net']['value'] ) ) ); ?>
</p>
<p class="stats-total-item-percent" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #777777; font-weight: normal; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 14px; font-size: 10px; white-space: nowrap;">
<?php echo $this->build_relative_markup( $dataset['earnings_net']['relative_data'] ); ?>
<span class="comparison" style="font-style: normal; font-weight: lighter; font-size: 12px; line-height: 14px; text-align: center; color: #6B7280; display: block; margin-top: 6px;">
<?php echo esc_html( $relative_text ); ?>
</span>
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
<table class="stats-totals-wrapper pull-down-40" style="border-collapse: collapse; border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; width: 100%; margin-top: 48px; margin-bottom: 48px !important;" width="100%" valign="top" align="left">
<tr style="padding: 0; vertical-align: top; text-align: left;" valign="top" align="left">
<td class="stats-totals-item-wrapper" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" valign="top" align="center">
<table class="stats-total-item" width="145" style="border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; width: 145px; display: inline-table; min-width: 145px;" valign="top" align="center">
<tr style="padding: 0; vertical-align: top; text-align: left;" valign="top" align="left">
<td class="stats-total-item-inner" style="width: 100%; min-width: 100%; word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" width="100%" valign="top" align="center">
<p class="stats-total-item-icon-wrapper" style="font-weight: 400; font-size: 14px; line-height: 18px; margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #809EB0; padding: 0; text-align: center; mso-line-height-rule: exactly; margin-bottom: 1px; height: 32px;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-new-customers.png' ); ?>" alt="#" title="#" width="28" height="28">
</p>
<p class="stats-total-item-title" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #1F2937; padding: 0; text-align: center; mso-line-height-rule: exactly; font-weight: 600; font-size: 14px; line-height: 18px; font-style: normal; margin-bottom: 5px; white-space: nowrap;">
<?php echo esc_html( __( 'New Customers', 'easy-digital-downloads' ) ); ?>
</p>
<p class="stats-total-item-value dark-white-color" style="margin: 0 0 6px 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: bold; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 32px; font-size: 32px;">
<?php echo esc_html( $dataset['new_customers']['value'] ); ?>
</p>
<p class="stats-total-item-percent" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #777777; font-weight: normal; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 14px; font-size: 10px; white-space: nowrap;">
<?php echo $this->build_relative_markup( $dataset['new_customers']['relative_data'] ); ?>
<span class="comparison" style="font-style: normal; font-weight: lighter; font-size: 12px; line-height: 14px; text-align: center; color: #6B7280; display: block; margin-top: 6px;">
<?php echo esc_html( $relative_text ); ?>
</span>
</p>
</td>
</tr>
</table>
</td>
<td class="stats-totals-item-wrapper" style="word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" valign="top" align="center">
<table class="stats-total-item" width="145" style="border-spacing: 0; padding: 0; vertical-align: top; text-align: left; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; width: 145px; display: inline-table; min-width: 145px;" valign="top" align="center">
<tr style="padding: 0; vertical-align: top; text-align: left;" valign="top" align="left">
<td class="stats-total-item-inner" style="width: 100%; min-width: 100%; word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; hyphens: auto; padding: 0px; vertical-align: top; text-align: center; mso-table-lspace: 0pt; mso-table-rspace: 0pt; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: normal; margin: 0; mso-line-height-rule: exactly; line-height: 140%; font-size: 14px; border-collapse: collapse;" width="100%" valign="top" align="center">
<p class="stats-total-item-icon-wrapper" style="font-weight: 400; font-size: 14px; line-height: 18px; margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #809EB0; padding: 0; text-align: center; mso-line-height-rule: exactly; margin-bottom: 1px; height: 32px;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-average.png' ); ?>" alt="#" title="#" width="28" height="28">
</p>
<p class="stats-total-item-title" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #1F2937; padding: 0; text-align: center; mso-line-height-rule: exactly; font-weight: 600; font-size: 14px; line-height: 18px; font-style: normal; margin-bottom: 5px; white-space: nowrap;">
<?php echo esc_html( __( 'Average Order', 'easy-digital-downloads' ) ); ?>
</p>
<p class="stats-total-item-value dark-white-color" style="margin: 0 0 6px 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #444444; font-weight: bold; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 32px; font-size: 32px;">
<?php echo esc_html( edd_currency_filter( edd_format_amount( $dataset['average_order_value']['value'] ) ) ); ?>
</p>
<p class="stats-total-item-percent" style="margin: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; color: #777777; font-weight: normal; padding: 0; text-align: center; mso-line-height-rule: exactly; line-height: 14px; font-size: 10px; white-space: nowrap;">
<?php echo $this->build_relative_markup( $dataset['average_order_value']['relative_data'] ); ?>
<span class="comparison" style="font-style: normal; font-weight: lighter; font-size: 12px; line-height: 14px; text-align: center; color: #6B7280; display: block; margin-top: 6px;">
<?php echo esc_html( $relative_text ); ?>
</span>
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
<hr style="border: 0.2px solid #E5E7EB; display: block;">
<!-- TABLE DATA -->
<div class="table-data-holder pull-down-25 " style="margin-top: 25px; ">
<div class="table-top-icon align-c" style="text-align: center;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-top-products.png' ); ?>" alt="#" title="#" width="28" height="28">
</div>
<div class="table-top-title align-c" style="text-align: center; font-size: 14px; line-height: 18px; font-weight: 600; color: #1F2937; display: block; margin-top: 0px; margin-bottom: 12px;">
<?php echo esc_html( __( 'Top 5 Products by Revenue', 'easy-digital-downloads' ) ); ?>
</div>
<table class="top-products" style="border-collapse: collapse; width: 100%; font-size: 12px; line-height: 15px; color: #4B5563;" width="100%">
<tr>
<th style="font-weight: 600; border-bottom: 1px solid #E5E7EB; text-align: left; border-right: none; padding: 10px 0px; font-size: 12px; line-height: 15px;" align="left"><?php echo esc_html( __( 'Product', 'easy-digital-downloads' ) ); ?></th>
<th style="font-weight: 600; border-bottom: 1px solid #E5E7EB; border-right: none; padding: 10px 0px; font-size: 12px; line-height: 15px; text-align: right;" align="right"><?php echo esc_html( __( 'Gross Revenue', 'easy-digital-downloads' ) ); ?></th>
</tr>
<?php
$counter = 1;
foreach ( $dataset['top_selling_products'] as $product ) :
if ( ! $product->object instanceof \EDD_Download ) {
continue;
}
$title = $product->object->post_title;
$revenue = edd_currency_filter( edd_format_amount( $product->total ) );
?>
<tr>
<td style="font-size: 12px; color: #4B5563; font-weight: 400; text-align: left; padding: 9px 0px; border-bottom: 1px solid #F0F1F4;" align="left"><?php echo esc_html( $counter ); ?>. <?php echo esc_html( $title ); ?></td>
<td style="font-size: 12px; color: #4B5563; font-weight: 400; padding: 9px 0px; border-bottom: 1px solid #F0F1F4; text-align: right;" align="right"><?php echo esc_html( $revenue ); ?></td>
</tr>
<?php
$counter++;
endforeach;
?>
</table>
</div>
<a href="<?php echo esc_attr( $view_more_url ); ?>" style="color: #2794DA; margin-top: 15px; margin-bottom: 15px; font-weight: 400; font-size: 14px; text-decoration-line: underline; display: inline-block; text-decoration: none;">
<?php echo esc_html( __( 'View Full Report', 'easy-digital-downloads' ) ); ?>
</a>
</div>
</div>
<!-- /.content-box -->
</div>
<!-- /.email-container -->
<?php if ( ! empty( $blurb ) ) : ?>
<!-- PRO-TIP SECTION -->
<div class="email-container pro-tip-blurb" style="max-width: 450px; margin: 0 auto; font-family: -apple-system, BlinkMacSystemFont, avenir next, avenir, segoe ui, helvetica neue, helvetica, Cantarell, Ubuntu, roboto, noto, arial, sans-serif; color: #1F2937;">
<div class="content-box pro-tip-section" style="background: #FFF;">
<div class="content-holder pro-tip-section" style="padding: 0px 31px 27px 31px;">
<div class="pro-tip-holder" style="background: #F3F8FE; border-radius: 10px; padding: 32px 40px;">
<div class="pro-tip-section-title" style="font-weight: 600; font-size: 18px; line-height: 23px; color: #2794DA;">
<img src="<?php echo esc_url( EDD_PLUGIN_URL . '/assets/images/icons/icon-megaphone.png' ); ?>" alt="#" title="#" width="24" height="24" style="vertical-align: bottom; display: inline-block; margin-right: 4px;">
<?php echo esc_html( __( 'Pro-tip from our expert', 'easy-digital-downloads' ) ); ?>
</div>
<div class="pro-tip-title pull-down-12" style="margin-top: 12px; font-weight: 600; font-size: 20px; line-height: 26px; color: #1F2937;">
<?php echo esc_html( $blurb['headline'] ); ?>
</div>
<p class="bigger pull-down-8" style="margin: 0px; font-weight: 400; color: #4B5563; margin-top: 8px; font-size: 16px; line-height: 22px;">
<?php echo esc_html( $blurb['content'] ); ?>
</p>
<div class="pull-down-15" style="margin-top: 15px;">
<a href="<?php echo esc_attr( $blurb['button_link'] ); ?>" class="cta-btn" style="padding: 6px 15px; font-weight: 600; font-size: 14px; line-height: 20px; background: #2794DA; display: inline-block; text-decoration: none; color: white;">
<?php echo esc_html( $blurb['button_text'] ); ?>
</a>
</div>
</div>
</div>
</div>
</div>
<!-- /.pro-tip-blurb -->
<?php endif; ?>
</body>
</html>

View File

@ -0,0 +1,410 @@
<?php
/**
* Email Functions
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Email the download link(s) and payment confirmation to the buyer in a
* customizable Purchase Receipt
*
* @since 1.0
* @since 2.8 - Add parameters for EDD_Payment and EDD_Customer object.
*
* @param int $payment_id Payment ID
* @param bool $admin_notice Whether to send the admin email notification or not (default: true)
* @param EDD_Payment $payment Payment object for payment ID.
* @param EDD_Customer $customer Customer object for associated payment.
* @return bool Whether the email was sent successfully.
*/
function edd_email_purchase_receipt( $payment_id, $admin_notice = true, $to_email = '', $payment = null, $customer = null ) {
if ( is_null( $payment ) ) {
$payment = edd_get_payment( $payment_id );
}
$payment_data = $payment->get_meta( '_edd_payment_meta', true );
$from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
$from_name = apply_filters( 'edd_purchase_from_name', $from_name, $payment_id, $payment_data );
$from_email = edd_get_option( 'from_email', get_bloginfo( 'admin_email' ) );
$from_email = apply_filters( 'edd_purchase_from_address', $from_email, $payment_id, $payment_data );
if ( empty( $to_email ) ) {
$to_email = $payment->email;
}
$subject = edd_get_option( 'purchase_subject', __( 'Purchase Receipt', 'easy-digital-downloads' ) );
$subject = apply_filters( 'edd_purchase_subject', wp_strip_all_tags( $subject ), $payment_id );
$subject = wp_specialchars_decode( edd_do_email_tags( $subject, $payment_id ) );
$heading = edd_get_option( 'purchase_heading', __( 'Purchase Receipt', 'easy-digital-downloads' ) );
$heading = apply_filters( 'edd_purchase_heading', $heading, $payment_id, $payment_data );
$heading = edd_do_email_tags( $heading, $payment_id );
$attachments = apply_filters( 'edd_receipt_attachments', array(), $payment_id, $payment_data );
$message = edd_do_email_tags( edd_get_email_body_content( $payment_id, $payment_data ), $payment_id );
$emails = EDD()->emails;
$emails->__set( 'from_name', $from_name );
$emails->__set( 'from_email', $from_email );
$emails->__set( 'heading', $heading );
$headers = apply_filters( 'edd_receipt_headers', $emails->get_headers(), $payment_id, $payment_data );
$emails->__set( 'headers', $headers );
$sent = $emails->send( $to_email, $subject, $message, $attachments );
if ( $admin_notice && ! edd_admin_notices_disabled( $payment_id ) ) {
do_action( 'edd_admin_sale_notice', $payment_id, $payment_data );
}
return $sent;
}
/**
* Email the download link(s) and payment confirmation to the admin accounts for testing.
*
* @since 1.5
* @return void
*/
function edd_email_test_purchase_receipt() {
$from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
$from_name = apply_filters( 'edd_purchase_from_name', $from_name, 0, array() );
$from_email = edd_get_option( 'from_email', get_bloginfo( 'admin_email' ) );
$from_email = apply_filters( 'edd_test_purchase_from_address', $from_email, 0, array() );
$subject = edd_get_option( 'purchase_subject', __( 'Purchase Receipt', 'easy-digital-downloads' ) );
$subject = apply_filters( 'edd_purchase_subject', wp_strip_all_tags( $subject ), 0 );
$subject = wp_specialchars_decode( edd_do_email_tags( $subject, 0 ) );
$heading = edd_get_option( 'purchase_heading', __( 'Purchase Receipt', 'easy-digital-downloads' ) );
$heading = edd_email_preview_template_tags( apply_filters( 'edd_purchase_heading', $heading, 0, array() ) );
$attachments = apply_filters( 'edd_receipt_attachments', array(), 0, array() );
$message = edd_email_preview_template_tags( edd_get_email_body_content( 0, array() ), 0 );
$emails = EDD()->emails;
$emails->__set( 'from_name' , $from_name );
$emails->__set( 'from_email', $from_email );
$emails->__set( 'heading' , $heading );
$headers = apply_filters( 'edd_receipt_headers', $emails->get_headers(), 0, array() );
$emails->__set( 'headers', $headers );
$emails->send( edd_get_admin_notice_emails(), $subject, $message, $attachments );
}
/**
* Sends the Admin Sale Notification Email
*
* @since 1.4.2
* @param int $payment_id Payment ID (default: 0)
* @param array $payment_data Payment Meta and Data
* @return void
*/
function edd_admin_email_notice( $payment_id = 0, $payment_data = array() ) {
$payment_id = absint( $payment_id );
if( empty( $payment_id ) ) {
return;
}
if( ! edd_get_payment_by( 'id', $payment_id ) ) {
return;
}
$from_name = edd_get_option( 'from_name', wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ) );
$from_name = apply_filters( 'edd_purchase_from_name', $from_name, $payment_id, $payment_data );
$from_email = edd_get_option( 'from_email', get_bloginfo( 'admin_email' ) );
$from_email = apply_filters( 'edd_admin_sale_from_address', $from_email, $payment_id, $payment_data );
$subject = edd_get_option( 'sale_notification_subject', sprintf( __( 'New download purchase - Order #%1$s', 'easy-digital-downloads' ), $payment_id ) );
$subject = apply_filters( 'edd_admin_sale_notification_subject', wp_strip_all_tags( $subject ), $payment_id );
$subject = wp_specialchars_decode( edd_do_email_tags( $subject, $payment_id ) );
$heading = edd_get_option( 'sale_notification_heading', __( 'New Sale!', 'easy-digital-downloads' ) );
$heading = apply_filters( 'edd_admin_sale_notification_heading', $heading, $payment_id, $payment_data );
$heading = edd_do_email_tags( $heading, $payment_id );
$attachments = apply_filters( 'edd_admin_sale_notification_attachments', array(), $payment_id, $payment_data );
$message = edd_get_sale_notification_body_content( $payment_id, $payment_data );
$emails = EDD()->emails;
$emails->__set( 'from_name', $from_name );
$emails->__set( 'from_email', $from_email );
$emails->__set( 'heading', $heading );
$headers = apply_filters( 'edd_admin_sale_notification_headers', $emails->get_headers(), $payment_id, $payment_data );
$emails->__set( 'headers', $headers );
$emails->send( edd_get_admin_notice_emails(), $subject, $message, $attachments );
}
add_action( 'edd_admin_sale_notice', 'edd_admin_email_notice', 10, 2 );
/**
* Retrieves the emails for which admin notifications are sent to (these can be
* changed in the EDD Settings)
*
* @since 1.0
* @return mixed
*/
function edd_get_admin_notice_emails() {
$emails = edd_get_option( 'admin_notice_emails', false );
$emails = strlen( trim( $emails ) ) > 0 ? $emails : get_bloginfo( 'admin_email' );
$emails = array_map( 'trim', explode( "\n", $emails ) );
return apply_filters( 'edd_admin_notice_emails', $emails );
}
/**
* Checks whether admin sale notices are disabled
*
* @since 1.5.2
*
* @param int $payment_id
* @return mixed
*/
function edd_admin_notices_disabled( $payment_id = 0 ) {
$ret = edd_get_option( 'disable_admin_notices', false );
return (bool) apply_filters( 'edd_admin_notices_disabled', $ret, $payment_id );
}
/**
* Get sale notification email text
*
* Returns the stored email text if available, the standard email text if not
*
* @since 1.7
* @author Daniel J Griffiths
* @return string $message
*/
function edd_get_default_sale_notification_email() {
$default_email_body = __( 'Hello', 'easy-digital-downloads' ) . "\n\n" . sprintf( __( 'A %s purchase has been made', 'easy-digital-downloads' ), edd_get_label_plural() ) . ".\n\n";
$default_email_body .= sprintf( __( '%s sold:', 'easy-digital-downloads' ), edd_get_label_plural() ) . "\n\n";
$default_email_body .= '{download_list}' . "\n\n";
$default_email_body .= __( 'Purchased by: ', 'easy-digital-downloads' ) . ' {name}' . "\n";
$default_email_body .= __( 'Amount: ', 'easy-digital-downloads' ) . ' {price}' . "\n";
$default_email_body .= __( 'Payment Method: ', 'easy-digital-downloads' ) . ' {payment_method}' . "\n\n";
$default_email_body .= __( 'Thank you', 'easy-digital-downloads' );
$message = edd_get_option( 'sale_notification', false );
$message = ! empty( $message ) ? $message : $default_email_body;
return $message;
}
/**
* Get various correctly formatted names used in emails
*
* @since 1.9
* @param $user_info
* @param $payment EDD_Payment for getting the names
*
* @return array $email_names
*/
function edd_get_email_names( $user_info, $payment = false ) {
$email_names = array();
$email_names['fullname'] = '';
if ( $payment instanceof EDD_Payment ) {
$email_names['name'] = $payment->email;
$email_names['username'] = $payment->email;
if ( $payment->user_id > 0 ) {
$user_data = get_userdata( $payment->user_id );
$email_names['name'] = $payment->first_name;
$email_names['fullname'] = trim( $payment->first_name . ' ' . $payment->last_name );
if ( ! empty( $user_data->user_login ) ) {
$email_names['username'] = $user_data->user_login;
}
} elseif ( ! empty( $payment->first_name ) ) {
$email_names['name'] = $payment->first_name;
$email_names['fullname'] = trim( $payment->first_name . ' ' . $payment->last_name );
$email_names['username'] = $payment->first_name;
}
} else {
if ( is_serialized( $user_info ) ) {
preg_match( '/[oO]\s*:\s*\d+\s*:\s*"\s*(?!(?i)(stdClass))/', $user_info, $matches );
if ( ! empty( $matches ) ) {
return array(
'name' => '',
'fullname' => '',
'username' => '',
);
} else {
$user_info = maybe_unserialize( $user_info );
}
}
if ( isset( $user_info['id'] ) && $user_info['id'] > 0 && isset( $user_info['first_name'] ) ) {
$user_data = get_userdata( $user_info['id'] );
$email_names['name'] = $user_info['first_name'];
$email_names['fullname'] = $user_info['first_name'] . ' ' . $user_info['last_name'];
$email_names['username'] = $user_data->user_login;
} elseif ( isset( $user_info['first_name'] ) ) {
$email_names['name'] = $user_info['first_name'];
$email_names['fullname'] = $user_info['first_name'] . ' ' . $user_info['last_name'];
$email_names['username'] = $user_info['first_name'];
} else {
$email_names['name'] = $user_info['email'];
$email_names['username'] = $user_info['email'];
}
}
return $email_names;
}
/**
* Handle installation and connection for Recapture via ajax
*
* @since 2.10.2
*/
function edd_recapture_remote_install_handler () {
if ( ! current_user_can( 'manage_shop_settings' ) || ! current_user_can( 'install_plugins' ) ) {
wp_send_json_error( array(
'error' => __( 'You do not have permission to do this.', 'easy-digital-downloads' )
) );
}
include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
include_once ABSPATH . 'wp-admin/includes/file.php';
include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$plugins = get_plugins();
if( ! array_key_exists( 'recapture-for-edd/recapture.php', $plugins ) ) {
/*
* Use the WordPress Plugins API to get the plugin download link.
*/
$api = plugins_api( 'plugin_information', array(
'slug' => 'recapture-for-edd',
) );
if ( is_wp_error( $api ) ) {
wp_send_json_error( array(
'error' => $api->get_error_message(),
'debug' => $api
) );
}
/*
* Use the AJAX Upgrader skin to quietly install the plugin.
*/
$upgrader = new Plugin_Upgrader( new WP_Ajax_Upgrader_Skin() );
$install = $upgrader->install( $api->download_link );
if ( is_wp_error( $install ) ) {
wp_send_json_error( array(
'error' => $install->get_error_message(),
'debug' => $api
) );
}
$activated = activate_plugin( $upgrader->plugin_info() );
} else {
$activated = activate_plugin( 'recapture-for-edd/recapture.php' );
}
/*
* Final check to see if Recapture is available.
*/
if ( is_wp_error( $activated ) ) {
wp_send_json_error( array(
'error' => __( 'Something went wrong. Recapture for EDD was not installed correctly.', 'easy-digital-downloads' )
) );
}
wp_send_json_success();
}
add_action( 'wp_ajax_edd_recapture_remote_install', 'edd_recapture_remote_install_handler' );
/**
* Maybe adds a notice to abandoned payments if Recapture isn't installed.
*
* @since 2.10.2
*
* @param int $payment_id The ID of the abandoned payment, for which a Recapture notice is being thrown.
*/
function maybe_add_recapture_notice_to_abandoned_payment( $payment_id ) {
if ( ! class_exists( 'Recapture' )
&& 'abandoned' === edd_get_payment_status( $payment_id )
&& ! get_user_meta( get_current_user_id(), '_edd_try_recapture_dismissed', true )
) {
?>
<div class="notice notice-warning recapture-notice">
<p>
<?php
echo wp_kses_post(
sprintf(
/* Translators: %1$s - <strong> tag, %2$s - </strong> tag, %3$s - <a> tag, %4$s - </a> tag */
__( '%1$sRecover abandoned purchases like this one.%2$s %3$sTry Recapture for free%4$s.', 'easy-digital-downloads' ),
'<strong>',
'</strong>',
'<a href="https://recapture.io/abandoned-carts-easy-digital-downloads" rel="noopener" target="_blank">',
'</a>'
)
);
?>
</p>
<?php
echo wp_kses_post(
sprintf(
/* Translators: %1$s - Opening anchor tag, %2$s - The url to dismiss the ajax notice, %3$s - Complete the opening of the anchor tag, %4$s - Open span tag, %4$s - Close span tag */
__( '%1$s %2$s %3$s %4$s Dismiss this notice. %5$s', 'easy-digital-downloads' ),
'<a href="',
esc_url(
wp_nonce_url(
add_query_arg(
array(
'edd_action' => 'dismiss_notices',
'edd_notice' => 'try_recapture',
)
),
'edd_notice_nonce'
)
),
'" type="button" class="notice-dismiss">',
'<span class="screen-reader-text">',
'</span>
</a>'
)
);
?>
</div>
<?php
}
}
add_action( 'edd_view_order_details_before', 'maybe_add_recapture_notice_to_abandoned_payment' );

View File

@ -0,0 +1,139 @@
<?php
/**
* Add a button to wp_editor() instances to allow easier tag insertion.
*
* @package EDD
* @subpackage Email
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Get registered emails.
*
* This assumes emails are "registered" by using a section in the Emails tab.
*
* @since 3.0
*
* @return array $emails Registered emails.
*/
function edd_email_tags_inserter_get_registered_emails() {
$settings = edd_get_registered_settings();
$emails = $settings['emails'];
unset( $emails['main'] );
return array_keys( $emails );
}
/**
* Wait until the admin has loaded (so edd_get_registered_settings() works)
* and hook in to WordPress for each registered email.
*
* @since 3.0
*/
function edd_email_tags_inserter_register() {
foreach ( edd_email_tags_inserter_get_registered_emails() as $email ) {
// Add Thickbox button.
add_action( 'edd_settings_tab_top_emails_' . $email, 'edd_email_tags_inserter_media_button' );
// Output Thickbox content.
add_action( 'edd_settings_tab_top_emails_' . $email, 'edd_email_tags_inserter_thickbox_content' );
// Enqueue scripts.
add_action( 'edd_settings_tab_top_emails_' . $email, 'edd_email_tags_inserter_enqueue_scripts' );
}
}
add_action( 'admin_menu', 'edd_email_tags_inserter_register' );
/**
* Wait until `media_buttons` action is called.
*
* @see edd_email_tags_inserter_media_button_output()
*
* @since 3.0
*/
function edd_email_tags_inserter_media_button() {
add_action( 'media_buttons', 'edd_email_tags_inserter_media_button_output' );
}
/**
* Adds an 'Insert Marker' button above the TinyMCE Editor on email-related
* `wp_editor()` instances.
*
* @since 3.0
*/
function edd_email_tags_inserter_media_button_output() {
?>
<a href="#TB_inline?width=640&inlineId=edd-insert-email-tag" class="edd-email-tags-inserter thickbox button edd-thickbox" style="padding-left: 0.4em;">
<span class="wp-media-buttons-icon dashicons dashicons-editor-code"></span>
<?php esc_html_e( 'Insert Marker', 'easy-digital-downloads' ); ?>
</a>
<?php
}
/**
* Enqueue scripts for clicking a tag inside of Thickbox.
*
* @since 3.0
*/
function edd_email_tags_inserter_enqueue_scripts() {
wp_enqueue_style( 'edd-admin-email-tags' );
wp_enqueue_script( 'edd-admin-email-tags' ) ;
// Send information about tags to script.
$items = array();
$tags = edd_get_email_tags();
foreach ( $tags as $tag ) {
$items[] = array(
'title' => $tag['label'] ? $tag['label'] : $tag['tag'],
'tag' => $tag['tag'],
'keywords' => array_merge(
explode( ' ', $tag['description'] ),
array( $tag['tag'] )
),
);
}
wp_localize_script(
'edd-admin-email-tags',
'eddEmailTagsInserter',
array(
'items' => $items,
)
);
}
/**
* Output Thickbox content.
*
* @since 3.0
*/
function edd_email_tags_inserter_thickbox_content() {
$tags = edd_get_email_tags();
?>
<div id="edd-insert-email-tag" style="display: none;">
<div class="edd-email-tags-filter">
<input type="search" class="edd-email-tags-filter-search" placeholder="<?php echo esc_attr( __( 'Find a tag...', 'easy-digital-downloads' ) ); ?>" />
</div>
<ul class="edd-email-tags-list">
<?php foreach ( $tags as $tag ) : ?>
<li id="<?php echo esc_attr( $tag['tag'] ); ?>" data-tag="<?php echo esc_attr( $tag['tag'] ); ?>" class="edd-email-tags-list-item">
<button class="edd-email-tags-list-button" data-to_insert="{<?php echo esc_attr( $tag['tag'] ); ?>}">
<strong><?php echo esc_html( $tag['label'] ); ?></strong><code><?php echo '{' . esc_html( $tag['tag'] ) . '}'; ?></code>
<span><?php echo esc_html( $tag['description'] ); ?></span>
</button>
</li>
<?php endforeach; ?>
</ul>
</div>
<?php
}

View File

@ -0,0 +1,843 @@
<?php
/**
* Email template tag helpers.
*
* Email tags are wrapped in { }
*
* A few examples:
*
* {download_list}
* {name}
* {sitename}
*
*
* To replace tags in content, use: edd_do_email_tags( $content, payment_id );
*
* To add tags, use: edd_add_email_tag( $tag, $description, $func, $label ). Be sure to wrap edd_add_email_tag()
* in a function hooked to the 'edd_add_email_tags' action
*
* @package EDD
* @subpackage Email
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Add an email tag.
*
* @since 1.9
* @since 3.0 Added $label parameter.
*
* @param string $tag Email tag to be replace in email.
* @param string $description Tag description.
* @param string $func Callback function to run when email tag is found.
* @param string $label Tag label.
*/
function edd_add_email_tag( $tag = '', $description = '', $func = '', $label = '' ) {
EDD()->email_tags->add( $tag, $description, $func, $label );
}
/**
* Remove an email tag
*
* @since 1.9
*
* @param string $tag Email tag to remove hook from
*/
function edd_remove_email_tag( $tag ) {
EDD()->email_tags->remove( $tag );
}
/**
* Check if $tag is a registered email tag
*
* @since 1.9
*
* @param string $tag Email tag that will be searched
*
* @return bool
*/
function edd_email_tag_exists( $tag ) {
return EDD()->email_tags->email_tag_exists( $tag );
}
/**
* Get all email tags
*
* @since 1.9
*
* @return array
*/
function edd_get_email_tags() {
return EDD()->email_tags->get_tags();
}
/**
* Get a formatted HTML list of all available email tags.
*
* @since 1.9
*
* @return string
*/
function edd_get_emails_tags_list() {
// Begin with empty list.
$list = '';
// Get all tags.
$email_tags = (array) edd_get_email_tags();
// Check.
if ( count( $email_tags ) > 0 ) {
// Loop.
foreach ( $email_tags as $email_tag ) {
// Add email tag to list.
$list .= '<code>{' . $email_tag['tag'] . '}</code> - ' . $email_tag['description'] . '<br/>';
}
}
// Return the list.
return $list;
}
/**
* Search content for email tags and filter email tags through their hooks.
*
* @since 1.9
* @since 3.0 Renamed `$payment_id` parameter to `$order_id`.
* Set default value of `$order_id` to 0.
* Set default value of `$content` to empty string.
*
* @param string $content Content to search for email tags.
* @param int $order_id Order ID.
*
* @return string Content with email tags filtered out.
*/
function edd_do_email_tags( $content = '', $order_id = 0 ) {
// Replace all tags.
$content = EDD()->email_tags->do_tags( $content, $order_id );
// Maintaining backwards compatibility.
$content = apply_filters( 'edd_email_template_tags', $content, edd_get_payment_meta( $order_id ), $order_id );
// Return content.
return $content;
}
/**
* Load email tags.
*
* @since 1.9
*/
function edd_load_email_tags() {
do_action( 'edd_add_email_tags' );
}
add_action( 'init', 'edd_load_email_tags', -999 );
/**
* Add default EDD email template tags.
*
* @since 1.9
*/
function edd_setup_email_tags() {
$email_tags = array(
array(
'tag' => 'download_list',
'label' => __( 'Download List', 'easy-digital-downloads' ),
'description' => __( 'A list of download links for each download purchased.', 'easy-digital-downloads' ),
'function' => 'text/html' === EDD()->emails->get_content_type()
? 'edd_email_tag_download_list'
: 'edd_email_tag_download_list_plain',
),
array(
'tag' => 'file_urls',
'label' => __( 'File URLs', 'easy-digital-downloads' ),
'description' => __( 'A plain-text list of download URLs for each download purchased.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_file_urls',
),
array(
'tag' => 'name',
'label' => __( 'First Name', 'easy-digital-downloads' ),
'description' => __( "The buyer's first name.", 'easy-digital-downloads' ),
'function' => 'edd_email_tag_first_name',
),
array(
'tag' => 'fullname',
'label' => __( 'Full Name', 'easy-digital-downloads' ),
'description' => __( "The buyer's full name: first and last.", 'easy-digital-downloads' ),
'function' => 'edd_email_tag_fullname',
),
array(
'tag' => 'username',
'label' => __( 'Username', 'easy-digital-downloads' ),
'description' => __( "The buyer's user name on the site, if they registered an account.", 'easy-digital-downloads' ),
'function' => 'edd_email_tag_username',
),
array(
'tag' => 'user_email',
'label' => __( 'Email', 'easy-digital-downloads' ),
'description' => __( "The buyer's email address.", 'easy-digital-downloads' ),
'function' => 'edd_email_tag_user_email',
),
array(
'tag' => 'billing_address',
'label' => __( 'Billing Address', 'easy-digital-downloads' ),
'description' => __( "The buyer's billing address.", 'easy-digital-downloads' ),
'function' => 'edd_email_tag_billing_address',
),
array(
'tag' => 'date',
'label' => __( 'Purchase Date', 'easy-digital-downloads' ),
'description' => __( 'The date of the purchase.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_date',
),
array(
'tag' => 'subtotal',
'label' => __( 'Subtotal', 'easy-digital-downloads' ),
'description' => __( 'The price of the purchase before taxes.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_subtotal',
),
array(
'tag' => 'tax',
'label' => __( 'Tax', 'easy-digital-downloads' ),
'description' => __( 'The taxed amount of the purchase', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_tax',
),
array(
'tag' => 'price',
'label' => __( 'Price', 'easy-digital-downloads' ),
'description' => __( 'The total price of the purchase', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_price',
),
array(
'tag' => 'payment_id',
'label' => __( 'Payment ID', 'easy-digital-downloads' ),
'description' => __( 'The unique identifier for this purchase.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_payment_id',
),
array(
'tag' => 'receipt_id',
'label' => __( 'Receipt ID', 'easy-digital-downloads' ),
'description' => __( 'The unique identifier for the receipt of this purchase.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_receipt_id',
),
array(
'tag' => 'payment_method',
'label' => __( 'Payment Method', 'easy-digital-downloads' ),
'description' => __( 'The method of payment used for this purchase.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_payment_method',
),
array(
'tag' => 'sitename',
'label' => __( 'Site Name', 'easy-digital-downloads' ),
'description' => __( 'Your site name.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_sitename',
),
array(
'tag' => 'receipt',
'label' => __( 'Receipt', 'easy-digital-downloads' ),
'description' => __( 'Links to the EDD success page with the text "View Receipt".', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_receipt',
),
array(
'tag' => 'receipt_link',
'label' => __( 'Receipt Link', 'easy-digital-downloads' ),
'description' => __( 'Adds a link so users can view their receipt directly on a simplified page on your site if they are unable to view it in the browser correctly.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_receipt_link',
),
array(
'tag' => 'discount_codes',
'label' => __( 'Discount Codes', 'easy-digital-downloads' ),
'description' => __( 'Adds a list of any discount codes applied to this purchase.', 'easy-digital-downloads' ),
'function' => 'edd_email_tag_discount_codes',
),
array(
'tag' => 'ip_address',
'label' => __( 'IP Address', 'easy-digital-downloads' ),
'description' => __( "The buyer's IP Address.", 'easy-digital-downloads' ),
'function' => 'edd_email_tag_ip_address',
),
);
// Apply edd_email_tags filter
$email_tags = apply_filters( 'edd_email_tags', $email_tags );
// Add email tags
foreach ( $email_tags as $email_tag ) {
$label = isset( $email_tag['label'] ) ? $email_tag['label'] : '';
edd_add_email_tag( $email_tag['tag'], $email_tag['description'], $email_tag['function'], $label );
}
}
add_action( 'edd_add_email_tags', 'edd_setup_email_tags' );
/**
* Email template tag: download_list
* A list of download links for each download purchased
*
* @param int $payment_id
*
* @return string download_list
*/
function edd_email_tag_download_list( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$order = edd_get_order( $payment_id );
if ( ! $order ) {
return '';
}
$download_list = '<ul>';
$cart_items = $payment->cart_details;
$email = $payment->email;
$needs_notes = array();
if ( $order->get_items() ) {
$show_names = apply_filters( 'edd_email_show_names', true );
$show_links = apply_filters( 'edd_email_show_links', true );
foreach ( $order->get_items() as $item ) {
if ( edd_use_skus() ) {
$sku = edd_get_download_sku( $item->product_id );
}
if ( edd_item_quantities_enabled() ) {
$quantity = $item->quantity;
}
if ( $show_names ) {
$title = '<strong>' . $item->product_name . '</strong>';
if ( ! empty( $quantity ) && $quantity > 1 ) {
$title .= "&nbsp;&ndash;&nbsp;" . __( 'Quantity', 'easy-digital-downloads' ) . ': ' . $quantity;
}
if ( ! empty( $sku ) ) {
$title .= "&nbsp;&ndash;&nbsp;" . __( 'SKU', 'easy-digital-downloads' ) . ': ' . $sku;
}
$download_list .= '<li>' . apply_filters( 'edd_email_receipt_download_title', $title, $cart_items[ $item->cart_index ], $item->price_id, $payment_id ) . '<br/>';
}
$files = edd_get_download_files( $item->product_id, $item->price_id );
if ( ! empty( $files ) ) {
foreach ( $files as $filekey => $file ) {
if ( $show_links ) {
$download_list .= '<div>';
$file_url = edd_get_download_file_url( $order->payment_key, $email, $filekey, $item->product_id, $item->price_id );
$download_list .= '<a href="' . esc_url_raw( $file_url ) . '">' . edd_get_file_name( $file ) . '</a>';
$download_list .= '</div>';
} else {
$download_list .= '<div>';
$download_list .= edd_get_file_name( $file );
$download_list .= '</div>';
}
}
} elseif ( edd_is_bundled_product( $item->product_id ) ) {
$bundled_products = apply_filters( 'edd_email_tag_bundled_products', edd_get_bundled_products( $item->product_id, $item->price_id ), $item, $payment_id, 'download_list' );
foreach ( $bundled_products as $bundle_item ) {
$download_list .= '<div class="edd_bundled_product"><strong>' . get_the_title( $bundle_item ) . '</strong></div>';
$bundle_item_id = edd_get_bundle_item_id( $bundle_item );
$bundle_item_price_id = edd_get_bundle_item_price_id( $bundle_item );
$download_files = edd_get_download_files( $bundle_item_id, $bundle_item_price_id );
foreach ( $download_files as $filekey => $file ) {
if ( $show_links ) {
$download_list .= '<div>';
$file_url = edd_get_download_file_url( $order->payment_key, $email, $filekey, $bundle_item_id, $bundle_item_price_id );
$download_list .= '<a href="' . esc_url( $file_url ) . '">' . edd_get_file_name( $file ) . '</a>';
$download_list .= '</div>';
} else {
$download_list .= '<div>';
$download_list .= edd_get_file_name( $file );
$download_list .= '</div>';
}
}
}
} else {
$no_downloads_message = apply_filters( 'edd_receipt_no_files_found_text', __( 'No downloadable files found.', 'easy-digital-downloads' ), $item->product_id );
$no_downloads_message = apply_filters( 'edd_email_receipt_no_downloads_message', $no_downloads_message, $item->product_id, $item->price_id, $payment_id );
if ( ! empty( $no_downloads_message ) ){
$download_list .= '<div>';
$download_list .= $no_downloads_message;
$download_list .= '</div>';
}
}
if ( ! array_key_exists( $item->product_id, $needs_notes ) ) {
$item_notes = edd_get_product_notes( $item->product_id );
if ( $item_notes ) {
$needs_notes[ $item->product_id ] = array(
'item_name' => get_the_title( $item->product_id ),
'item_notes' => $item_notes,
);
}
}
if ( $show_names ) {
$download_list .= '</li>';
}
}
}
$download_list .= '</ul>';
// Remove any empty values.
$needs_notes = array_filter( $needs_notes );
if ( ! empty( $needs_notes ) ) {
$download_list .= __( 'Additional information about your purchase:', 'easy-digital-downloads' );
$download_list .= '<ul>';
foreach ( $needs_notes as $note ) {
$download_list .= '<li>' . $note['item_name'] . "\n" . '<small>' . $note['item_notes'] . '</small></li>';
}
$download_list .= '</ul>';
}
return $download_list;
}
/**
* Email template tag: download_list
* A list of download links for each download purchased in plaintext
*
* @since 2.1.1
* @param int $payment_id
*
* @return string download_list
*/
function edd_email_tag_download_list_plain( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$order = edd_get_order( $payment_id );
$payment_data = $payment->get_meta();
$cart_items = $payment->cart_details;
$email = $payment->email;
$download_list = '';
if ( $order->get_items() ) {
$show_names = apply_filters( 'edd_email_show_names', true );
$show_links = apply_filters( 'edd_email_show_links', true );
foreach ( $order->get_items() as $item ) {
if ( edd_use_skus() ) {
$sku = edd_get_download_sku( $item->product_id );
}
if ( edd_item_quantities_enabled() ) {
$quantity = $item->quantity;
}
if ( $show_names ) {
$title = $item->product_name;
if ( ! empty( $quantity ) && $quantity > 1 ) {
$title .= __( 'Quantity', 'easy-digital-downloads' ) . ': ' . $quantity;
}
if ( ! empty( $sku ) ) {
$title .= __( 'SKU', 'easy-digital-downloads' ) . ': ' . $sku;
}
$download_list .= "\n";
$download_list .= apply_filters( 'edd_email_receipt_download_title', $title, $cart_items[ $item->cart_index ], $item->price_id, $payment_id ) . "\n";
}
$files = edd_get_download_files( $item->product_id, $item->price_id );
if ( ! empty( $files ) ) {
foreach ( $files as $filekey => $file ) {
if( $show_links ) {
$download_list .= "\n";
$file_url = edd_get_download_file_url( $payment_data['key'], $email, $filekey, $item->product_id, $item->price_id );
$download_list .= edd_get_file_name( $file ) . ': ' . $file_url . "\n";
} else {
$download_list .= "\n";
$download_list .= edd_get_file_name( $file ) . "\n";
}
}
} elseif ( edd_is_bundled_product( $item->product_id ) ) {
$bundled_products = apply_filters( 'edd_email_tag_bundled_products', edd_get_bundled_products( $item->product_id ), $cart_items[ $item->cart_index ], $payment_id, 'download_list' );
foreach ( $bundled_products as $bundle_item ) {
$download_list .= '<div class="edd_bundled_product"><strong>' . get_the_title( $bundle_item ) . '</strong></div>';
$files = edd_get_download_files( $bundle_item );
foreach ( $files as $filekey => $file ) {
if( $show_links ) {
$file_url = edd_get_download_file_url( $payment_data['key'], $email, $filekey, $bundle_item, $item->price_id );
$download_list .= edd_get_file_name( $file ) . ': ' . $file_url . "\n";
} else {
$download_list .= edd_get_file_name( $file ) . "\n";
}
}
}
}
if ( '' != edd_get_product_notes( $item->product_id ) ) {
$download_list .= "\n";
$download_list .= edd_get_product_notes( $item->product_id ) . "\n";
}
}
}
return $download_list;
}
/**
* Email template tag: file_urls
* A plain-text list of download URLs for each download purchased
*
* @param int $payment_id
*
* @return string $file_urls
*/
function edd_email_tag_file_urls( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$payment_data = $payment->get_meta();
$file_urls = '';
$cart_items = $payment->cart_details;
$email = $payment->email;
foreach ( $cart_items as $item ) {
$price_id = edd_get_cart_item_price_id( $item );
$files = edd_get_download_files( $item['id'], $price_id );
if ( $files ) {
foreach ( $files as $filekey => $file ) {
$file_url = edd_get_download_file_url( $payment_data['key'], $email, $filekey, $item['id'], $price_id );
$file_urls .= esc_html( $file_url ) . '<br/>';
}
}
elseif ( edd_is_bundled_product( $item['id'] ) ) {
$bundled_products = apply_filters( 'edd_email_tag_bundled_products', edd_get_bundled_products( $item['id'] ), $item, $payment_id, 'file_urls' );
foreach ( $bundled_products as $bundle_item ) {
$files = edd_get_download_files( $bundle_item );
foreach ( $files as $filekey => $file ) {
$file_url = edd_get_download_file_url( $payment_data['key'], $email, $filekey, $bundle_item, $price_id );
$file_urls .= esc_html( $file_url ) . '<br/>';
}
}
}
}
return $file_urls;
}
/**
* Email template tag: name
* The buyer's first name
*
* @param int $payment_id
*
* @return string name
*/
function edd_email_tag_first_name( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$user_info = $payment->user_info;
if( empty( $user_info) ) {
return '';
}
$email_name = edd_get_email_names( $user_info, $payment );
return $email_name['name'];
}
/**
* Email template tag: fullname
* The buyer's full name, first and last
*
* @param int $payment_id
*
* @return string fullname
*/
function edd_email_tag_fullname( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$user_info = $payment->user_info;
if( empty( $user_info ) ) {
return '';
}
$email_name = edd_get_email_names( $user_info, $payment );
return $email_name['fullname'];
}
/**
* Email template tag: username
* The buyer's user name on the site, if they registered an account
*
* @param int $payment_id
*
* @return string username
*/
function edd_email_tag_username( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$user_info = $payment->user_info;
if( empty( $user_info ) ) {
return '';
}
$email_name = edd_get_email_names( $user_info, $payment );
return $email_name['username'];
}
/**
* Email template tag: user_email
* The buyer's email address
*
* @param int $payment_id
*
* @return string user_email
*/
function edd_email_tag_user_email( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
return $payment->email;
}
/**
* Email template tag: billing_address
* The buyer's billing address
*
* @param int $payment_id
*
* @return string billing_address
*/
function edd_email_tag_billing_address( $payment_id ) {
$user_info = edd_get_payment_meta_user_info( $payment_id );
$user_address = ! empty( $user_info['address'] ) ? $user_info['address'] : array( 'line1' => '', 'line2' => '', 'city' => '', 'country' => '', 'state' => '', 'zip' => '' );
$return = $user_address['line1'] . "\n";
if( ! empty( $user_address['line2'] ) ) {
$return .= $user_address['line2'] . "\n";
}
$return .= $user_address['city'] . ' ' . $user_address['zip'] . ' ' . $user_address['state'] . "\n";
$return .= $user_address['country'];
return $return;
}
/**
* Email template tag: date
* Date of purchase
*
* @param int $payment_id
*
* @return string date
*/
function edd_email_tag_date( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
return date_i18n( get_option( 'date_format' ), strtotime( $payment->date ) );
}
/**
* Email template tag: subtotal
* Price of purchase before taxes
*
* @param int $payment_id
*
* @return string subtotal
*/
function edd_email_tag_subtotal( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$subtotal = edd_currency_filter( edd_format_amount( $payment->subtotal ), $payment->currency );
return html_entity_decode( $subtotal, ENT_COMPAT, 'UTF-8' );
}
/**
* Email template tag: tax
* The taxed amount of the purchase
*
* @param int $payment_id
*
* @return string tax
*/
function edd_email_tag_tax( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$tax = edd_currency_filter( edd_format_amount( $payment->tax ), $payment->currency );
return html_entity_decode( $tax, ENT_COMPAT, 'UTF-8' );
}
/**
* Email template tag: price
* The total price of the purchase
*
* @param int $payment_id
*
* @return string price
*/
function edd_email_tag_price( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
$price = edd_currency_filter( edd_format_amount( $payment->total ), $payment->currency );
return html_entity_decode( $price, ENT_COMPAT, 'UTF-8' );
}
/**
* Email template tag: payment_id
* The unique ID number for this purchase
*
* @param int $payment_id
*
* @return int payment_id
*/
function edd_email_tag_payment_id( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
return $payment->number;
}
/**
* Email template tag: receipt_id
* The unique ID number for this purchase receipt
*
* @param int $payment_id
*
* @return string receipt_id
*/
function edd_email_tag_receipt_id( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
return $payment->key;
}
/**
* Email template tag: payment_method
* The method of payment used for this purchase
*
* @param int $payment_id
*
* @return string gateway
*/
function edd_email_tag_payment_method( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
return edd_get_gateway_checkout_label( $payment->gateway );
}
/**
* Email template tag: sitename
* Your site name
*
* @param int $payment_id
*
* @return string sitename
*/
function edd_email_tag_sitename( $payment_id ) {
return wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES );
}
/**
* Email template tag: receipt
*
* Adds a link to the user's receipt page on the website.
*
* @param [type] $order_id
* @return void
*/
function edd_email_tag_receipt( $order_id ) {
return sprintf(
'<a href="%s">%s</a>',
esc_url( edd_get_receipt_page_uri( $order_id ) ),
__( 'View Receipt', 'easy-digital-downloads' )
);
}
/**
* Email template tag: receipt_link
* Adds a link so users can view their receipt directly on your website if they are unable to view it in the browser correctly
*
* @param $payment_id int
*
* @return string receipt_link
*/
function edd_email_tag_receipt_link( $payment_id ) {
$receipt_url = esc_url(
add_query_arg(
array(
'payment_key' => urlencode( edd_get_payment_key( $payment_id ) ),
'edd_action' => 'view_receipt',
),
home_url()
)
);
$formatted = sprintf( __( '%1$sView it in your browser %2$s', 'easy-digital-downloads' ), '<a href="' . esc_url_raw( $receipt_url ) . '">', '&raquo;</a>' );
if ( edd_get_option( 'email_template' ) !== 'none' ) {
return $formatted;
} else {
return $receipt_url;
}
}
/**
* Email template tag: discount_codes
* Adds a list of any discount codes applied to this purchase
*
* @since 2.0
* @param int $payment_id
* @return string $discount_codes
*/
function edd_email_tag_discount_codes( $payment_id ) {
$user_info = edd_get_payment_meta_user_info( $payment_id );
$discount_codes = '';
if( isset( $user_info['discount'] ) && $user_info['discount'] !== 'none' ) {
$discount_codes = $user_info['discount'];
}
return $discount_codes;
}
/**
* Email template tag: IP address
* IP address of the customer
*
* @since 2.3
* @param int $payment_id
* @return string IP address
*/
function edd_email_tag_ip_address( $payment_id ) {
$payment = new EDD_Payment( $payment_id );
return $payment->ip;
}

View File

@ -0,0 +1,306 @@
<?php
/**
* Email Template
*
* @package EDD
* @subpackage Emails
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Gets all the email templates that have been registerd. The list is extendable
* and more templates can be added.
*
* As of 2.0, this is simply a wrapper to EDD_Email_Templates->get_templates()
*
* @since 1.0.8.2
* @return array $templates All the registered email templates
*/
function edd_get_email_templates() {
$templates = new EDD_Emails;
return $templates->get_templates();
}
/**
* Email Template Tags
*
* @since 1.0
*
* @param string $message Message with the template tags
* @param array $payment_data Payment Data
* @param int $payment_id Payment ID
* @param bool $admin_notice Whether or not this is a notification email
*
* @return string $message Fully formatted message
*/
function edd_email_template_tags( $message, $payment_data, $payment_id, $admin_notice = false ) {
return edd_do_email_tags( $message, $payment_id );
}
/**
* Email Preview Template Tags
*
* @since 1.0
* @param string $message Email message with template tags
* @return string $message Fully formatted message
*/
function edd_email_preview_template_tags( $message ) {
$download_list = '<ul>';
$download_list .= '<li>' . __( 'Sample Product Title', 'easy-digital-downloads' ) . '<br />';
$download_list .= '<div>';
$download_list .= '<a href="#">' . __( 'Sample Download File Name', 'easy-digital-downloads' ) . '</a> - <small>' . __( 'Optional notes about this download.', 'easy-digital-downloads' ) . '</small>';
$download_list .= '</div>';
$download_list .= '</li>';
$download_list .= '</ul>';
$file_urls = esc_html( trailingslashit( get_site_url() ) . 'test.zip?test=key&key=123' );
$price = edd_currency_filter( edd_format_amount( 10.50 ) );
$gateway = edd_get_gateway_admin_label( edd_get_default_gateway() );
$receipt_id = strtolower( md5( uniqid() ) );
$notes = __( 'These are some sample notes added to a product.', 'easy-digital-downloads' );
$tax = edd_currency_filter( edd_format_amount( 1.00 ) );
$sub_total = edd_currency_filter( edd_format_amount( 9.50 ) );
$payment_id = rand(1, 100);
$user = wp_get_current_user();
$message = str_replace( '{download_list}', $download_list, $message );
$message = str_replace( '{file_urls}', $file_urls, $message );
$message = str_replace( '{name}', $user->display_name, $message );
$message = str_replace( '{fullname}', $user->display_name, $message );
$message = str_replace( '{username}', $user->user_login, $message );
$message = str_replace( '{date}', edd_date_i18n( current_time( 'timestamp' ) ), $message );
$message = str_replace( '{subtotal}', $sub_total, $message );
$message = str_replace( '{tax}', $tax, $message );
$message = str_replace( '{price}', $price, $message );
$message = str_replace( '{receipt_id}', $receipt_id, $message );
$message = str_replace( '{payment_method}', $gateway, $message );
$message = str_replace( '{sitename}', get_bloginfo( 'name' ), $message );
$message = str_replace( '{product_notes}', $notes, $message );
$message = str_replace( '{payment_id}', $payment_id, $message );
$message = str_replace( '{receipt_link}', edd_email_tag_receipt_link( $payment_id ), $message );
$message = str_replace( '{receipt}', edd_email_tag_receipt( $payment_id ), $message );
$message = apply_filters( 'edd_email_preview_template_tags', $message );
return apply_filters( 'edd_email_template_wpautop', true ) ? wpautop( $message ) : $message;
}
/**
* Email Template Preview
*
* @access private
* @since 1.0.8.2
*/
function edd_email_template_preview() {
if( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
ob_start();
?>
<a href="<?php echo esc_url( add_query_arg( array( 'edd_action' => 'preview_email' ), home_url() ) ); ?>" class="button-secondary" target="_blank"><?php _e( 'Preview Purchase Receipt', 'easy-digital-downloads' ); ?></a>
<a href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'edd_action' => 'send_test_email' ) ), 'edd-test-email' ) ); ?>" class="button-secondary"><?php _e( 'Send Test Email', 'easy-digital-downloads' ); ?></a>
<?php
echo ob_get_clean();
}
add_action( 'edd_purchase_receipt_email_settings', 'edd_email_template_preview' );
/**
* Displays the email preview
*
* @since 2.1
* @return void
*/
function edd_display_email_template_preview() {
if( empty( $_GET['edd_action'] ) ) {
return;
}
if( 'preview_email' !== $_GET['edd_action'] ) {
return;
}
if( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
EDD()->emails->heading = edd_email_preview_template_tags( edd_get_option( 'purchase_heading', __( 'Purchase Receipt', 'easy-digital-downloads' ) ) );
echo EDD()->emails->build_email( edd_email_preview_template_tags( edd_get_email_body_content( 0, array() ) ) );
exit;
}
add_action( 'template_redirect', 'edd_display_email_template_preview' );
/**
* Email Template Body
*
* @since 1.0.8.2
* @param int $payment_id Payment ID
* @param array $payment_data Payment Data
* @return string $email_body Body of the email
*/
function edd_get_email_body_content( $payment_id = 0, $payment_data = array() ) {
$default_email_body = __( "Dear", "easy-digital-downloads" ) . " {name},\n\n";
$default_email_body .= __( "Thank you for your purchase. Please click on the link(s) below to download your files.", "easy-digital-downloads" ) . "\n\n";
$default_email_body .= "{download_list}\n\n";
$default_email_body .= "{sitename}";
$email = edd_get_option( 'purchase_receipt', false );
$email = $email ? stripslashes( $email ) : $default_email_body;
$email_body = apply_filters( 'edd_email_template_wpautop', true ) ? wpautop( $email ) : $email;
$email_body = apply_filters( 'edd_purchase_receipt_' . EDD()->emails->get_template(), $email_body, $payment_id, $payment_data );
return apply_filters( 'edd_purchase_receipt', $email_body, $payment_id, $payment_data );
}
/**
* Sale Notification Template Body
*
* @since 1.7
* @author Daniel J Griffiths
* @param int $payment_id Payment ID
* @param array $payment_data Payment Data
* @return string $email_body Body of the email
*/
function edd_get_sale_notification_body_content( $payment_id = 0, $payment_data = array() ) {
$payment = edd_get_payment( $payment_id );
$order = edd_get_order( $payment_id );
$name = $payment->email;
if ( $payment->user_id > 0 ) {
$user_data = get_userdata( $payment->user_id );
if ( ! empty( $user_data->display_name ) ) {
$name = $user_data->display_name;
}
} elseif ( ! empty( $payment->first_name ) && ! empty( $payment->last_name ) ) {
$name = $payment->first_name . ' ' . $payment->last_name;
}
$download_list = '';
$order_items = $order->get_items();
if( ! empty( $order_items ) ) {
foreach( $order_items as $item ) {
$download_list .= html_entity_decode( $item->product_name, ENT_COMPAT, 'UTF-8' ) . "\n";
}
}
$gateway = edd_get_gateway_checkout_label( $payment->gateway );
$default_email_body = __( 'Hello', 'easy-digital-downloads' ) . "\n\n" . sprintf( __( 'A %s purchase has been made', 'easy-digital-downloads' ), edd_get_label_plural() ) . ".\n\n";
$default_email_body .= sprintf( __( '%s sold:', 'easy-digital-downloads' ), edd_get_label_plural() ) . "\n\n";
$default_email_body .= $download_list . "\n\n";
$default_email_body .= __( 'Purchased by: ', 'easy-digital-downloads' ) . " " . html_entity_decode( $name, ENT_COMPAT, 'UTF-8' ) . "\n";
$default_email_body .= __( 'Amount: ', 'easy-digital-downloads' ) . " " . html_entity_decode( edd_currency_filter( edd_format_amount( $payment->total ) ), ENT_COMPAT, 'UTF-8' ) . "\n";
$default_email_body .= __( 'Payment Method: ', 'easy-digital-downloads' ) . " " . $gateway . "\n\n";
$default_email_body .= __( 'Thank you', 'easy-digital-downloads' );
$message = edd_get_option( 'sale_notification', false );
$message = $message ? stripslashes( $message ) : $default_email_body;
//$email_body = edd_email_template_tags( $email, $payment_data, $payment_id, true );
$email_body = edd_do_email_tags( $message, $payment_id );
$email_body = apply_filters( 'edd_email_template_wpautop', true ) ? wpautop( $email_body ) : $email_body;
return apply_filters( 'edd_sale_notification', $email_body, $payment_id, $payment_data );
}
/**
* Render Receipt in the Browser
*
* A link is added to the Purchase Receipt to view the email in the browser and
* this function renders the Purchase Receipt in the browser. It overrides the
* Purchase Receipt template and provides its only styling.
*
* @since 1.5
* @author Sunny Ratilal
* @param array $data The request data.
*/
function edd_render_receipt_in_browser( $data ) {
if ( ! isset( $data['payment_key'] ) ) {
wp_die( __( 'Missing purchase key.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ) );
}
if ( ! empty( $_POST['edd_action'] ) && ! empty( $_POST['edd_user_login'] ) && ! empty( $_POST['edd_login_nonce'] ) ) {
return;
}
$key = urlencode( $data['payment_key'] );
ob_start();
// Disallows caching of the page
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
header("Expires: Sat, 23 Oct 1977 05:00:00 PST"); // Date in the past
?>
<!DOCTYPE html>
<html lang="en">
<head>
<title><?php esc_html_e( 'Receipt', 'easy-digital-downloads' ); ?></title>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<?php wp_head(); ?>
<style>
body.edd_receipt_page {
margin: 12px auto;
align-items: center;
border: 1px solid #cfcfcf;
max-width: fit-content;
padding: 12px 24px;
border-radius: 8px;
}
.edd_receipt_page #edd_login_form fieldset {
border: none;
display: grid;
}
.edd_receipt_page #edd_login_form label,
.edd_receipt_page #edd_login_form input[type=text],
.edd_receipt_page #edd_login_form input[type=password]{
display: block;
width: 100%;
}
.edd_receipt_page th {
text-align: left;
}
</style>
</head>
<body class="<?php echo esc_attr( apply_filters( 'edd_receipt_page_body_class', 'edd_receipt_page' ) ); ?>">
<div id="edd_receipt_wrapper">
<?php do_action( 'edd_render_receipt_in_browser_before' ); ?>
<?php echo do_shortcode( '[edd_receipt payment_key=' . $key . ']' ); ?>
<?php do_action( 'edd_render_receipt_in_browser_after' ); ?>
</div>
<?php wp_footer(); ?>
</body>
</html>
<?php
echo ob_get_clean();
die();
}
add_action( 'edd_view_receipt', 'edd_render_receipt_in_browser' );