updated plugin `Easy Digital Downloads` version 3.1.2

This commit is contained in:
KawaiiPunk 2023-06-28 12:45:44 +00:00 committed by Gitium
parent 44df590080
commit f710fa7de2
120 changed files with 5556 additions and 3347 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@
* Description: The easiest way to sell digital products with WordPress.
* Author: Easy Digital Downloads
* Author URI: https://easydigitaldownloads.com
* Version: 3.1.1.4.2
* Version: 3.1.2
* Text Domain: easy-digital-downloads
* Domain Path: /languages
* Requires at least: 5.4
@ -27,7 +27,7 @@
* @package EDD
* @category Core
* @author Easy Digital Downloads
* @version 3.1.1.4.2
* @version 3.1.2
*/
// Exit if accessed directly.

View File

@ -59,6 +59,7 @@ function edd_tools_banned_emails_display() {
* @return void
*/
function edd_trigger_purchase_delete( $data ) {
_edd_deprecated_function( __FUNCTION__, '3.0' );
if ( wp_verify_nonce( $data['_wpnonce'], 'edd_payment_nonce' ) ) {
$payment_id = absint( $data['purchase_id'] );
@ -72,7 +73,6 @@ function edd_trigger_purchase_delete( $data ) {
edd_redirect( admin_url( 'edit.php?post_type=download&page=edd-payment-history&edd-message=payment_deleted' ) );
}
}
add_action( 'edd_delete_payment', 'edd_trigger_purchase_delete' );
/**
* Add-ons Page
@ -283,6 +283,491 @@ function edd_add_extentions_link() {
}
}
/**
* Display the system info tab
*
* @deprecated 3.1.2
* @since 2.0
*/
function edd_tools_sysinfo_display() {
if ( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
_edd_deprecated_function( __FUNCTION__, '3.1.2' );
?>
<div class="postbox">
<h3><span><?php esc_html_e( 'System Information', 'easy-digital-downloads' ); ?></span></h3>
<div class="inside">
<p>
<?php esc_html_e( 'Use the system information below to help troubleshoot problems.', 'easy-digital-downloads' ); ?>
</p>
<form id="edd-system-info" action="<?php echo esc_url( admin_url( 'edit.php?post_type=download&page=edd-tools&tab=system_info' ) ); ?>" method="post" dir="ltr">
<textarea readonly="readonly" onclick="this.focus(); this.select()" id="system-info-textarea" class="edd-tools-textarea" name="edd-sysinfo"
><?php echo edd_tools_sysinfo_get(); ?></textarea>
<p>
<input type="hidden" name="edd-action" value="download_sysinfo"/>
<?php
wp_nonce_field( 'edd_download_system_info', 'edd_system_info' );
submit_button( __( 'Download System Info File', 'easy-digital-downloads' ), 'primary', 'edd-download-sysinfo', false );
submit_button( __( 'Copy to Clipboard', 'easy-digital-downloads' ), 'secondary edd-inline-button', 'edd-copy-system-info', false, array( 'onclick' => "this.form['edd-sysinfo'].focus();this.form['edd-sysinfo'].select();document.execCommand('copy');return false;" ) );
?>
</p>
</form>
</div>
</div>
<?php
}
/**
* Get system info.
*
* @deprecated 3.1.2
* @since 2.0
*
* @return string $return A string containing the info to output
*/
function edd_tools_sysinfo_get() {
_edd_deprecated_function( __FUNCTION__, '3.1.2' );
global $wpdb;
if ( ! class_exists( 'Browser' ) ) {
require_once EDD_PLUGIN_DIR . 'includes/libraries/browser.php';
}
$browser = new Browser();
// Get theme info
$theme_data = wp_get_theme();
$theme = $theme_data->Name . ' ' . $theme_data->Version;
$parent_theme = $theme_data->Template;
if ( ! empty( $parent_theme ) ) {
$parent_theme_data = wp_get_theme( $parent_theme );
$parent_theme = $parent_theme_data->Name . ' ' . $parent_theme_data->Version;
}
// Try to identify the hosting provider
$host = edd_get_host();
$return = '### Begin System Info (Generated ' . date( 'Y-m-d H:i:s' ) . ') ###' . "\n\n";
// Start with the basics...
$return .= '-- Site Info' . "\n\n";
$return .= 'Site URL: ' . site_url() . "\n";
$return .= 'Home URL: ' . home_url() . "\n";
$return .= 'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ) . "\n";
$return = apply_filters( 'edd_sysinfo_after_site_info', $return );
// Can we determine the site's host?
if ( $host ) {
$return .= "\n" . '-- Hosting Provider' . "\n\n";
$return .= 'Host: ' . $host . "\n";
$return = apply_filters( 'edd_sysinfo_after_host_info', $return );
}
// The local users' browser information, handled by the Browser class
$return .= "\n" . '-- User Browser' . "\n\n";
$return .= $browser;
$return = apply_filters( 'edd_sysinfo_after_user_browser', $return );
$locale = get_locale();
// WordPress configuration
$return .= "\n" . '-- WordPress Configuration' . "\n\n";
$return .= 'Version: ' . get_bloginfo( 'version' ) . "\n";
$return .= 'Language: ' . ( ! empty( $locale ) ? $locale : 'en_US' ) . "\n";
$return .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . "\n";
$return .= 'Active Theme: ' . $theme . "\n";
$return .= 'WP Timezone: ' . wp_timezone_string() . "\n";
$return .= 'EDD Timezone: ' . edd_get_timezone_abbr() . "\n";
if ( $parent_theme !== $theme ) {
$return .= 'Parent Theme: ' . $parent_theme . "\n";
}
$customized_template_files = edd_get_theme_edd_templates();
$return .= "\n" . '-- Customized Templates' . "\n\n";
if ( empty( $customized_template_files ) ) {
$return .= 'No custom templates found.' . "\n\n";
} else {
foreach ( $customized_template_files as $customized_template_file ) {
$return .= $customized_template_file . "\n";
}
}
$return .= "\n";
$return = apply_filters( 'edd_sysinfo_after_customized_templates', $return );
$return .= 'Show On Front: ' . get_option( 'show_on_front' ) . "\n";
// Only show page specs if frontpage is set to 'page'
if ( get_option( 'show_on_front' ) == 'page' ) {
$front_page_id = get_option( 'page_on_front' );
$blog_page_id = get_option( 'page_for_posts' );
$return .= 'Page On Front: ' . ( $front_page_id != 0 ? '#' . $front_page_id : 'Unset' ) . "\n";
$return .= 'Page For Posts: ' . ( $blog_page_id != 0 ? '#' . $blog_page_id : 'Unset' ) . "\n";
}
$return .= 'ABSPATH: ' . ABSPATH . "\n";
// Make sure wp_remote_post() is working
$request['cmd'] = '_notify-validate';
$params = array(
'sslverify' => false,
'timeout' => 60,
'user-agent' => 'EDD/' . EDD_VERSION,
'body' => $request,
);
$response = wp_remote_post( 'https://www.paypal.com/cgi-bin/webscr', $params );
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) {
$WP_REMOTE_POST = 'wp_remote_post() works';
} else {
$WP_REMOTE_POST = 'wp_remote_post() does not work';
}
$return .= 'Remote Post: ' . $WP_REMOTE_POST . "\n";
$return .= 'Table Prefix: ' . 'Length: ' . strlen( $wpdb->prefix ) . ' Status: ' . ( strlen( $wpdb->prefix ) > 16 ? 'ERROR: Too long' : 'Acceptable' ) . "\n";
// Commented out per https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues/3475
//$return .= 'Admin AJAX: ' . ( edd_test_ajax_works() ? 'Accessible' : 'Inaccessible' ) . "\n";
$return .= 'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' ) . "\n";
$return .= 'Memory Limit: ' . WP_MEMORY_LIMIT . "\n";
$return .= 'Registered Post Stati: ' . implode( ', ', get_post_stati() ) . "\n";
$return = apply_filters( 'edd_sysinfo_after_wordpress_config', $return );
// EDD configuration
$return .= "\n" . '-- EDD Configuration' . "\n\n";
$return .= 'Version: ' . EDD_VERSION . "\n";
$return .= 'Upgraded From: ' . get_option( 'edd_version_upgraded_from', 'None' ) . "\n";
$return .= 'EDD (Pro) Status: ' . ( edd_is_pro() ? "Enabled\n" : "Disabled\n" );
$return .= 'EDD (Pro) Activated On: ' . ( get_option( 'edd_pro_activation_date' ) ? edd_date_i18n( get_option( 'edd_pro_activation_date' ), 'Y-m-d' ) . "\n" : "N/A\n" );
$return .= 'EDD Pass Status: ' . ( EDD\Admin\Pass_Manager::isPro() ? "Valid Pass\n" : "Missing\n" );
$return .= 'Test Mode: ' . ( edd_is_test_mode() ? "Enabled\n" : "Disabled\n" );
$return .= 'AJAX: ' . ( ! edd_is_ajax_disabled() ? "Enabled\n" : "Disabled\n" );
$return .= 'Guest Checkout: ' . ( edd_no_guest_checkout() ? "Disabled\n" : "Enabled\n" );
$return .= 'Symlinks: ' . ( apply_filters( 'edd_symlink_file_downloads', edd_get_option( 'symlink_file_downloads', false ) ) && function_exists( 'symlink' ) ? "Enabled\n" : "Disabled\n" );
$return .= 'Download Method: ' . ucfirst( edd_get_file_download_method() ) . "\n";
$return .= 'Currency Code: ' . edd_get_currency() . "\n";
$return .= 'Currency Position: ' . edd_get_option( 'currency_position', 'before' ) . "\n";
$return .= 'Decimal Separator: ' . edd_get_option( 'decimal_separator', '.' ) . "\n";
$return .= 'Thousands Separator: ' . edd_get_option( 'thousands_separator', ',' ) . "\n";
$return .= 'Upgrades Completed: ' . implode( ',', edd_get_completed_upgrades() ) . "\n";
$return .= 'Download Link Expiration: ' . edd_get_option( 'download_link_expiration' ) . " hour(s)\n";
$return = apply_filters( 'edd_sysinfo_after_edd_config', $return );
// EDD Database tables
$return .= "\n" . '-- EDD Database Tables' . "\n\n";
foreach ( EDD()->components as $component ) {
// Object
$thing = $component->get_interface( 'table' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->get_version() . "\n";
}
// Meta
$thing = $component->get_interface( 'meta' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->get_version() . "\n";
}
}
$return = apply_filters( 'edd_sysinfo_after_edd_database_tables', $return );
// EDD Database tables
$return .= "\n" . '-- EDD Database Row Counts' . "\n\n";
foreach ( EDD()->components as $component ) {
// Object
$thing = $component->get_interface( 'table' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->count() . "\n";
}
// Meta
$thing = $component->get_interface( 'meta' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->count() . "\n";
}
}
$return = apply_filters( 'edd_sysinfo_after_edd_database_row_counts', $return );
// EDD pages
$purchase_page = edd_get_option( 'purchase_page', '' );
$success_page = edd_get_option( 'success_page', '' );
$failure_page = edd_get_option( 'failure_page', '' );
$return .= "\n" . '-- EDD Page Configuration' . "\n\n";
$return .= 'Checkout: ' . ( ! empty( $purchase_page ) ? "Valid\n" : "Invalid\n" );
$return .= 'Checkout Page: ' . ( ! empty( $purchase_page ) ? get_permalink( $purchase_page ) . "\n" : "Unset\n" );
$return .= 'Success Page: ' . ( ! empty( $success_page ) ? get_permalink( $success_page ) . "\n" : "Unset\n" );
$return .= 'Failure Page: ' . ( ! empty( $failure_page ) ? get_permalink( $failure_page ) . "\n" : "Unset\n" );
$return .= 'Downloads Slug: ' . ( defined( 'EDD_SLUG' ) ? '/' . EDD_SLUG . "\n" : "/downloads\n" );
$return = apply_filters( 'edd_sysinfo_after_edd_pages', $return );
// EDD gateways
$return .= "\n" . '-- EDD Gateway Configuration' . "\n\n";
$active_gateways = edd_get_enabled_payment_gateways();
if ( $active_gateways ) {
$default_gateway_is_active = edd_is_gateway_active( edd_get_default_gateway() );
if ( $default_gateway_is_active ) {
$default_gateway = edd_get_default_gateway();
$default_gateway = $active_gateways[ $default_gateway ]['admin_label'];
} else {
$default_gateway = 'Test Payment';
}
$gateways = array();
foreach ( $active_gateways as $gateway ) {
$gateways[] = $gateway['admin_label'];
}
$return .= 'Enabled Gateways: ' . implode( ', ', $gateways ) . "\n";
$return .= 'Default Gateway: ' . $default_gateway . "\n";
} else {
$return .= 'Enabled Gateways: None' . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_edd_gateways', $return );
// EDD Taxes
$return .= "\n" . '-- EDD Tax Configuration' . "\n\n";
$return .= 'Taxes: ' . ( edd_use_taxes() ? "Enabled\n" : "Disabled\n" );
$return .= 'Default Rate: ' . edd_get_formatted_tax_rate() . "\n";
$return .= 'Display On Checkout: ' . ( edd_get_option( 'checkout_include_tax', false ) ? "Displayed\n" : "Not Displayed\n" );
$return .= 'Prices Include Tax: ' . ( edd_prices_include_tax() ? "Yes\n" : "No\n" );
$rates = edd_get_tax_rates();
if ( ! empty( $rates ) ) {
$return .= 'Country / State Rates: ' . "\n";
foreach ( $rates as $rate ) {
$return .= ' Country: ' . $rate['country'] . ', State: ' . $rate['state'] . ', Rate: ' . $rate['rate'] . "\n";
}
}
$return = apply_filters( 'edd_sysinfo_after_edd_taxes', $return );
// EDD Templates
$dir = get_stylesheet_directory() . '/edd_templates/*';
if ( is_dir( $dir ) && ( count( glob( "$dir/*" ) ) !== 0 ) ) {
$return .= "\n" . '-- EDD Template Overrides' . "\n\n";
foreach ( glob( $dir ) as $file ) {
$return .= 'Filename: ' . basename( $file ) . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_edd_templates', $return );
}
// Drop Ins
$dropins = get_dropins();
if ( count( $dropins ) > 0 ) {
$return .= "\n" . '-- Drop Ins' . "\n\n";
foreach ( $dropins as $plugin => $plugin_data ) {
$return .= str_pad( $plugin_data['Name'] . ': ', 26, ' ' ) . $plugin_data['Version'] . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_dropin_plugins', $return );
}
// Get plugins that have an update
$updates = get_plugin_updates();
// Must-use plugins
// NOTE: MU plugins can't show updates!
$muplugins = get_mu_plugins();
if ( count( $muplugins ) > 0 ) {
$return .= "\n" . '-- Must-Use Plugins' . "\n\n";
foreach ( $muplugins as $plugin => $plugin_data ) {
$return .= str_pad( $plugin_data['Name'] . ': ', 26, ' ' ) . $plugin_data['Version'] . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_mu_plugins', $return );
}
// WordPress active plugins
$return .= "\n" . '-- WordPress Active Plugins' . "\n\n";
$plugins = get_plugins();
$active_plugins = get_option( 'active_plugins', array() );
foreach ( $plugins as $plugin_path => $plugin ) {
if ( ! in_array( $plugin_path, $active_plugins ) ) {
continue;
}
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
$plugin_url = '';
if ( ! empty( $plugin['PluginURI'] ) ) {
$plugin_url = $plugin['PluginURI'];
} elseif ( ! empty( $plugin['AuthorURI'] ) ) {
$plugin_url = $plugin['AuthorURI'];
} elseif ( ! empty( $plugin['Author'] ) ) {
$plugin_url = $plugin['Author'];
}
if ( $plugin_url ) {
$plugin_url = "\n" . $plugin_url;
}
$return .= str_pad( $plugin['Name'] . ': ', 26, ' ' ) . $plugin['Version'] . $update . $plugin_url . "\n\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_plugins', $return );
// WordPress inactive plugins
$return .= "\n" . '-- WordPress Inactive Plugins' . "\n\n";
foreach ( $plugins as $plugin_path => $plugin ) {
if ( in_array( $plugin_path, $active_plugins ) ) {
continue;
}
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
$plugin_url = '';
if ( ! empty( $plugin['PluginURI'] ) ) {
$plugin_url = $plugin['PluginURI'];
} elseif ( ! empty( $plugin['AuthorURI'] ) ) {
$plugin_url = $plugin['AuthorURI'];
} elseif ( ! empty( $plugin['Author'] ) ) {
$plugin_url = $plugin['Author'];
}
if ( $plugin_url ) {
$plugin_url = "\n" . $plugin_url;
}
$return .= str_pad( $plugin['Name'] . ': ', 26, ' ' ) . $plugin['Version'] . $update . $plugin_url . "\n\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_plugins_inactive', $return );
if ( is_multisite() ) {
// WordPress Multisite active plugins
$return .= "\n" . '-- Network Active Plugins' . "\n\n";
$plugins = wp_get_active_network_plugins();
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
foreach ( $plugins as $plugin_path ) {
$plugin_base = plugin_basename( $plugin_path );
if ( ! array_key_exists( $plugin_base, $active_plugins ) ) {
continue;
}
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
$plugin = get_plugin_data( $plugin_path );
$plugin_url = '';
if ( ! empty( $plugin['PluginURI'] ) ) {
$plugin_url = $plugin['PluginURI'];
} elseif ( ! empty( $plugin['AuthorURI'] ) ) {
$plugin_url = $plugin['AuthorURI'];
} elseif ( ! empty( $plugin['Author'] ) ) {
$plugin_url = $plugin['Author'];
}
if ( $plugin_url ) {
$plugin_url = "\n" . $plugin_url;
}
$return .= str_pad( $plugin['Name'] . ': ', 26, ' ' ) . $plugin['Version'] . $update . $plugin_url . "\n\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_ms_plugins', $return );
}
// Server configuration (really just versioning)
$return .= "\n" . '-- Webserver Configuration' . "\n\n";
$return .= 'PHP Version: ' . PHP_VERSION . "\n";
$return .= 'MySQL Version: ' . $wpdb->db_version() . "\n";
$return .= 'Webserver Info: ' . $_SERVER['SERVER_SOFTWARE'] . "\n";
$return = apply_filters( 'edd_sysinfo_after_webserver_config', $return );
// PHP configs... now we're getting to the important stuff
$return .= "\n" . '-- PHP Configuration' . "\n\n";
$return .= 'Memory Limit: ' . ini_get( 'memory_limit' ) . "\n";
$return .= 'Upload Max Size: ' . ini_get( 'upload_max_filesize' ) . "\n";
$return .= 'Post Max Size: ' . ini_get( 'post_max_size' ) . "\n";
$return .= 'Upload Max Filesize: ' . ini_get( 'upload_max_filesize' ) . "\n";
$return .= 'Time Limit: ' . ini_get( 'max_execution_time' ) . "\n";
$return .= 'Max Input Vars: ' . ini_get( 'max_input_vars' ) . "\n";
$return .= 'Display Errors: ' . ( ini_get( 'display_errors' ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A' ) . "\n";
$return .= 'PHP Arg Separator: ' . edd_get_php_arg_separator_output() . "\n";
$return = apply_filters( 'edd_sysinfo_after_php_config', $return );
// PHP extensions and such
$return .= "\n" . '-- PHP Extensions' . "\n\n";
$return .= 'cURL: ' . ( function_exists( 'curl_init' ) ? 'Supported' : 'Not Supported' ) . "\n";
$return .= 'fsockopen: ' . ( function_exists( 'fsockopen' ) ? 'Supported' : 'Not Supported' ) . "\n";
$return .= 'SOAP Client: ' . ( class_exists( 'SoapClient' ) ? 'Installed' : 'Not Installed' ) . "\n";
$return .= 'Suhosin: ' . ( extension_loaded( 'suhosin' ) ? 'Installed' : 'Not Installed' ) . "\n";
$return = apply_filters( 'edd_sysinfo_after_php_ext', $return );
// Session stuff
$return .= "\n" . '-- Session Configuration' . "\n\n";
$return .= 'EDD Use Sessions: ' . ( defined( 'EDD_USE_PHP_SESSIONS' ) && EDD_USE_PHP_SESSIONS ? 'Enforced' : ( EDD()->session->use_php_sessions() ? 'Enabled' : 'Disabled' ) ) . "\n";
$return .= 'Session: ' . ( isset( $_SESSION ) ? 'Enabled' : 'Disabled' ) . "\n";
// The rest of this is only relevant is session is enabled
if ( isset( $_SESSION ) ) {
$return .= 'Session Name: ' . esc_html( ini_get( 'session.name' ) ) . "\n";
$return .= 'Cookie Path: ' . esc_html( ini_get( 'session.cookie_path' ) ) . "\n";
$return .= 'Save Path: ' . esc_html( ini_get( 'session.save_path' ) ) . "\n";
$return .= 'Use Cookies: ' . ( ini_get( 'session.use_cookies' ) ? 'On' : 'Off' ) . "\n";
$return .= 'Use Only Cookies: ' . ( ini_get( 'session.use_only_cookies' ) ? 'On' : 'Off' ) . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_session_config', $return );
$return .= "\n" . '### End System Info ###';
return $return;
}
/**
* Generates a System Info download file
*
* @deprecated 3.1.2
* @since 2.0
*/
function edd_tools_sysinfo_download() {
_edd_deprecated_function( __FUNCTION__, '3.1.2' );
if ( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
check_admin_referer( 'edd_download_system_info', 'edd_system_info' );
nocache_headers();
header( 'Content-Type: text/plain' );
header( 'Content-Disposition: attachment; filename="edd-system-info.txt"' );
echo wp_strip_all_tags( $_POST['edd-sysinfo'] );
edd_die();
}
/**
* Process bulk edit actions via AJAX
*
@ -292,6 +777,7 @@ function edd_add_extentions_link() {
*/
function edd_save_bulk_edit() {
_edd_deprecated_function( __FUNCTION__, '3.1.1.4' );
$post_ids = ! empty( $_POST['post_ids'] )
? wp_parse_id_list( $_POST['post_ids'] )
: array();
@ -314,3 +800,89 @@ function edd_save_bulk_edit() {
die();
}
/**
* Remove sale logs from refunded orders
*
* @deprecated 3.1.2
* @since 2.4.3
* @return void
*/
function edd_remove_refunded_sale_logs() {
_edd_deprecated_function( __FUNCTION__, '3.1.2' );
check_admin_referer( 'edd-upgrade' );
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$step = isset( $_GET['step'] ) ? absint( $_GET['step'] ) : 1;
$total = isset( $_GET['total'] ) ? absint( $_GET['total'] ) : edd_count_payments()->refunded;
$refunds = edd_get_payments( array(
'status' => 'refunded',
'number' => 20,
'page' => $step
) );
if ( ! empty( $refunds ) ) {
$edd_logs = EDD()->debug_log;
// Refunded Payments found so process them
foreach ( $refunds as $refund ) {
// Remove related sale log entries
$edd_logs->delete_logs(
null,
'sale',
array(
array(
'key' => '_edd_log_payment_id',
'value' => $refund->ID
)
)
);
}
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'remove_refunded_sale_logs',
'step' => urlencode( $step ),
'total' => urlencode( $total ),
'_wpnonce' => wp_create_nonce( 'edd-upgrade' ),
), admin_url( 'index.php' ) );
edd_redirect( $redirect );
// No more refunded payments found, finish up
} else {
edd_set_upgrade_complete( 'remove_refunded_sale_logs' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/**
* Sales Log View
*
* @deprecated 3.0
*
* @since 1.4
* @uses EDD_Sales_Log_Table::prepare_items()
* @uses EDD_Sales_Log_Table::display()
* @return void
*/
function edd_logs_view_sales() {
_edd_deprecated_function( __FUNCTION__, '3.0' );
// Setup or bail
if ( ! edd_logs_view_setup( 'sales' ) ) {
return;
}
$logs_table = new EDD_Sales_Log_Table();
edd_logs_view_page( $logs_table, 'sales' );
}

View File

@ -208,17 +208,17 @@ function edd_is_admin_page( $passed_page = '', $passed_view = '', $include_non_e
switch ( $passed_view ) {
case 'list-table':
case 'new':
if ( ( 'download' === $typenow || 'download' === $post_type ) && $pagenow === 'edit-tags.php' && 'edit' !== $action && 'download_tax' === $taxonomy ) {
if ( ( 'download' === $typenow || 'download' === $post_type ) && $pagenow === 'edit-tags.php' && 'edit' !== $action && 'download_tag' === $taxonomy ) {
$found = true;
}
break;
case 'edit':
if ( ( 'download' === $typenow || 'download' === $post_type ) && $pagenow === 'edit-tags.php' && 'edit' === $action && 'download_tax' === $taxonomy ) {
if ( ( 'download' === $typenow || 'download' === $post_type ) && $pagenow === 'edit-tags.php' && 'edit' === $action && 'download_tag' === $taxonomy ) {
$found = true;
}
break;
default:
if ( ( 'download' === $typenow || 'download' === $post_type ) && $pagenow === 'edit-tags.php' && 'download_tax' === $taxonomy ) {
if ( ( 'download' === $typenow || 'download' === $post_type ) && $pagenow === 'edit-tags.php' && 'download_tag' === $taxonomy ) {
$found = true;
}
break;

View File

@ -128,11 +128,6 @@ class EDD_Notices {
*/
public function add_notices() {
// User can edit pages
if ( current_user_can( 'edit_pages' ) ) {
$this->add_page_notices();
}
// User can view shop reports
if ( current_user_can( 'view_shop_reports' ) ) {
$this->add_reports_notices();
@ -140,9 +135,9 @@ class EDD_Notices {
// User can manage the entire shop
if ( current_user_can( 'manage_shop_settings' ) ) {
$this->add_system_notices();
$this->add_data_notices();
$this->add_settings_notices();
$this->add_order_upgrade_notice();
}
// Generic notices
@ -189,6 +184,10 @@ class EDD_Notices {
* @since 2.6.0 bbPress (r6771)
*/
public function display_notices() {
$screen = get_current_screen();
if ( 'site-health' === $screen->id ) {
return;
}
$this->show_debugging_notice();
@ -261,6 +260,7 @@ class EDD_Notices {
* Notices about missing pages
*
* @since 3.0
* @deprecated 3.1.2
*/
private function add_page_notices() {
@ -289,6 +289,7 @@ class EDD_Notices {
* Notices for the entire shop
*
* @since 3.0
* @deprecated 3.1.2
*/
private function add_system_notices() {
@ -419,41 +420,48 @@ class EDD_Notices {
private function add_settings_notices() {
// Settings area
if ( ! empty( $_GET['page'] ) && ( 'edd-settings' === $_GET['page'] ) ) {
if ( empty( $_GET['page'] ) || ( 'edd-settings' !== $_GET['page'] ) ) {
return;
}
// Settings updated
if ( ! empty( $_GET['settings-updated'] ) ) {
$this->add_notice( array(
// Settings updated
if ( ! empty( $_GET['settings-updated'] ) ) {
$this->add_notice(
array(
'id' => 'edd-notices',
'message' => __( 'Settings updated.', 'easy-digital-downloads' )
) );
}
// No payment gateways are enabled
if ( ! edd_get_option( 'gateways' ) && edd_is_test_mode() ) {
// URL to fix this
$url = edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'gateways',
)
);
// Link
$link = '<a href="' . esc_url( $url ) . '">' . __( 'Fix this', 'easy-digital-downloads' ) . '</a>';
// Add the notice
$this->add_notice( array(
'id' => 'edd-gateways',
'class' => 'error',
'message' => sprintf( __( 'No payment gateways are enabled. %s.', 'easy-digital-downloads' ), $link ),
'is_dismissible' => false
) );
}
)
);
}
}
/**
* Adds a notice if an order migration is running.
* This is only shown if the migration is running via UI by a different user or on another screen.
*
* @since 3.1.2
* @return void
*/
private function add_order_upgrade_notice() {
if ( edd_has_upgrade_completed( 'migrate_orders' ) ) {
return;
}
if ( ! get_option( '_edd_v30_doing_order_migration', false ) ) {
return;
}
if ( get_option( 'edd_v30_cli_migration_running', false ) ) {
return;
}
$this->add_notice(
array(
'id' => 'edd-v30-order-migration-running',
'class' => 'updated',
'message' => __( 'Easy Digital Downloads is migrating orders. Sales and earnings data for your store will be updated when all orders have been migrated.', 'easy-digital-downloads' ),
'is_dismissible' => false,
)
);
}
/**
* Notices about actions that the user has taken
*

View File

@ -47,6 +47,16 @@ class EDD_Email_Summary_Admin {
* @param array $data GET Request array.
*/
public function send_test_email_summary() {
if ( ! current_user_can( 'manage_shop_settings' ) ) {
echo wp_json_encode(
array(
'status' => 'error',
'message' => __( 'You do not have permission to perform this action.', 'easy-digital-downloads' ),
)
);
}
add_action( 'wp_mail_failed', array( $this, 'mail_failed' ) );
$output = array(

View File

@ -259,11 +259,12 @@ class EDD_Batch_Downloads_Import extends EDD_Batch_Import {
*/
public function get_percentage_complete() {
if( $this->total > 0 ) {
$percentage = 0;
if ( $this->total > 0 ) {
$percentage = ( $this->step * $this->per_step / $this->total ) * 100;
}
if( $percentage > 100 ) {
if ( $percentage > 100 ) {
$percentage = 100;
}
@ -368,7 +369,7 @@ class EDD_Batch_Downloads_Import extends EDD_Batch_Import {
private function set_image( $download_id = 0, $image = '', $post_author = 0 ) {
$is_url = false !== filter_var( $image, FILTER_VALIDATE_URL );
$is_local = $is_url && false !== strpos( site_url(), $image );
$is_local = $is_url && false !== strpos( $image, site_url() );
$ext = edd_get_file_extension( $image );
if( $is_url && $is_local ) {

View File

@ -608,13 +608,14 @@ class EDD_Batch_Payments_Import extends EDD_Batch_Import {
*/
public function get_percentage_complete() {
$total = count( $this->csv );
$percentage = 0;
$total = count( $this->csv );
if( $total > 0 ) {
if ( $total > 0 ) {
$percentage = ( $this->step * $this->per_step / $total ) * 100;
}
if( $percentage > 100 ) {
if ( $percentage > 100 ) {
$percentage = 100;
}

View File

@ -85,13 +85,23 @@ class EDD_Batch_Import {
*/
public function __construct( $_file = '', $_step = 1 ) {
$this->step = $_step;
$this->file = $_file;
$this->done = false;
$this->csv = $this->get_csv_file( $this->file );
$this->step = $_step;
$this->done = false;
if ( ! empty( $_file ) ) {
$this->set_up_csv( $_file );
}
}
/**
* Sets up the CSV file for importing.
*
* @param [type] $file
* @return void
*/
public function set_up_csv( $file ) {
$this->csv = $this->get_csv_file( $file );
$this->total = count( $this->csv );
$this->init();
}
/**
@ -121,7 +131,8 @@ class EDD_Batch_Import {
* @return array
*/
public function get_csv_file( $file ) {
$csv = array_map( 'str_getcsv', file( $this->file ) );
$this->file = $file;
$csv = array_map( 'str_getcsv', file( $file ) );
array_walk(
$csv,
function ( &$a ) use ( $csv ) {

View File

@ -21,21 +21,36 @@ defined( 'ABSPATH' ) || exit;
*/
function edd_do_ajax_import_file_upload() {
if ( ! wp_verify_nonce( $_REQUEST['edd_ajax_import'], 'edd_ajax_import' ) ) {
wp_send_json_error( array( 'error' => __( 'Nonce verification failed', 'easy-digital-downloads' ) ) );
}
if ( empty( $_POST['edd-import-class'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import parameters. Import class must be specified.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
require_once ABSPATH . 'wp-admin/includes/file.php';
}
require_once EDD_PLUGIN_DIR . 'includes/admin/import/class-batch-import.php';
if( ! wp_verify_nonce( $_REQUEST['edd_ajax_import'], 'edd_ajax_import' ) ) {
wp_send_json_error( array( 'error' => __( 'Nonce verification failed', 'easy-digital-downloads' ) ) );
$importer_class = sanitize_text_field( $_POST['edd-import-class'] );
$is_class_allowed = edd_importer_is_class_allowed( $importer_class );
if ( false === $is_class_allowed ) {
wp_send_json_error( array( 'error' => __( 'Invalid importer class supplied', 'easy-digital-downloads' ) ) );
}
if( empty( $_POST['edd-import-class'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import parameters. Import class must be specified.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
do_action( 'edd_batch_import_class_include', $importer_class );
$import = new $importer_class();
// The import class checks for the user's capability.
if ( ! $import->can_import() ) {
wp_send_json_error( array( 'error' => __( 'You do not have permission to import data', 'easy-digital-downloads' ) ) );
}
if( empty( $_FILES['edd-import-file'] ) ) {
if ( empty( $_FILES['edd-import-file'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import file. Please provide an import file.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
@ -43,7 +58,7 @@ function edd_do_ajax_import_file_upload() {
wp_send_json_error( array( 'error' => __( 'The file you uploaded does not appear to be a CSV file.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( ! file_exists( $_FILES['edd-import-file']['tmp_name'] ) ) {
if ( ! file_exists( $_FILES['edd-import-file']['tmp_name'] ) ) {
wp_send_json_error( array( 'error' => __( 'Something went wrong during the upload process, please try again.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
@ -52,20 +67,7 @@ function edd_do_ajax_import_file_upload() {
if ( $import_file && empty( $import_file['error'] ) ) {
$importer_class = sanitize_text_field( $_POST['edd-import-class'] );
$is_class_allowed = edd_importer_is_class_allowed( $importer_class );
if ( false === $is_class_allowed ) {
wp_send_json_error( array( 'error' => __( 'Invalid importer class supplied', 'easy-digital-downloads' ) ) );
}
do_action( 'edd_batch_import_class_include', $importer_class );
$import = new $importer_class( $import_file['file'] );
if( ! $import->can_import() ) {
wp_send_json_error( array( 'error' => __( 'You do not have permission to import data', 'easy-digital-downloads' ) ) );
}
$import->set_up_csv( $import_file['file'] );
wp_send_json_success( array(
'form' => $_POST,
'class' => $importer_class,
@ -104,11 +106,11 @@ function edd_do_ajax_import() {
wp_send_json_error( array( 'error' => __( 'Nonce verification failed', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( empty( $_REQUEST['class'] ) ) {
if ( empty( $_REQUEST['class'] ) ) {
wp_send_json_error( array( 'error' => __( 'Missing import parameters. Import class must be specified.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
if( ! file_exists( $_REQUEST['upload']['file'] ) ) {
if ( ! file_exists( $_REQUEST['upload']['file'] ) ) {
wp_send_json_error( array( 'error' => __( 'Something went wrong during the upload process, please try again.', 'easy-digital-downloads' ), 'request' => $_REQUEST ) );
}
@ -140,13 +142,12 @@ function edd_do_ajax_import() {
$step = absint( $_REQUEST['step'] );
$class = $importer_class;
$import = new $class( $file, $step );
if( ! $import->can_import() ) {
$import = new $class( '', $step );
if ( ! $import->can_import() ) {
wp_send_json_error( array( 'error' => __( 'You do not have permission to import data', 'easy-digital-downloads' ) ) );
}
$import->set_up_csv( $file );
parse_str( $_REQUEST['mapping'], $map );

View File

@ -563,7 +563,7 @@ function edd_get_registered_settings() {
'default_gateway' => array(
'id' => 'default_gateway',
'name' => __( 'Default Gateway', 'easy-digital-downloads' ),
'desc' => __( 'Automatically select this gateway on checkout pages.<br>If empty, the first active gateway is selected instead.', 'easy-digital-downloads' ),
'desc' => __( 'Choose the gateway your checkout will use by default.<br />If you choose Automatic, the first enabled gateway from the Active Gateways will be used.', 'easy-digital-downloads' ),
'type' => 'gateway_select',
'options' => $gateways,
),
@ -2151,11 +2151,37 @@ function edd_gateways_callback( $args ) {
$html .= '<li class="edd-check-wrapper" data-key="' . edd_sanitize_key( $key ) . '">';
$html .= '<label>';
$html .= '<input name="edd_settings[' . esc_attr( $args['id'] ) . '][' . edd_sanitize_key( $key ) . ']" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . '][' . edd_sanitize_key( $key ) . ']" class="' . $class . '" type="checkbox" value="1" data-gateway-key="' . edd_sanitize_key( $key ) . '" ' . checked( '1', $enabled, false ) . '/>&nbsp;';
$attributes = array(
'name' => 'edd_settings[' . edd_sanitize_key( $args['id'] ) . '][' . edd_sanitize_key( $key ) . ']',
'id' => 'edd_settings[' . edd_sanitize_key( $args['id'] ) . '][' . edd_sanitize_key( $key ) . ']',
'data-gateway-key' => edd_sanitize_key( $key ),
'checked' => checked( '1', $enabled, false ),
'is_setup' => edd_is_gateway_setup( $key ),
'disabled' => '',
);
if ( ! $attributes['is_setup'] ) {
$attributes['disabled'] = 'disabled="disabled"';
}
$html .= '<input name="' . $attributes['name'] . '" id="' . $attributes['id'] . '" class="' . $class . '" type="checkbox" value="1" data-gateway-key="' . $attributes['data-gateway-key'] . '" ' . $attributes['checked'] . ' ' . $attributes['disabled'] . '/>&nbsp;';
$html .= esc_html( $option['admin_label'] );
if ( 'manual' === $key ) {
$html .= '<span alt="f223" class="edd-help-tip dashicons dashicons-editor-help" title="<strong>' . esc_html__( 'Store Gateway', 'easy-digital-downloads' ) . '</strong>: ' . esc_html__( 'This is an internal payment gateway which can be used for manually added orders or test purchases. No money is actually processed.', 'easy-digital-downloads' ) . '"></span>';
}
// If a settings URL is returned, display a button to go to the settings page.
$gateway_settings_url = edd_get_gateway_settings_url( $key );
if ( ! empty( $gateway_settings_url ) ) {
$html .= sprintf(
'<a class="button edd-settings__button-settings" href="%s"><span class="screen-reader-text">%s</span></a>',
$gateway_settings_url,
__( 'Configure Gateway', 'easy-digital-downloads' )
);
}
$html .= '</label>';
$html .= '</li>';
}
@ -2170,7 +2196,7 @@ function edd_gateways_callback( $args ) {
)
);
$html .= '<p class="description">' . esc_html__( 'These gateways will be offered at checkout.', 'easy-digital-downloads' ) . '<br>' . sprintf( __( 'More <a href="%s">Payment Gateways</a> are available.', 'easy-digital-downloads' ), $url ) . '</p>';
$html .= '<p class="description">' . esc_html__( 'Choose how you want to allow your customers to pay you.', 'easy-digital-downloads' ) . '<br>' . sprintf( __( 'More <a href="%s">Payment Gateways</a> are available.', 'easy-digital-downloads' ), $url ) . '</p>';
}
echo apply_filters( 'edd_after_setting_output', $html, $args );
@ -2199,7 +2225,7 @@ function edd_gateway_select_callback( $args ) {
}
$html = '<select name="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']"" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']" class="' . $class . '">';
$html .= '<option value="">' . __( '&mdash; No gateway &mdash;', 'easy-digital-downloads' ) . '</option>';
$html .= '<option value="">' . __( 'Automatic', 'easy-digital-downloads' ) . '</option>';
$gateways = edd_get_payment_gateways();
foreach ( $gateways as $key => $option ) {
@ -2858,6 +2884,11 @@ if ( ! function_exists( 'edd_license_key_callback' ) ) {
* @return void
*/
function edd_hook_callback( $args ) {
// Since our settings are hook based, just be sure the user can manage shop settings before firing the setting hook.
if ( ! current_user_can( 'manage_shop_settings') ) {
return;
}
do_action( 'edd_' . $args['id'], $args );
}

View File

@ -58,6 +58,17 @@ function edd_tools_page() {
$tab_url
);
// System Info is now found in Site Health.
if ( 'system_info' === $tab_id ) {
$tab_url = add_query_arg(
array(
'tab' => 'debug',
'edd' => 'filter',
),
admin_url( 'site-health.php' )
);
}
$active = ( $active_tab === $tab_id )
? ' nav-tab-active'
: '';
@ -469,7 +480,7 @@ function edd_tools_import_export_display() {
<?php wp_nonce_field( 'edd_ajax_import', 'edd_ajax_import' ); ?>
<input type="hidden" name="edd-import-class" value="EDD_Batch_Payments_Import"/>
<p>
<input name="edd-import-file" id="edd-payments-import-file" type="file"/>
<input name="edd-import-file" id="edd-payments-import-file" type="file" accept=".csv" required/>
</p>
<span>
<input type="submit" value="<?php _e( 'Import CSV', 'easy-digital-downloads' ); ?>"
@ -784,7 +795,7 @@ function edd_tools_import_export_display() {
<?php wp_nonce_field( 'edd_ajax_import', 'edd_ajax_import' ); ?>
<input type="hidden" name="edd-import-class" value="EDD_Batch_Downloads_Import"/>
<p>
<input name="edd-import-file" id="edd-downloads-import-file" type="file"/>
<input name="edd-import-file" id="edd-downloads-import-file" type="file" accept=".csv" required/>
</p>
<span>
<input type="submit" value="<?php _e( 'Import CSV', 'easy-digital-downloads' ); ?>"
@ -1022,7 +1033,7 @@ function edd_tools_import_export_display() {
<form method="post" enctype="multipart/form-data"
action="<?php echo esc_url( edd_get_admin_url( array( 'page' => 'edd-tools', 'tab' => 'import_export' ) ) ); ?>">
<p>
<input type="file" name="import_file"/>
<input type="file" name="import_file" accept=".json" required/>
</p>
<p>
<input type="hidden" name="edd_action" value="import_settings"/>
@ -1252,484 +1263,6 @@ function edd_handle_submit_debug_log() {
}
add_action( 'edd_submit_debug_log', 'edd_handle_submit_debug_log' );
/**
* Display the system info tab
*
* @since 2.0
*/
function edd_tools_sysinfo_display() {
if ( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
?>
<div class="postbox">
<h3><span><?php esc_html_e( 'System Information', 'easy-digital-downloads' ); ?></span></h3>
<div class="inside">
<p>
<?php esc_html_e( 'Use the system information below to help troubleshoot problems.', 'easy-digital-downloads' ); ?>
</p>
<form id="edd-system-info" action="<?php echo esc_url( admin_url( 'edit.php?post_type=download&page=edd-tools&tab=system_info' ) ); ?>" method="post" dir="ltr">
<textarea readonly="readonly" onclick="this.focus(); this.select()" id="system-info-textarea" class="edd-tools-textarea" name="edd-sysinfo"
><?php echo edd_tools_sysinfo_get(); ?></textarea>
<p>
<input type="hidden" name="edd-action" value="download_sysinfo"/>
<?php
wp_nonce_field( 'edd_download_system_info', 'edd_system_info' );
submit_button( __( 'Download System Info File', 'easy-digital-downloads' ), 'primary', 'edd-download-sysinfo', false );
submit_button( __( 'Copy to Clipboard', 'easy-digital-downloads' ), 'secondary edd-inline-button', 'edd-copy-system-info', false, array( 'onclick' => "this.form['edd-sysinfo'].focus();this.form['edd-sysinfo'].select();document.execCommand('copy');return false;" ) );
?>
</p>
</form>
</div>
</div>
<?php
}
add_action( 'edd_tools_tab_system_info', 'edd_tools_sysinfo_display' );
/**
* Get system info.
*
* @since 2.0
*
* @return string $return A string containing the info to output
*/
function edd_tools_sysinfo_get() {
global $wpdb;
if ( ! class_exists( 'Browser' ) ) {
require_once EDD_PLUGIN_DIR . 'includes/libraries/browser.php';
}
$browser = new Browser();
// Get theme info
$theme_data = wp_get_theme();
$theme = $theme_data->Name . ' ' . $theme_data->Version;
$parent_theme = $theme_data->Template;
if ( ! empty( $parent_theme ) ) {
$parent_theme_data = wp_get_theme( $parent_theme );
$parent_theme = $parent_theme_data->Name . ' ' . $parent_theme_data->Version;
}
// Try to identify the hosting provider
$host = edd_get_host();
$return = '### Begin System Info (Generated ' . date( 'Y-m-d H:i:s' ) . ') ###' . "\n\n";
// Start with the basics...
$return .= '-- Site Info' . "\n\n";
$return .= 'Site URL: ' . site_url() . "\n";
$return .= 'Home URL: ' . home_url() . "\n";
$return .= 'Multisite: ' . ( is_multisite() ? 'Yes' : 'No' ) . "\n";
$return = apply_filters( 'edd_sysinfo_after_site_info', $return );
// Can we determine the site's host?
if ( $host ) {
$return .= "\n" . '-- Hosting Provider' . "\n\n";
$return .= 'Host: ' . $host . "\n";
$return = apply_filters( 'edd_sysinfo_after_host_info', $return );
}
// The local users' browser information, handled by the Browser class
$return .= "\n" . '-- User Browser' . "\n\n";
$return .= $browser;
$return = apply_filters( 'edd_sysinfo_after_user_browser', $return );
$locale = get_locale();
// WordPress configuration
$return .= "\n" . '-- WordPress Configuration' . "\n\n";
$return .= 'Version: ' . get_bloginfo( 'version' ) . "\n";
$return .= 'Language: ' . ( ! empty( $locale ) ? $locale : 'en_US' ) . "\n";
$return .= 'Permalink Structure: ' . ( get_option( 'permalink_structure' ) ? get_option( 'permalink_structure' ) : 'Default' ) . "\n";
$return .= 'Active Theme: ' . $theme . "\n";
$return .= 'WP Timezone: ' . wp_timezone_string() . "\n";
$return .= 'EDD Timezone: ' . edd_get_timezone_abbr() . "\n";
if ( $parent_theme !== $theme ) {
$return .= 'Parent Theme: ' . $parent_theme . "\n";
}
$customized_template_files = edd_get_theme_edd_templates();
$return .= "\n" . '-- Customized Templates' . "\n\n";
if ( empty( $customized_template_files ) ) {
$return .= 'No custom templates found.' . "\n\n";
} else {
foreach ( $customized_template_files as $customized_template_file ) {
$return .= $customized_template_file . "\n";
}
}
$return .= "\n";
$return = apply_filters( 'edd_sysinfo_after_customized_templates', $return );
$return .= 'Show On Front: ' . get_option( 'show_on_front' ) . "\n";
// Only show page specs if frontpage is set to 'page'
if ( get_option( 'show_on_front' ) == 'page' ) {
$front_page_id = get_option( 'page_on_front' );
$blog_page_id = get_option( 'page_for_posts' );
$return .= 'Page On Front: ' . ( $front_page_id != 0 ? '#' . $front_page_id : 'Unset' ) . "\n";
$return .= 'Page For Posts: ' . ( $blog_page_id != 0 ? '#' . $blog_page_id : 'Unset' ) . "\n";
}
$return .= 'ABSPATH: ' . ABSPATH . "\n";
// Make sure wp_remote_post() is working
$request['cmd'] = '_notify-validate';
$params = array(
'sslverify' => false,
'timeout' => 60,
'user-agent' => 'EDD/' . EDD_VERSION,
'body' => $request,
);
$response = wp_remote_post( 'https://www.paypal.com/cgi-bin/webscr', $params );
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) {
$WP_REMOTE_POST = 'wp_remote_post() works';
} else {
$WP_REMOTE_POST = 'wp_remote_post() does not work';
}
$return .= 'Remote Post: ' . $WP_REMOTE_POST . "\n";
$return .= 'Table Prefix: ' . 'Length: ' . strlen( $wpdb->prefix ) . ' Status: ' . ( strlen( $wpdb->prefix ) > 16 ? 'ERROR: Too long' : 'Acceptable' ) . "\n";
// Commented out per https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues/3475
//$return .= 'Admin AJAX: ' . ( edd_test_ajax_works() ? 'Accessible' : 'Inaccessible' ) . "\n";
$return .= 'WP_DEBUG: ' . ( defined( 'WP_DEBUG' ) ? WP_DEBUG ? 'Enabled' : 'Disabled' : 'Not set' ) . "\n";
$return .= 'Memory Limit: ' . WP_MEMORY_LIMIT . "\n";
$return .= 'Registered Post Stati: ' . implode( ', ', get_post_stati() ) . "\n";
$return = apply_filters( 'edd_sysinfo_after_wordpress_config', $return );
// EDD configuration
$return .= "\n" . '-- EDD Configuration' . "\n\n";
$return .= 'Version: ' . EDD_VERSION . "\n";
$return .= 'Activated On: ' . edd_date_i18n( edd_get_activation_date(), 'Y-m-d' ) . "\n";
$return .= 'Upgraded From: ' . get_option( 'edd_version_upgraded_from', 'None' ) . "\n";
$return .= 'EDD (Pro) Status: ' . ( edd_is_pro() ? "Enabled\n" : "Disabled\n" );
$return .= 'EDD (Pro) Activated On: ' . ( get_option( 'edd_pro_activation_date' ) ? edd_date_i18n( get_option( 'edd_pro_activation_date' ), 'Y-m-d' ) . "\n" : "N/A\n" );
$return .= 'EDD Pass Status: ' . ( EDD\Admin\Pass_Manager::isPro() ? "Valid Pass\n" : "Missing\n" );
$return .= 'Test Mode: ' . ( edd_is_test_mode() ? "Enabled\n" : "Disabled\n" );
$return .= 'AJAX: ' . ( ! edd_is_ajax_disabled() ? "Enabled\n" : "Disabled\n" );
$return .= 'Guest Checkout: ' . ( edd_no_guest_checkout() ? "Disabled\n" : "Enabled\n" );
$return .= 'Symlinks: ' . ( apply_filters( 'edd_symlink_file_downloads', edd_get_option( 'symlink_file_downloads', false ) ) && function_exists( 'symlink' ) ? "Enabled\n" : "Disabled\n" );
$return .= 'Download Method: ' . ucfirst( edd_get_file_download_method() ) . "\n";
$return .= 'Currency Code: ' . edd_get_currency() . "\n";
$return .= 'Currency Position: ' . edd_get_option( 'currency_position', 'before' ) . "\n";
$return .= 'Decimal Separator: ' . edd_get_option( 'decimal_separator', '.' ) . "\n";
$return .= 'Thousands Separator: ' . edd_get_option( 'thousands_separator', ',' ) . "\n";
$return .= 'Upgrades Completed: ' . implode( ',', edd_get_completed_upgrades() ) . "\n";
$return .= 'Download Link Expiration: ' . edd_get_option( 'download_link_expiration' ) . " hour(s)\n";
$return = apply_filters( 'edd_sysinfo_after_edd_config', $return );
// EDD Database tables
$return .= "\n" . '-- EDD Database Tables' . "\n\n";
foreach ( EDD()->components as $component ) {
// Object
$thing = $component->get_interface( 'table' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->get_version() . "\n";
}
// Meta
$thing = $component->get_interface( 'meta' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->get_version() . "\n";
}
}
$return = apply_filters( 'edd_sysinfo_after_edd_database_tables', $return );
// EDD Database tables
$return .= "\n" . '-- EDD Database Row Counts' . "\n\n";
foreach ( EDD()->components as $component ) {
// Object
$thing = $component->get_interface( 'table' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->count() . "\n";
}
// Meta
$thing = $component->get_interface( 'meta' );
if ( ! empty( $thing ) ) {
$return .= str_pad( $thing->name . ': ', 32, ' ' ) . $thing->count() . "\n";
}
}
$return = apply_filters( 'edd_sysinfo_after_edd_database_row_counts', $return );
// EDD pages
$purchase_page = edd_get_option( 'purchase_page', '' );
$success_page = edd_get_option( 'success_page', '' );
$failure_page = edd_get_option( 'failure_page', '' );
$return .= "\n" . '-- EDD Page Configuration' . "\n\n";
$return .= 'Checkout: ' . ( ! empty( $purchase_page ) ? "Valid\n" : "Invalid\n" );
$return .= 'Checkout Page: ' . ( ! empty( $purchase_page ) ? get_permalink( $purchase_page ) . "\n" : "Unset\n" );
$return .= 'Success Page: ' . ( ! empty( $success_page ) ? get_permalink( $success_page ) . "\n" : "Unset\n" );
$return .= 'Failure Page: ' . ( ! empty( $failure_page ) ? get_permalink( $failure_page ) . "\n" : "Unset\n" );
$return .= 'Downloads Slug: ' . ( defined( 'EDD_SLUG' ) ? '/' . EDD_SLUG . "\n" : "/downloads\n" );
$return = apply_filters( 'edd_sysinfo_after_edd_pages', $return );
// EDD gateways
$return .= "\n" . '-- EDD Gateway Configuration' . "\n\n";
$active_gateways = edd_get_enabled_payment_gateways();
if ( $active_gateways ) {
$default_gateway_is_active = edd_is_gateway_active( edd_get_default_gateway() );
if ( $default_gateway_is_active ) {
$default_gateway = edd_get_default_gateway();
$default_gateway = $active_gateways[ $default_gateway ]['admin_label'];
} else {
$default_gateway = 'Test Payment';
}
$gateways = array();
foreach ( $active_gateways as $gateway ) {
$gateways[] = $gateway['admin_label'];
}
$return .= 'Enabled Gateways: ' . implode( ', ', $gateways ) . "\n";
$return .= 'Default Gateway: ' . $default_gateway . "\n";
} else {
$return .= 'Enabled Gateways: None' . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_edd_gateways', $return );
// EDD Taxes
$return .= "\n" . '-- EDD Tax Configuration' . "\n\n";
$return .= 'Taxes: ' . ( edd_use_taxes() ? "Enabled\n" : "Disabled\n" );
$return .= 'Default Rate: ' . edd_get_formatted_tax_rate() . "\n";
$return .= 'Display On Checkout: ' . ( edd_get_option( 'checkout_include_tax', false ) ? "Displayed\n" : "Not Displayed\n" );
$return .= 'Prices Include Tax: ' . ( edd_prices_include_tax() ? "Yes\n" : "No\n" );
$rates = edd_get_tax_rates();
if ( ! empty( $rates ) ) {
$return .= 'Country / State Rates: ' . "\n";
foreach ( $rates as $rate ) {
$return .= ' Country: ' . $rate['country'] . ', State: ' . $rate['state'] . ', Rate: ' . $rate['rate'] . "\n";
}
}
$return = apply_filters( 'edd_sysinfo_after_edd_taxes', $return );
// EDD Templates
$dir = get_stylesheet_directory() . '/edd_templates/*';
if ( is_dir( $dir ) && ( count( glob( "$dir/*" ) ) !== 0 ) ) {
$return .= "\n" . '-- EDD Template Overrides' . "\n\n";
foreach ( glob( $dir ) as $file ) {
$return .= 'Filename: ' . basename( $file ) . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_edd_templates', $return );
}
// Drop Ins
$dropins = get_dropins();
if ( count( $dropins ) > 0 ) {
$return .= "\n" . '-- Drop Ins' . "\n\n";
foreach ( $dropins as $plugin => $plugin_data ) {
$return .= str_pad( $plugin_data['Name'] . ': ', 26, ' ' ) . $plugin_data['Version'] . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_dropin_plugins', $return );
}
// Get plugins that have an update
$updates = get_plugin_updates();
// Must-use plugins
// NOTE: MU plugins can't show updates!
$muplugins = get_mu_plugins();
if ( count( $muplugins ) > 0 ) {
$return .= "\n" . '-- Must-Use Plugins' . "\n\n";
foreach ( $muplugins as $plugin => $plugin_data ) {
$return .= str_pad( $plugin_data['Name'] . ': ', 26, ' ' ) . $plugin_data['Version'] . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_mu_plugins', $return );
}
// WordPress active plugins
$return .= "\n" . '-- WordPress Active Plugins' . "\n\n";
$plugins = get_plugins();
$active_plugins = get_option( 'active_plugins', array() );
foreach ( $plugins as $plugin_path => $plugin ) {
if ( ! in_array( $plugin_path, $active_plugins ) ) {
continue;
}
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
$plugin_url = '';
if ( ! empty( $plugin['PluginURI'] ) ) {
$plugin_url = $plugin['PluginURI'];
} elseif ( ! empty( $plugin['AuthorURI'] ) ) {
$plugin_url = $plugin['AuthorURI'];
} elseif ( ! empty( $plugin['Author'] ) ) {
$plugin_url = $plugin['Author'];
}
if ( $plugin_url ) {
$plugin_url = "\n" . $plugin_url;
}
$return .= str_pad( $plugin['Name'] . ': ', 26, ' ' ) . $plugin['Version'] . $update . $plugin_url . "\n\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_plugins', $return );
// WordPress inactive plugins
$return .= "\n" . '-- WordPress Inactive Plugins' . "\n\n";
foreach ( $plugins as $plugin_path => $plugin ) {
if ( in_array( $plugin_path, $active_plugins ) ) {
continue;
}
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
$plugin_url = '';
if ( ! empty( $plugin['PluginURI'] ) ) {
$plugin_url = $plugin['PluginURI'];
} elseif ( ! empty( $plugin['AuthorURI'] ) ) {
$plugin_url = $plugin['AuthorURI'];
} elseif ( ! empty( $plugin['Author'] ) ) {
$plugin_url = $plugin['Author'];
}
if ( $plugin_url ) {
$plugin_url = "\n" . $plugin_url;
}
$return .= str_pad( $plugin['Name'] . ': ', 26, ' ' ) . $plugin['Version'] . $update . $plugin_url . "\n\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_plugins_inactive', $return );
if ( is_multisite() ) {
// WordPress Multisite active plugins
$return .= "\n" . '-- Network Active Plugins' . "\n\n";
$plugins = wp_get_active_network_plugins();
$active_plugins = get_site_option( 'active_sitewide_plugins', array() );
foreach ( $plugins as $plugin_path ) {
$plugin_base = plugin_basename( $plugin_path );
if ( ! array_key_exists( $plugin_base, $active_plugins ) ) {
continue;
}
$update = ( array_key_exists( $plugin_path, $updates ) ) ? ' (needs update - ' . $updates[ $plugin_path ]->update->new_version . ')' : '';
$plugin = get_plugin_data( $plugin_path );
$plugin_url = '';
if ( ! empty( $plugin['PluginURI'] ) ) {
$plugin_url = $plugin['PluginURI'];
} elseif ( ! empty( $plugin['AuthorURI'] ) ) {
$plugin_url = $plugin['AuthorURI'];
} elseif ( ! empty( $plugin['Author'] ) ) {
$plugin_url = $plugin['Author'];
}
if ( $plugin_url ) {
$plugin_url = "\n" . $plugin_url;
}
$return .= str_pad( $plugin['Name'] . ': ', 26, ' ' ) . $plugin['Version'] . $update . $plugin_url . "\n\n";
}
$return = apply_filters( 'edd_sysinfo_after_wordpress_ms_plugins', $return );
}
// Server configuration (really just versioning)
$return .= "\n" . '-- Webserver Configuration' . "\n\n";
$return .= 'PHP Version: ' . PHP_VERSION . "\n";
$return .= 'MySQL Version: ' . $wpdb->db_version() . "\n";
$return .= 'Webserver Info: ' . $_SERVER['SERVER_SOFTWARE'] . "\n";
$return = apply_filters( 'edd_sysinfo_after_webserver_config', $return );
// PHP configs... now we're getting to the important stuff
$return .= "\n" . '-- PHP Configuration' . "\n\n";
$return .= 'Memory Limit: ' . ini_get( 'memory_limit' ) . "\n";
$return .= 'Upload Max Size: ' . ini_get( 'upload_max_filesize' ) . "\n";
$return .= 'Post Max Size: ' . ini_get( 'post_max_size' ) . "\n";
$return .= 'Upload Max Filesize: ' . ini_get( 'upload_max_filesize' ) . "\n";
$return .= 'Time Limit: ' . ini_get( 'max_execution_time' ) . "\n";
$return .= 'Max Input Vars: ' . ini_get( 'max_input_vars' ) . "\n";
$return .= 'Display Errors: ' . ( ini_get( 'display_errors' ) ? 'On (' . ini_get( 'display_errors' ) . ')' : 'N/A' ) . "\n";
$return .= 'PHP Arg Separator: ' . edd_get_php_arg_separator_output() . "\n";
$return = apply_filters( 'edd_sysinfo_after_php_config', $return );
// PHP extensions and such
$return .= "\n" . '-- PHP Extensions' . "\n\n";
$return .= 'cURL: ' . ( function_exists( 'curl_init' ) ? 'Supported' : 'Not Supported' ) . "\n";
$return .= 'fsockopen: ' . ( function_exists( 'fsockopen' ) ? 'Supported' : 'Not Supported' ) . "\n";
$return .= 'SOAP Client: ' . ( class_exists( 'SoapClient' ) ? 'Installed' : 'Not Installed' ) . "\n";
$return .= 'Suhosin: ' . ( extension_loaded( 'suhosin' ) ? 'Installed' : 'Not Installed' ) . "\n";
$return = apply_filters( 'edd_sysinfo_after_php_ext', $return );
// Session stuff
$return .= "\n" . '-- Session Configuration' . "\n\n";
$return .= 'EDD Use Sessions: ' . ( defined( 'EDD_USE_PHP_SESSIONS' ) && EDD_USE_PHP_SESSIONS ? 'Enforced' : ( EDD()->session->use_php_sessions() ? 'Enabled' : 'Disabled' ) ) . "\n";
$return .= 'Session: ' . ( isset( $_SESSION ) ? 'Enabled' : 'Disabled' ) . "\n";
// The rest of this is only relevant is session is enabled
if ( isset( $_SESSION ) ) {
$return .= 'Session Name: ' . esc_html( ini_get( 'session.name' ) ) . "\n";
$return .= 'Cookie Path: ' . esc_html( ini_get( 'session.cookie_path' ) ) . "\n";
$return .= 'Save Path: ' . esc_html( ini_get( 'session.save_path' ) ) . "\n";
$return .= 'Use Cookies: ' . ( ini_get( 'session.use_cookies' ) ? 'On' : 'Off' ) . "\n";
$return .= 'Use Only Cookies: ' . ( ini_get( 'session.use_only_cookies' ) ? 'On' : 'Off' ) . "\n";
}
$return = apply_filters( 'edd_sysinfo_after_session_config', $return );
$return .= "\n" . '### End System Info ###';
return $return;
}
/**
* Generates a System Info download file
*
* @since 2.0
*/
function edd_tools_sysinfo_download() {
if ( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
check_admin_referer( 'edd_download_system_info', 'edd_system_info' );
nocache_headers();
header( 'Content-Type: text/plain' );
header( 'Content-Disposition: attachment; filename="edd-system-info.txt"' );
echo wp_strip_all_tags( $_POST['edd-sysinfo'] );
edd_die();
}
add_action( 'edd_download_sysinfo', 'edd_tools_sysinfo_download' );
/**
* Redirects requests to the old sales log to the orders page.
*

View File

@ -138,6 +138,7 @@ class EDD_Tools_Reset_Stats extends EDD_Batch_Export {
// Reset the sequential order numbers
if ( edd_get_option( 'enable_sequential' ) ) {
delete_option( 'edd_last_payment_number' );
delete_option( 'edd_next_order_number' );
}
$this->done = true;

View File

@ -85,29 +85,6 @@ function edd_logs_view_page( $logs_table, $tag = '' ) {
/** Views *********************************************************************/
/**
* Sales Log View
*
* @deprecated 3.0
*
* @since 1.4
* @uses EDD_Sales_Log_Table::prepare_items()
* @uses EDD_Sales_Log_Table::display()
* @return void
*/
function edd_logs_view_sales() {
// Setup or bail
if ( ! edd_logs_view_setup( 'sales' ) ) {
return;
}
$logs_table = new EDD_Sales_Log_Table();
edd_logs_view_page( $logs_table, 'sales' );
}
add_action( 'edd_logs_view_sales', 'edd_logs_view_sales' );
/**
* File Download Logs
*

View File

@ -0,0 +1,911 @@
<?php
/**
* Converts old sale and file download logs to new logging system
*
* @since 1.3.1
* @deprecated 3.1.2
* @uses WP_Query
* @uses EDD_Logging
* @return void
*/
function edd_v131_upgrades() {
if ( get_option( 'edd_logs_upgraded' ) ) {
return;
}
$edd_version = edd_get_db_version();
if ( version_compare( $edd_version, '1.3', '>=' ) ) {
return;
}
edd_set_time_limit();
$query = new WP_Query( array(
'post_type' => 'download',
'posts_per_page' => -1,
'post_status' => 'publish'
) );
$downloads = $query->get_posts();
if ( $downloads ) {
$edd_log = new EDD_Logging();
foreach ( $downloads as $download ) {
// Convert sale logs
$sale_logs = edd_get_download_sales_log( $download->ID, false );
if ( $sale_logs ) {
foreach ( $sale_logs['sales'] as $sale ) {
$log_data = array(
'post_parent' => $download->ID,
'post_date' => $sale['date'],
'log_type' => 'sale'
);
$log_meta = array(
'payment_id'=> $sale['payment_id']
);
$log = $edd_log->insert_log( $log_data, $log_meta );
}
}
// Convert file download logs
$file_logs = edd_get_file_download_log( $download->ID, false );
if ( $file_logs ) {
foreach ( $file_logs['downloads'] as $log ) {
$log_data = array(
'post_parent' => $download->ID,
'post_date' => $log['date'],
'log_type' => 'file_download'
);
$log_meta = array(
'user_info' => $log['user_info'],
'file_id' => $log['file_id'],
'ip' => $log['ip']
);
$log = $edd_log->insert_log( $log_data, $log_meta );
}
}
}
}
add_option( 'edd_logs_upgraded', '1' );
}
/**
* Upgrade routine for v1.3.0
*
* @since 1.3.0
* @deprecated 3.1.2
* @return void
*/
function edd_v134_upgrades() {
$general_options = get_option( 'edd_settings_general' );
// Settings already updated
if ( isset( $general_options['failure_page'] ) ) {
return;
}
// Failed Purchase Page
$failed = wp_insert_post(
array(
'post_title' => __( 'Transaction Failed', 'easy-digital-downloads' ),
'post_content' => __( 'Your transaction failed, please try again or contact site support.', 'easy-digital-downloads' ),
'post_status' => 'publish',
'post_author' => 1,
'post_type' => 'page',
'post_parent' => $general_options['purchase_page'],
'comment_status' => 'closed'
)
);
$general_options['failure_page'] = $failed;
update_option( 'edd_settings_general', $general_options );
}
/**
* Upgrade routine for v1.4
*
* @since 1.4
* @deprecated 3.1.2
* @global $edd_options Array of all the EDD Options
* @return void
*/
function edd_v14_upgrades() {
/** Add [edd_receipt] to success page **/
$success_page = get_post( edd_get_option( 'success_page' ) );
// Check for the [edd_receipt] shortcode and add it if not present
if ( strpos( $success_page->post_content, '[edd_receipt' ) === false ) {
$page_content = $success_page->post_content .= "\n[edd_receipt]";
wp_update_post( array( 'ID' => edd_get_option( 'success_page' ), 'post_content' => $page_content ) );
}
/** Convert Discounts to new Custom Post Type **/
$discounts = get_option( 'edd_discounts' );
if ( $discounts ) {
foreach ( $discounts as $discount ) {
$discount_id = wp_insert_post( array(
'post_type' => 'edd_discount',
'post_title' => isset( $discount['name'] ) ? $discount['name'] : '',
'post_status' => 'active'
) );
$meta = array(
'code' => isset( $discount['code'] ) ? $discount['code'] : '',
'uses' => isset( $discount['uses'] ) ? $discount['uses'] : '',
'max_uses' => isset( $discount['max'] ) ? $discount['max'] : '',
'amount' => isset( $discount['amount'] ) ? $discount['amount'] : '',
'start' => isset( $discount['start'] ) ? $discount['start'] : '',
'expiration' => isset( $discount['expiration'] ) ? $discount['expiration'] : '',
'type' => isset( $discount['type'] ) ? $discount['type'] : '',
'min_price' => isset( $discount['min_price'] ) ? $discount['min_price'] : ''
);
foreach ( $meta as $meta_key => $value ) {
update_post_meta( $discount_id, '_edd_discount_' . $meta_key, $value );
}
}
// Remove old discounts from database
delete_option( 'edd_discounts' );
}
}
/**
* Upgrade routine for v1.5
*
* @since 1.5
* @deprecated 3.1.2
* @return void
*/
function edd_v15_upgrades() {
// Update options for missing tax settings
$tax_options = get_option( 'edd_settings_taxes' );
// Set include tax on checkout to off
$tax_options['checkout_include_tax'] = 'no';
// Check if prices are displayed with taxes
$tax_options['prices_include_tax'] = isset( $tax_options['taxes_on_prices'] )
? 'yes'
: 'no';
update_option( 'edd_settings_taxes', $tax_options );
// Flush the rewrite rules for the new /edd-api/ end point
flush_rewrite_rules( false );
}
/**
* Upgrades for EDD v2.0
*
* @since 2.0
* @deprecated 3.1.2
* @return void
*/
function edd_v20_upgrades() {
global $edd_options, $wpdb;
edd_set_time_limit();
// Upgrade for the anti-behavior fix - #2188
if ( ! empty( $edd_options['disable_ajax_cart'] ) ) {
unset( $edd_options['enable_ajax_cart'] );
} else {
$edd_options['enable_ajax_cart'] = '1';
}
// Upgrade for the anti-behavior fix - #2188
if ( ! empty( $edd_options['disable_cart_saving'] ) ) {
unset( $edd_options['enable_cart_saving'] );
} else {
$edd_options['enable_cart_saving'] = '1';
}
// Properly set the register / login form options based on whether they were enabled previously - #2076
if ( ! empty( $edd_options['show_register_form'] ) ) {
$edd_options['show_register_form'] = 'both';
} else {
$edd_options['show_register_form'] = 'none';
}
// Remove all old, improperly expired sessions. See https://github.com/easydigitaldownloads/Easy-Digital-Downloads/issues/2031
$wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '_wp_session_expires_%' AND option_value+0 < 2789308218" );
update_option( 'edd_settings', $edd_options );
}
/**
* Upgrades for EDD v2.0 and sequential payment numbers
*
* @deprecated 3.1.1.2 EDD no longer implies that past orders will be updated.
* @since 2.0
* @return void
*/
function edd_v20_upgrade_sequential_payment_numbers() {
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$step = isset( $_GET['step'] ) ? absint( $_GET['step'] ) : 1;
$total = isset( $_GET['total'] ) ? absint( $_GET['total'] ) : false;
if ( empty( $total ) || $total <= 1 ) {
$payments = edd_count_payments();
foreach ( $payments as $status ) {
$total += $status;
}
}
$orders = edd_get_orders( array(
'number' => 100,
'offset' => $step == 1 ? 0 : ( $step - 1 ) * 100,
'order' => 'asc',
) );
if ( $orders ) {
$prefix = edd_get_option( 'sequential_prefix' );
$postfix = edd_get_option( 'sequential_postfix' );
$number = ! empty( $_GET['custom'] ) ? absint( $_GET['custom'] ) : intval( edd_get_option( 'sequential_start', 1 ) );
foreach ( $orders as $order ) {
// Re-add the prefix and postfix
$payment_number = $prefix . $number . $postfix;
edd_update_order( $order->id, array(
'order_number' => $payment_number
) );
// Increment the payment number
$number++;
}
// Payments found so upgrade them
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'upgrade_sequential_payment_numbers',
'step' => urlencode( $step ),
'custom' => urlencode( $number ),
'total' => urlencode( $total ),
), admin_url( 'index.php' ) );
edd_redirect( $redirect );
// No more payments found, finish up
} else {
delete_option( 'edd_upgrade_sequential' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/**
* Upgrades for EDD v2.1 and the new customers database
*
* @since 2.1
* @deprecated 3.1.2 EDD no longer implies that past orders will be updated.
* @return void
*/
function edd_v21_upgrade_customers_db() {
global $wpdb;
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$number = 20;
$step = isset( $_GET['step'] )
? absint( $_GET['step'] )
: 1;
$offset = $step == 1
? 0
: ( $step - 1 ) * $number;
$emails = $wpdb->get_col( $wpdb->prepare( "SELECT DISTINCT meta_value FROM {$wpdb->postmeta} WHERE meta_key = '_edd_payment_user_email' LIMIT %d,%d;", $offset, $number ) );
if ( $emails ) {
foreach ( $emails as $email ) {
if ( EDD()->customers->exists( $email ) ) {
continue; // Allow the upgrade routine to be safely re-run in the case of failure
}
$payments = new EDD_Payments_Query( array(
'user' => $email,
'order' => 'ASC',
'orderby' => 'ID',
'number' => 9999999,
'page' => $step
) );
$payments = $payments->get_payments();
if ( $payments ) {
$total_value = 0.00;
$total_count = 0;
foreach ( $payments as $payment ) {
if ( 'revoked' == $payment->status || 'complete' == $payment->status ) {
$total_value += $payment->total;
$total_count += 1;
}
}
$ids = wp_list_pluck( $payments, 'ID' );
$user = get_user_by( 'email', $email );
$args = array(
'email' => $email,
'user_id' => $user ? $user->ID : 0,
'name' => $user ? $user->display_name : '',
'purchase_count' => $total_count,
'purchase_value' => round( $total_value, 2 ),
'payment_ids' => implode( ',', array_map( 'absint', $ids ) ),
'date_created' => $payments[0]->date
);
$customer_id = EDD()->customers->add( $args );
foreach ( $ids as $id ) {
update_post_meta( $id, '_edd_payment_customer_id', $customer_id );
}
}
}
// Customers found so upgrade them
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'upgrade_customers_db',
'step' => urlencode( $step ),
), admin_url( 'index.php' ) );
edd_redirect( $redirect );
// No more customers found, finish up
} else {
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/**
* Fixes the edd_log meta for 2.2.6
*
* @since 2.2.6
* @deprecated 3.1.2 EDD no longer implies that past orders will be updated.
* @return void
*/
function edd_v226_upgrade_payments_price_logs_db() {
global $wpdb;
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$number = 25;
$step = isset( $_GET['step'] )
? absint( $_GET['step'] )
: 1;
$offset = $step == 1
? 0
: ( $step - 1 ) * $number;
if ( 1 === $step ) {
// Check if we have any variable price products on the first step
$sql = "SELECT ID FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} m ON p.ID = m.post_id WHERE m.meta_key = '_variable_pricing' AND m.meta_value = 1 LIMIT 1";
$has_variable = $wpdb->get_col( $sql );
if ( empty( $has_variable ) ) {
// We had no variable priced products, so go ahead and just complete
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
$payment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'edd_payment' ORDER BY post_date DESC LIMIT %d,%d;", $offset, $number ) );
if ( ! empty( $payment_ids ) ) {
foreach ( $payment_ids as $payment_id ) {
$payment_downloads = edd_get_payment_meta_downloads( $payment_id );
$variable_downloads = array();
// May not be an array due to some very old payments, move along
if ( ! is_array( $payment_downloads ) ) {
continue;
}
foreach ( $payment_downloads as $download ) {
// Don't care if the download is a single price id
if ( ! isset( $download['options']['price_id'] ) ) {
continue;
}
$variable_downloads[] = array( 'id' => $download['id'], 'price_id' => $download['options']['price_id'] );
}
$variable_download_ids = array_unique( wp_list_pluck( $variable_downloads, 'id' ) );
$unique_download_ids = implode( ',', $variable_download_ids );
// If there were no downloads, just fees, move along
if ( empty( $unique_download_ids ) ) {
continue;
}
// Get all Log Ids where the post parent is in the set of download IDs we found in the cart meta
$logs = $wpdb->get_results( "SELECT m.post_id AS log_id, p.post_parent AS download_id FROM {$wpdb->postmeta} m LEFT JOIN {$wpdb->posts} p ON m.post_id = p.ID WHERE meta_key = '_edd_log_payment_id' AND meta_value = $payment_id AND p.post_parent IN ($unique_download_ids)", ARRAY_A );
$mapped_logs = array();
// Go through each cart item
foreach ( $variable_downloads as $cart_item ) {
// Itterate through the logs we found attached to this payment
foreach ( $logs as $key => $log ) {
// If this Log ID is associated with this download ID give it the price_id
if ( (int) $log['download_id'] === (int) $cart_item['id'] ) {
$mapped_logs[$log['log_id']] = $cart_item['price_id'];
// Remove this Download/Log ID from the list, for multipurchase compatibility
unset( $logs[$key] );
// These aren't the logs we're looking for. Move Along, Move Along.
break;
}
}
}
if ( ! empty( $mapped_logs ) ) {
$update = "UPDATE {$wpdb->postmeta} SET meta_value = ";
$case = "CASE post_id ";
foreach ( $mapped_logs as $post_id => $value ) {
$case .= "WHEN {$post_id} THEN {$value} ";
}
$case .= "END ";
$log_ids = implode( ',', array_keys( $mapped_logs ) );
$where = "WHERE post_id IN ({$log_ids}) AND meta_key = '_edd_log_price_id'";
$sql = $update . $case . $where;
// Execute our query to update this payment
$wpdb->query( $sql );
}
}
// More Payments found so upgrade them
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'upgrade_payments_price_logs_db',
'step' => urlencode( $step ),
), admin_url( 'index.php' ) );
edd_redirect( $redirect );
} else {
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/**
* Upgrades payment taxes for 2.3
*
* @since 2.3
* @deprecated 3.1.2 EDD no longer implies that past orders will be updated.
* @return void
*/
function edd_v23_upgrade_payment_taxes() {
global $wpdb;
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$number = 50;
$step = isset( $_GET['step'] )
? absint( $_GET['step'] )
: 1;
$offset = $step == 1
? 0
: ( $step - 1 ) * $number;
if ( $step < 2 ) {
// Check if we have any payments before moving on
$sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'edd_payment' LIMIT 1";
$has_payments = $wpdb->get_col( $sql );
if ( empty( $has_payments ) ) {
// We had no payments, just complete
edd_set_upgrade_complete( 'upgrade_payment_taxes' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
$total = isset( $_GET['total'] ) ? absint( $_GET['total'] ) : false;
if ( empty( $total ) || $total <= 1 ) {
$total_sql = "SELECT COUNT(ID) as total_payments FROM {$wpdb->posts} WHERE post_type = 'edd_payment'";
$results = $wpdb->get_row( $total_sql, 0 );
$total = $results->total_payments;
}
$payment_ids = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'edd_payment' ORDER BY post_date DESC LIMIT %d,%d;", $offset, $number ) );
if ( $payment_ids ) {
// Add the new _edd_payment_meta item
foreach ( $payment_ids as $payment_id ) {
$payment_tax = edd_get_payment_tax( $payment_id );
edd_update_payment_meta( $payment_id, '_edd_payment_tax', $payment_tax );
}
// Payments found so upgrade them
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'upgrade_payment_taxes',
'step' => urlencode( $step ),
'number' => urlencode( $number ),
'total' => urlencode( $total ),
), admin_url( 'index.php' ) );
edd_redirect( $redirect );
// No more payments found, finish up
} else {
edd_set_upgrade_complete( 'upgrade_payment_taxes' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/**
* Run the upgrade for the customers to find all payment attachments
*
* @since 2.3
* @deprecated 3.1.2 EDD no longer implies that past orders will be updated.
* @return void
*/
function edd_v23_upgrade_customer_purchases() {
global $wpdb;
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$number = 50;
$step = isset( $_GET['step'] )
? absint( $_GET['step'] )
: 1;
$offset = $step == 1
? 0
: ( $step - 1 ) * $number;
if ( $step < 2 ) {
// Check if we have any payments before moving on
$sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'edd_payment' LIMIT 1";
$has_payments = $wpdb->get_col( $sql );
if ( empty( $has_payments ) ) {
// We had no payments, just complete
edd_set_upgrade_complete( 'upgrade_customer_payments_association' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
$total = isset( $_GET['total'] ) ? absint( $_GET['total'] ) : false;
if ( empty( $total ) || $total <= 1 ) {
$total = EDD()->customers->count();
}
$customers = edd_get_customers( array( 'number' => $number, 'offset' => $offset ) );
if ( ! empty( $customers ) ) {
foreach ( $customers as $customer ) {
// Get payments by email and user ID
$select = "SELECT ID FROM {$wpdb->posts} p ";
$join = "LEFT JOIN {$wpdb->postmeta} m ON p.ID = m.post_id ";
$where = "WHERE p.post_type = 'edd_payment' ";
if ( ! empty( $customer->user_id ) && intval( $customer->user_id ) > 0 ) {
$where .= "AND ( ( m.meta_key = '_edd_payment_user_email' AND m.meta_value = '{$customer->email}' ) OR ( m.meta_key = '_edd_payment_customer_id' AND m.meta_value = '{$customer->id}' ) OR ( m.meta_key = '_edd_payment_user_id' AND m.meta_value = '{$customer->user_id}' ) )";
} else {
$where .= "AND ( ( m.meta_key = '_edd_payment_user_email' AND m.meta_value = '{$customer->email}' ) OR ( m.meta_key = '_edd_payment_customer_id' AND m.meta_value = '{$customer->id}' ) ) ";
}
$sql = $select . $join . $where;
$found_payments = $wpdb->get_col( $sql );
$unique_payment_ids = array_unique( array_filter( $found_payments ) );
if ( ! empty( $unique_payment_ids ) ) {
$unique_ids_string = implode( ',', $unique_payment_ids );
$customer_data = array( 'payment_ids' => $unique_ids_string );
$purchase_value_sql = "SELECT SUM( m.meta_value ) FROM {$wpdb->postmeta} m LEFT JOIN {$wpdb->posts} p ON m.post_id = p.ID WHERE m.post_id IN ( {$unique_ids_string} ) AND p.post_status IN ( 'publish', 'revoked' ) AND m.meta_key = '_edd_payment_total'";
$purchase_value = $wpdb->get_col( $purchase_value_sql );
$purchase_count_sql = "SELECT COUNT( m.post_id ) FROM {$wpdb->postmeta} m LEFT JOIN {$wpdb->posts} p ON m.post_id = p.ID WHERE m.post_id IN ( {$unique_ids_string} ) AND p.post_status IN ( 'publish', 'revoked' ) AND m.meta_key = '_edd_payment_total'";
$purchase_count = $wpdb->get_col( $purchase_count_sql );
if ( ! empty( $purchase_value ) && ! empty( $purchase_count ) ) {
$purchase_value = $purchase_value[0];
$purchase_count = $purchase_count[0];
$customer_data['purchase_count'] = $purchase_count;
$customer_data['purchase_value'] = $purchase_value;
}
} else {
$customer_data['purchase_count'] = 0;
$customer_data['purchase_value'] = 0;
$customer_data['payment_ids'] = '';
}
if ( ! empty( $customer_data ) ) {
$customer = new EDD_Customer( $customer->id );
$customer->update( $customer_data );
}
}
// More Payments found so upgrade them
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'upgrade_customer_payments_association',
'step' => urlencode( $step ),
'number' => urlencode( $number ),
'total' => urlencode( $total ),
), admin_url( 'index.php' ) );
edd_redirect( $redirect );
// No more customers found, finish up
} else {
edd_set_upgrade_complete( 'upgrade_customer_payments_association' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/**
* Upgrade the User meta API Key storage to swap keys/values for performance
*
* @since 2.4
* @deprecated 3.1.2
* @return void
*/
function edd_upgrade_user_api_keys() {
global $wpdb;
if ( ! current_user_can( 'manage_shop_settings' ) ) {
wp_die( __( 'You do not have permission to do shop upgrades', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_set_time_limit();
$number = 10;
$step = isset( $_GET['step'] )
? absint( $_GET['step'] )
: 1;
$offset = $step == 1
? 0
: ( $step - 1 ) * $number;
if ( $step < 2 ) {
// Check if we have any users with API Keys before moving on
$sql = "SELECT user_id FROM $wpdb->usermeta WHERE meta_key = 'edd_user_public_key' LIMIT 1";
$has_key = $wpdb->get_col( $sql );
// We had no key, just complete
if ( empty( $has_key ) ) {
edd_set_upgrade_complete( 'upgrade_user_api_keys' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
$total = isset( $_GET['total'] )
? absint( $_GET['total'] )
: false;
if ( empty( $total ) || $total <= 1 ) {
$total = $wpdb->get_var( "SELECT count(user_id) FROM $wpdb->usermeta WHERE meta_key = 'edd_user_public_key'" );
}
$keys_sql = $wpdb->prepare( "SELECT user_id, meta_key, meta_value FROM $wpdb->usermeta WHERE meta_key = 'edd_user_public_key' OR meta_key = 'edd_user_secret_key' ORDER BY user_id ASC LIMIT %d,%d;", $offset, $number );
$found_keys = $wpdb->get_results( $keys_sql );
if ( ! empty( $found_keys ) ) {
foreach ( $found_keys as $key ) {
$user_id = $key->user_id;
$meta_key = $key->meta_key;
$meta_value = $key->meta_value;
// Generate a new entry
update_user_meta( $user_id, $meta_value, $meta_key );
// Delete the old one
delete_user_meta( $user_id, $meta_key );
}
// More Payments found so upgrade them
$step++;
$redirect = add_query_arg( array(
'page' => 'edd-upgrades',
'edd-upgrade' => 'upgrade_user_api_keys',
'step' => urlencode( $step ),
'number' => urlencode( $number ),
'total' => urlencode( $total ) ) );
edd_redirect( $redirect );
// No more customers found, finish up
} else {
edd_set_upgrade_complete( 'upgrade_user_api_keys' );
delete_option( 'edd_doing_upgrade' );
edd_redirect( admin_url() );
}
}
/** 2.9.2 Upgrades ***********************************************************/
/**
* Output the results of the file-download log data update
*
* @since 2.9.2
* @deprecated 3.1.2
*/
function edd_upgrade_render_update_file_download_log_data() {
$migration_complete = edd_has_upgrade_completed( 'update_file_download_log_data' );
if ( $migration_complete ) : ?>
<div id="edd-sl-migration-complete" class="notice notice-success">
<p>
<?php _e( '<strong>Migration complete:</strong> You have already completed the update to the file download logs.', 'easy-digital-downloads' ); ?>
</p>
</div>
<?php
delete_option( 'edd_doing_upgrade' );
return;
endif; ?>
<div id="edd-migration-ready" class="notice notice-success" style="display: none;">
<p><?php _e( '<strong>Upgrades Complete:</strong> You may now safely navigate away from this page.', 'easy-digital-downloads' ); ?></p>
</div>
<div id="edd-migration-nav-warn" class="notice notice-warning">
<p><?php _e( '<strong>Important:</strong> Do not navigate away from this page until all upgrades complete.', 'easy-digital-downloads' ); ?></p>
</div>
<style>
.dashicons.dashicons-yes {
display: none;
color: rgb(0, 128, 0);
vertical-align: middle;
}
</style>
<script>
jQuery( function($) {
$(document).ready(function () {
$(document).on("DOMNodeInserted", function (e) {
var element = e.target;
if (element.id === 'edd-batch-success') {
element = $(element);
element.parent().prev().find('.edd-migration.allowed').hide();
element.parent().prev().find('.edd-migration.unavailable').show();
var element_wrapper = element.parents().eq(4),
next_step_wrapper = element_wrapper.next();
element_wrapper.find('.dashicons.dashicons-yes').show();
if (next_step_wrapper.find('.postbox').length) {
next_step_wrapper.find('.edd-migration.allowed').show();
next_step_wrapper.find('.edd-migration.unavailable').hide();
if (auto_start_next_step) {
next_step_wrapper.find('.edd-export-form').submit();
}
} else {
$('#edd-migration-nav-warn').hide();
$('#edd-migration-ready').slideDown();
}
}
});
});
});
</script>
<div class="metabox-holder">
<div class="postbox">
<h2 class="hndle">
<span><?php _e( 'Update file download logs', 'easy-digital-downloads' ); ?></span>
<span class="dashicons dashicons-yes"></span>
</h2>
<div class="inside migrate-file-download-logs-control">
<p>
<?php _e( 'This will update the file download logs to remove some <abbr title="Personally Identifiable Information">PII</abbr> and make file download counts more accurate.', 'easy-digital-downloads' ); ?>
</p>
<form method="post" id="edd-fix-file-download-logs-form" class="edd-export-form edd-import-export-form">
<span class="step-instructions-wrapper">
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
<?php if ( ! $migration_complete ) : ?>
<span class="edd-migration allowed">
<input type="submit" id="migrate-logs-submit" value="<?php _e( 'Update File Download Logs', 'easy-digital-downloads' ); ?>" class="button-primary"/>
</span>
<?php else: ?>
<input type="submit" disabled id="migrate-logs-submit" value="<?php _e( 'Update File Download Logs', 'easy-digital-downloads' ); ?>" class="button-secondary"/>
&mdash; <?php _e( 'File download logs have already been updated.', 'easy-digital-downloads' ); ?>
<?php endif; ?>
<input type="hidden" name="edd-export-class" value="EDD_File_Download_Log_Migration" />
<span class="spinner"></span>
</span>
</form>
</div><!-- .inside -->
</div><!-- .postbox -->
</div>
<?php
}
/**
* Register the batch file-download log migration
*
* @since 2.9.2
* @deprecated 3.1.2
*/
function edd_register_batch_file_download_log_migration() {
add_action( 'edd_batch_export_class_include', 'edd_include_file_download_log_migration_batch_processor', 10, 1 );
}
/**
* Include the file-download log batch processor
*
* @since 2.9.2
* @deprecated 3.1.2
*
* @param string $class
*/
function edd_include_file_download_log_migration_batch_processor( $class = '' ) {
if ( 'EDD_File_Download_Log_Migration' === $class ) {
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/classes/class-file-download-log-migration.php';
}
}

View File

@ -76,12 +76,17 @@ function edd_upgrades_screen() {
if ( ! empty( $action ) ) :
// Redirect URL
$redirect = add_query_arg( array(
'edd_action' => sanitize_key( $action ),
'step' => absint( $step ),
'total' => absint( $total ),
'custom' => absint( $custom ),
), admin_url( 'index.php' ) ); ?>
$redirect = add_query_arg(
array(
'edd_action' => sanitize_key( $action ),
'step' => absint( $step ),
'total' => absint( $total ),
'custom' => absint( $custom ),
'_wpnonce' => wp_create_nonce( 'edd-upgrade' ),
),
admin_url( 'index.php' )
);
?>
<div id="edd-upgrade-status">
<p><?php _e( 'The upgrade process has started, please be patient. This could take several minutes. You will be automatically redirected when the upgrade is finished.', 'easy-digital-downloads' ); ?></p>
@ -113,7 +118,8 @@ function edd_upgrades_screen() {
// Trigger upgrades on page load
var data = {
action: 'edd_trigger_upgrades'
action: 'edd_trigger_upgrades',
nonce: '<?php echo esc_attr( wp_create_nonce( 'edd-upgrade' ) ); ?>'
};
jQuery.post( ajaxurl, data, function (response) {

View File

@ -753,14 +753,11 @@ class Data_Migrator {
*/
$order_data = apply_filters( 'edd_30_migration_order_creation_data', $order_data, $payment_meta, $cart_details, $meta );
update_option( '_edd_v30_doing_order_migration', true, false );
// Remove all order status transition actions.
remove_all_actions( 'edd_transition_order_status' );
remove_all_actions( 'edd_transition_order_item_status' );
remove_action( 'edd_order_item_added', 'edd_recalculate_order_item_download' );
remove_action( 'edd_order_item_updated', 'edd_recalculate_order_item_download' );
remove_action( 'edd_order_item_deleted', 'edd_recalculate_order_item_download' );
remove_action( 'edd_order_adjustment_added', 'edd_recalculate_order_adjustment_download' );
remove_action( 'edd_order_adjustment_updated', 'edd_recalculate_order_adjustment_download' );
$order_id = edd_add_order( $order_data );
@ -1351,6 +1348,8 @@ class Data_Migrator {
*/
do_action( 'edd_30_migrate_order', $order_id, $payment_meta, $meta );
delete_option( '_edd_v30_doing_order_migration' );
return $order_id;
}

View File

@ -92,6 +92,26 @@ class Orders extends Base {
}
}
/**
* Recalculates all customer values.
*
* @since 3.1.2
* @return void
*/
private function recalculate_customer_values() {
$customers = edd_get_customers(
array(
'number' => 9999999,
)
);
if ( ! empty( $customers ) ) {
foreach ( $customers as $customer ) {
$customer->recalculate_stats();
}
}
}
/**
* Calculate the percentage completed.
*

View File

@ -29,9 +29,6 @@ $view_url = edd_get_admin_url(
<# } #>
<div>
<# if ( false !== data.orderItem ) { #>
{{ data.orderItem.productName }}:&nbsp;
<# } #>
<# if ( '' !== data.description ) { #>
{{ data.description }}
<# } #>
@ -40,7 +37,9 @@ $view_url = edd_get_admin_url(
<br />
<small>
<# } #>
<# if ( 'credit' === data.type ) { #>
<# if ( false !== data.orderItem ) { #>
<?php esc_html_e( 'Fee', 'easy-digital-downloads' ); ?>: {{ data.orderItem.productName }}
<# } else if ( 'credit' === data.type ) { #>
<?php esc_html_e( 'Order Credit', 'easy-digital-downloads' ); ?>
<# } else { #>
<?php esc_html_e( 'Order Fee', 'easy-digital-downloads' ); ?>

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '75153cfac5e884f38a28');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '9575575720727823baf2');

View File

@ -1 +1 @@
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .components-placeholder a.components-button.edd-new-download{background-color:var(--wp-admin-theme-color)!important;color:#fff!important;line-height:1.5;margin:0 auto!important;padding:.5em 1em;text-decoration:none}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder{align-items:center;background-color:#fefefe;border-radius:5px}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder__fieldset{justify-content:center}
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .components-placeholder{align-items:center;background-color:#fefefe;border-radius:5px}.editor-styles-wrapper .components-placeholder__fieldset{justify-content:center}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions{display:flex;gap:2em;justify-content:space-around}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions a.components-button{line-height:1.5;margin-right:0;padding:.5em 1em;text-decoration:none}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions a.components-button.edd-downloads--primary{background-color:var(--wp-admin-theme-color);color:#fff}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions a.components-button.edd-downloads--secondary{background-color:#fff;border:1px solid var(--wp-admin-theme-color);color:var(--wp-admin-theme-color)}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder{align-items:center;background-color:#fefefe;border-radius:5px}.editor-styles-wrapper .wp-block.wp-block-edd-buy-button .components-placeholder__fieldset{justify-content:center}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.edd-blocks-form__cart .edd_cart_remove_item_btn{border:none;margin-left:.5rem;padding:0;text-decoration:none}.edd-blocks-form__cart .edd_cart_remove_item_btn svg{opacity:.6}.edd-blocks-form__cart .edd_cart_remove_item_btn svg:hover{opacity:.9}.edd-blocks-form__cart #edd_checkout_cart{border:1px solid #eee;display:grid}.edd-blocks-form__cart .edd_cart_item_name{display:grid;gap:1rem}.edd-blocks-form__cart .edd_cart_item_name .edd_cart_actions{align-items:center;display:inline-flex;flex-basis:100%;gap:.5rem}.edd-blocks-form__cart .edd_cart_item_name .edd_cart_actions label{margin:0!important}.edd-blocks-form__cart .edd_cart_item_name .edd_cart_actions input.edd-item-quantity{width:3rem!important}.edd-blocks-form__cart .edd_checkout_cart_item_title{align-items:center;display:flex;gap:1rem}.edd-blocks-form__cart .edd_cart_fee_amount,.edd-blocks-form__cart .edd_cart_item_price{align-items:center;display:flex;gap:.5rem}@media(min-width:480px){.edd-blocks-form__cart .edd_cart_fee_amount,.edd-blocks-form__cart .edd_cart_item_price{justify-content:flex-end}}.edd-blocks-form__cart .edd-blocks-cart__row{align-items:center;display:flex;flex-wrap:wrap;gap:1rem;padding:1.5rem}.edd-blocks-form__cart .edd-blocks-cart__row>div:last-of-type:not(:first-of-type){flex:1 1 110px}@media(min-width:480px){.edd-blocks-form__cart .edd-blocks-cart__row>div:last-of-type:not(:first-of-type){text-align:right}}.edd-blocks-form__cart .edd-blocks-cart__items,.edd-blocks-form__cart .edd-blocks-cart__row-header{border-bottom:1px solid #eee}.edd-blocks-form__cart .edd-blocks-cart__row-header,.edd-blocks-form__cart .edd_cart_total{font-weight:700}.edd-blocks-form__cart .edd-blocks-cart__row-footer{text-align:right}.edd-blocks-form__cart .edd-blocks-cart__row-footer>div:only-child{flex-grow:1}.edd-blocks-form__cart .edd-blocks-cart__action-remove,.edd-blocks-form__cart .edd_discount_remove{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMWVtIiBoZWlnaHQ9IjFlbSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2U9ImN1cnJlbnRDb2xvciIgY2xhc3M9InctNiBoLTYiPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTE0Ljc0IDlsLS4zNDYgOW0tNC43ODggMEw5LjI2IDltOS45NjgtMy4yMWMuMzQyLjA1Mi42ODIuMTA3IDEuMDIyLjE2Nm0tMS4wMjItLjE2NUwxOC4xNiAxOS42NzNhMi4yNSAyLjI1IDAgMDEtMi4yNDQgMi4wNzdIOC4wODRhMi4yNSAyLjI1IDAgMDEtMi4yNDQtMi4wNzdMNC43NzIgNS43OW0xNC40NTYgMGE0OC4xMDggNDguMTA4IDAgMDAtMy40NzgtLjM5N20tMTIgLjU2MmMuMzQtLjA1OS42OC0uMTE0IDEuMDIyLS4xNjVtMCAwYTQ4LjExIDQ4LjExIDAgMDEzLjQ3OC0uMzk3bTcuNSAwdi0uOTE2YzAtMS4xOC0uOTEtMi4xNjQtMi4wOS0yLjIwMWE1MS45NjQgNTEuOTY0IDAgMDAtMy4zMiAwYy0xLjE4LjAzNy0yLjA5IDEuMDIyLTIuMDkgMi4yMDF2LjkxNm03LjUgMGE0OC42NjcgNDguNjY3IDAgMDAtNy41IDAiIC8+Cjwvc3ZnPgo=) 50% no-repeat;background-size:1em;box-shadow:none!important;display:block;height:1em;opacity:.6;top:0;width:1em}.edd-blocks-form__cart .edd-blocks-cart__action-remove:hover,.edd-blocks-form__cart .edd_discount_remove:hover{background-position:50%;opacity:1}.edd-blocks-form__cart .edd_cart_item_image img{display:block}.edd-blocks__cart-mini,.edd-blocks__cart-mini a{align-items:center;color:unset;display:flex;gap:.25rem;justify-content:flex-end;text-decoration:none}.edd-blocks__cart-mini a svg,.edd-blocks__cart-mini svg{fill:none;height:1.5rem;width:1.5rem}.wp-block-edd-cart .edd-blocks-cart__row-footer{padding:.5rem 1.5rem}
.edd-blocks-form__cart .edd_cart_remove_item_btn{border:none;margin-left:.5rem;padding:0;text-decoration:none}.edd-blocks-form__cart .edd_cart_remove_item_btn svg{opacity:.6}.edd-blocks-form__cart .edd_cart_remove_item_btn svg:hover{opacity:.9}.edd-blocks-form__cart #edd_checkout_cart{border:1px solid #eee;display:grid}.edd-blocks-form__cart .edd_cart_item_name{display:grid;gap:1rem}.edd-blocks-form__cart .edd_cart_item_name .edd_cart_actions{align-items:center;display:inline-flex;flex-basis:100%;gap:.5rem}.edd-blocks-form__cart .edd_cart_item_name .edd_cart_actions label{margin:0!important}.edd-blocks-form__cart .edd_cart_item_name .edd_cart_actions input.edd-item-quantity{width:3rem!important}.edd-blocks-form__cart .edd_checkout_cart_item_title{align-items:center;display:flex;gap:1rem}.edd-blocks-form__cart .edd_cart_fee_amount,.edd-blocks-form__cart .edd_cart_item_price{align-items:center;display:flex;gap:.5rem}@media(min-width:480px){.edd-blocks-form__cart .edd_cart_fee_amount,.edd-blocks-form__cart .edd_cart_item_price{justify-content:flex-end}}.edd-blocks-form__cart .edd-blocks-cart__row,.edd-blocks-form__cart .edd_cart_footer_row{align-items:center;display:flex;flex-wrap:wrap;gap:1rem;padding:1.5rem}.edd-blocks-form__cart .edd-blocks-cart__row>div:last-of-type:not(:first-of-type),.edd-blocks-form__cart .edd_cart_footer_row>div:last-of-type:not(:first-of-type){flex:1 1 110px}@media(min-width:480px){.edd-blocks-form__cart .edd-blocks-cart__row>div:last-of-type:not(:first-of-type),.edd-blocks-form__cart .edd_cart_footer_row>div:last-of-type:not(:first-of-type){text-align:right}}.edd-blocks-form__cart .edd-blocks-cart__items,.edd-blocks-form__cart .edd-blocks-cart__row-header{border-bottom:1px solid #eee}.edd-blocks-form__cart .edd-blocks-cart__row-header,.edd-blocks-form__cart .edd_cart_total{font-weight:700}.edd-blocks-form__cart .edd-blocks-cart__row-footer{text-align:right}.edd-blocks-form__cart .edd-blocks-cart__row-footer>div:only-child{flex-grow:1}.edd-blocks-form__cart .edd-blocks-cart__action-remove,.edd-blocks-form__cart .edd_discount_remove{background:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMWVtIiBoZWlnaHQ9IjFlbSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBmaWxsPSJub25lIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2U9ImN1cnJlbnRDb2xvciIgY2xhc3M9InctNiBoLTYiPgogIDxwYXRoIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgZD0iTTE0Ljc0IDlsLS4zNDYgOW0tNC43ODggMEw5LjI2IDltOS45NjgtMy4yMWMuMzQyLjA1Mi42ODIuMTA3IDEuMDIyLjE2Nm0tMS4wMjItLjE2NUwxOC4xNiAxOS42NzNhMi4yNSAyLjI1IDAgMDEtMi4yNDQgMi4wNzdIOC4wODRhMi4yNSAyLjI1IDAgMDEtMi4yNDQtMi4wNzdMNC43NzIgNS43OW0xNC40NTYgMGE0OC4xMDggNDguMTA4IDAgMDAtMy40NzgtLjM5N20tMTIgLjU2MmMuMzQtLjA1OS42OC0uMTE0IDEuMDIyLS4xNjVtMCAwYTQ4LjExIDQ4LjExIDAgMDEzLjQ3OC0uMzk3bTcuNSAwdi0uOTE2YzAtMS4xOC0uOTEtMi4xNjQtMi4wOS0yLjIwMWE1MS45NjQgNTEuOTY0IDAgMDAtMy4zMiAwYy0xLjE4LjAzNy0yLjA5IDEuMDIyLTIuMDkgMi4yMDF2LjkxNm03LjUgMGE0OC42NjcgNDguNjY3IDAgMDAtNy41IDAiIC8+Cjwvc3ZnPgo=) 50% no-repeat;background-size:1em;box-shadow:none!important;display:block;height:1em;opacity:.6;top:0;width:1em}.edd-blocks-form__cart .edd-blocks-cart__action-remove:hover,.edd-blocks-form__cart .edd_discount_remove:hover{background-position:50%;opacity:1}.edd-blocks-form__cart .edd_cart_item_image img{display:block}.edd-blocks__cart-mini,.edd-blocks__cart-mini a{align-items:center;color:unset;display:flex;gap:.25rem;justify-content:flex-end;text-decoration:none}.edd-blocks__cart-mini a svg,.edd-blocks__cart-mini svg{fill:none;height:1.5rem;width:1.5rem}.wp-block-edd-cart .edd-blocks-cart__row-footer{padding:.5rem 1.5rem}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '2066313c4795ca117892');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '21903bcd30e08c89eb77');

View File

@ -1 +1 @@
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .components-placeholder a.components-button.edd-new-download{background-color:var(--wp-admin-theme-color)!important;color:#fff!important;line-height:1.5;margin:0 auto!important;padding:.5em 1em;text-decoration:none}.edd-blocks-term-selector select{min-height:60px!important}.edd-blocks-term-selector svg{display:none!important}
.edd-no-js{display:none!important}svg.edd-blocks__icon{fill:none!important}.editor-styles-wrapper .components-placeholder{align-items:center;background-color:#fefefe;border-radius:5px}.editor-styles-wrapper .components-placeholder__fieldset{justify-content:center}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions{display:flex;gap:2em;justify-content:space-around}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions a.components-button{line-height:1.5;margin-right:0;padding:.5em 1em;text-decoration:none}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions a.components-button.edd-downloads--primary{background-color:var(--wp-admin-theme-color);color:#fff}.editor-styles-wrapper .components-placeholder div.edd-downloads--actions a.components-button.edd-downloads--secondary{background-color:#fff;border:1px solid var(--wp-admin-theme-color);color:var(--wp-admin-theme-color)}.edd-blocks-term-selector select{min-height:60px!important}.edd-blocks-term-selector svg{display:none!important}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'b5c8776e3d561d9f287e');
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'db173b2cb95eaab8c3ff');

File diff suppressed because one or more lines are too long

View File

@ -4,7 +4,7 @@
* Description: Core blocks for Easy Digital Downloads.
* Requires at least: 5.8
* Requires PHP: 7.0
* Version: 2.0.6
* Version: 2.0.7
* Author: Easy Digital Downloads
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html

View File

@ -44,7 +44,7 @@ function register_keys( $settings ) {
$settings['main']['recaptcha_secret_key'] = array(
'id' => 'recaptcha_secret_key',
'name' => __( 'reCAPTCHA Secret Key', 'easy-digital-downloads' ),
'type' => 'text',
'type' => 'password',
'std' => '',
);

View File

@ -12,13 +12,29 @@ add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\localize' );
*/
function localize() {
$user = wp_get_current_user();
$downloads = new \WP_Query(
array(
'post_type' => 'download',
'posts_per_page' => 1,
'post_status' => 'any',
'no_found_rows' => true,
$user = wp_get_current_user();
$download_query_args = array(
'post_type' => 'download',
'posts_per_page' => 1,
'no_found_rows' => true,
);
$published_downloads = new \WP_Query(
array_merge(
$download_query_args,
array(
'post_status' => array( 'publish' ),
)
)
);
$draft_downloads = new \WP_Query(
array_merge(
$download_query_args,
array(
'post_status' => array( 'draft' ),
)
)
);
@ -26,14 +42,18 @@ function localize() {
'wp-block-editor',
'EDDBlocks',
array(
'current_user' => md5( $user->user_email ),
'all_access' => function_exists( 'edd_all_access' ),
'recurring' => function_exists( 'EDD_Recurring' ),
'is_pro' => edd_is_pro(),
'no_redownload' => edd_no_redownload(),
'supports_buy_now' => edd_shop_supports_buy_now(),
'has_downloads' => $downloads->have_posts(),
'new_download' => add_query_arg( 'post_type', 'download', admin_url( 'post-new.php' ) ),
'current_user' => md5( $user->user_email ),
'all_access' => function_exists( 'edd_all_access' ),
'recurring' => function_exists( 'EDD_Recurring' ),
'is_pro' => edd_is_pro(),
'no_redownload' => edd_no_redownload(),
'supports_buy_now' => edd_shop_supports_buy_now(),
'has_published_downloads' => $published_downloads->have_posts(),
'has_draft_downloads' => $draft_downloads->have_posts(),
'new_download_link' => add_query_arg( 'post_type', 'download', admin_url( 'post-new.php' ) ),
'view_downloads_link' => add_query_arg( 'post_type', 'download', admin_url( 'edit.php' ) ),
'download_label_singular' => edd_get_label_singular(),
'download_label_plural' => edd_get_label_plural(),
)
);
}

View File

@ -42,3 +42,27 @@ function get_quantity_string() {
_n( 'item', 'items', $quantity, 'easy-digital-downloads' )
);
}
/**
* Outputs the additional cart data. Table markup is replaced.
*
* @since 2.0
* @param string $action The action being called.
* @param mixed $args
* @return string
*/
function do_cart_action( $action = 'edd_cart_items_after', ...$args ) {
ob_start();
do_action( $action, $args );
$details = ob_get_clean();
if ( empty( $details ) ) {
return;
}
$details = str_replace( '<tr', '<div', $details );
$details = str_replace( '</tr', '</div', $details );
$details = str_replace( '<td', '<div', $details );
$details = str_replace( '</td', '</div', $details );
echo wp_kses_post( $details );
}

View File

@ -413,11 +413,13 @@ function get_purchased_products( $block_attributes ) {
return false;
}
$downloads = array();
$valid_items = array();
$downloads = array();
foreach ( $items as $item ) {
if ( edd_is_bundled_product( $item->product_id ) ) {
$key = ! empty( $block_attributes['variations'] ) ? $item->product_name : edd_get_download_name( $item->product_id );
if ( array_key_exists( $key, $downloads ) ) {
$key = ! empty( $block_attributes['variations'] ) ? $item->product_name : edd_get_download_name( $item->product_id );
$valid_key = $item->product_id;
if ( in_array( $valid_key, $valid_items, true ) ) {
continue;
}
$bundled_products = edd_get_bundled_products( $item->product_id, $item->price_id );
@ -425,6 +427,7 @@ function get_purchased_products( $block_attributes ) {
$product_id = edd_get_bundle_item_id( $bundle_item );
$price_id = edd_get_bundle_item_price_id( $bundle_item );
$key = edd_get_download_name( $product_id );
$valid_key = $product_id;
$order_item_args = array(
'order_id' => $item->order_id,
'status' => $item->status,
@ -444,15 +447,18 @@ function get_purchased_products( $block_attributes ) {
}
}
$order_item_args['price_id'] = $price_id;
$valid_key .= "_{$price_id}";
}
if ( array_key_exists( $key, $downloads ) ) {
if ( in_array( $valid_key, $valid_items, true ) ) {
continue;
}
$valid_items[] = $valid_key;
$downloads[ $key ] = new \EDD\Orders\Order_Item( $order_item_args );
}
continue;
}
$key = $item->product_name;
$key = $item->product_name;
$valid_key = $item->product_id;
if ( is_numeric( $item->price_id ) && edd_has_variable_prices( $item->product_id ) ) {
if ( empty( $block_attributes['variations'] ) ) {
$download_files = edd_get_download_files( $item->product_id, $item->price_id );
@ -460,11 +466,14 @@ function get_purchased_products( $block_attributes ) {
if ( empty( $conditions ) || in_array( 'all', $conditions, true ) ) {
$key = edd_get_download_name( $item->product_id );
}
} else {
$valid_key .= "_{$item->price_id}";
}
}
if ( array_key_exists( $key, $downloads ) ) {
if ( in_array( $valid_key, $valid_items, true ) ) {
continue;
}
$valid_items[] = $valid_key;
$downloads[ $key ] = $item;
}

View File

@ -1,3 +1,6 @@
<?php
use EDD\Blocks\Checkout\Functions as CheckoutFunctions;
?>
<form id="edd_checkout_cart_form" class="edd-blocks-form edd-blocks-form__cart" method="post">
<?php
$cart_classes = array(
@ -30,7 +33,7 @@
if ( edd_cart_has_fees() ) {
include 'cart-fees.php';
}
do_action( 'edd_cart_items_after' );
CheckoutFunctions\do_cart_action( 'edd_cart_items_after' );
if ( edd_use_taxes() && ! edd_prices_include_tax() ) {
include 'cart-subtotal.php';

View File

@ -58,7 +58,7 @@ add_action( 'template_redirect', 'edd_process_cart_endpoints', 100 );
*/
function edd_process_add_to_cart( $data ) {
$download_id = ! empty( $data['download_id'] ) ? absint( $data['download_id'] ) : false;
$options = isset( $data['edd_options'] ) ? $data['edd_options'] : array();
$options = isset( $data['edd_options'] ) ? (array) $data['edd_options'] : array();
if ( ! empty( $data['edd_download_quantity'] ) ) {
$options['quantity'] = absint( $data['edd_download_quantity'] );

View File

@ -438,7 +438,7 @@ class EDD_Cart {
if ( $download->has_variable_prices() && ! isset( $options['price_id'] ) ) {
// Forces to the default price ID if none is specified and download has variable prices
$options['price_id'] = get_post_meta( $download->ID, '_edd_default_price_id', true );
$options['price_id'] = $download->get_default_price_id();
}
if ( isset( $options['quantity'] ) ) {
@ -1222,21 +1222,22 @@ class EDD_Cart {
* Get the name of an item in the cart.
*
* @since 2.7
* @since 3.1.2 Updated to use edd_get_download_name() for consistency
*
* @param array $item Item details
* @return string $name Item name
*/
public function get_item_name( $item = array() ) {
$item_title = get_the_title( $item['id'] );
$download_id = $item['id'];
$price_id = $this->get_item_price_id( $item );
$item_title = edd_get_download_name( $download_id, $price_id );
// In the event that we dont' get a name back, use the ID.
if ( empty( $item_title ) ) {
$item_title = $item['id'];
}
if ( edd_has_variable_prices( $item['id'] ) && false !== edd_get_cart_item_price_id( $item ) ) {
$item_title .= ' - ' . edd_get_cart_item_price_name( $item );
}
return apply_filters( 'edd_get_cart_item_name', $item_title, $item['id'], $item );
}

View File

@ -355,7 +355,7 @@ final class Easy_Digital_Downloads {
// Plugin version.
if ( ! defined( 'EDD_VERSION' ) ) {
define( 'EDD_VERSION', '3.1.1.4.2' );
define( 'EDD_VERSION', '3.1.2' );
}
// Make sure CAL_GREGORIAN is defined.
@ -833,6 +833,7 @@ final class Easy_Digital_Downloads {
require_once EDD_PLUGIN_DIR . 'includes/admin/settings/display-settings.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/tools.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/plugins.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/deprecated-upgrade-functions.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/downgrades.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/upgrade-functions.php';
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/upgrades.php';

View File

@ -1765,7 +1765,8 @@ class EDD_CLI extends WP_CLI_Command {
} else {
if ( ! $full_migration ) {
WP_CLI::line( __( 'Partial order migration complete. Orders Processed: ', 'easy-digital-downloads' ) . $total );
WP_CLI::line( __( 'To recalculate all download sales and earnings, run wp edd `recalculate_download_sales_earnings`.', 'easy-digital-downloads' ) );
WP_CLI::line( __( 'To recalculate all download sales and earnings, run `wp edd recalculate_download_sales_earnings`.', 'easy-digital-downloads' ) );
WP_CLI::line( __( 'To recalculate all customer sales and earnings, run `wp edd recalculate_customer_values`.', 'easy-digital-downloads' ) );
} else {
WP_CLI::line( __( 'Migration complete: Orders', 'easy-digital-downloads' ) );
$new_count = edd_count_orders( array( 'type' => 'sale' ) );
@ -1780,6 +1781,7 @@ class EDD_CLI extends WP_CLI_Command {
$progress->tick();
$this->recalculate_download_sales_earnings();
$this->recalculate_customer_values();
}
}
@ -1857,6 +1859,33 @@ class EDD_CLI extends WP_CLI_Command {
WP_CLI::line( __( 'Downloads Updated: ', 'easy-digital-downloads' ) . $total );
}
/**
* Recalculates all customer values.
*
* @since 3.1.2
* @return void
*/
public function recalculate_customer_values() {
$customers = edd_get_customers(
array(
'number' => 9999999,
)
);
$total = count( $customers );
if ( ! empty( $total ) ) {
$progress = new \cli\progress\Bar( 'Recalculating Customer Values', $total );
foreach ( $customers as $customer ) {
$customer->recalculate_stats();
$progress->tick();
}
$progress->finish();
}
WP_CLI::line( __( 'Sales and Earnings successfully recalculated for all customers.', 'easy-digital-downloads' ) );
WP_CLI::line( __( 'Customers Updated: ', 'easy-digital-downloads' ) . $total );
}
/**
* Removes legacy data from 2.9 and earlier that has been migrated to 3.0.
*

View File

@ -306,7 +306,38 @@ class EDD_Download {
* @param array $prices The array of variables prices.
* @param int|string The ID of the download.
*/
return apply_filters( 'edd_get_variable_prices', $this->prices, $this->ID );
return (array) apply_filters( 'edd_get_variable_prices', $this->prices, $this->ID );
}
/**
* Get the default Price ID for variable priced products.
*
* Since it is possible for the value to not be set on older products, we'll set it to the first price in the array
* if one is not set, as that has been the default behavior since default prices were introduced.
*
* Storing it as the first if found, is just more consistent and intentional.
*
* @since 3.1.2
*
* @return int|null The default price ID, or null if the product does not have variable prices.
*/
public function get_default_price_id() {
if ( ! $this->has_variable_prices() ) {
return null;
}
$default_price_id = get_post_meta( $this->ID, '_edd_default_price_id', true );
// If no default price ID is set, or the default price ID is not in the prices array, set the first price as the default.
$prices = $this->get_prices();
if ( is_array( $prices ) && ( ! is_numeric( $default_price_id ) || ! array_key_exists( (int) $default_price_id, $prices ) ) ) {
$default_price_id = key( $prices );
// Set the default price ID
update_post_meta( $this->ID, '_edd_default_price_id', $default_price_id );
}
return absint( apply_filters( 'edd_variable_default_price_id', $default_price_id, $this->ID ) );
}
/**

View File

@ -179,11 +179,11 @@ class EDD_Fees {
* @since 1.5
* @param string $type Fee type, "fee" or "item"
* @param int $download_id The download ID whose fees to retrieve
* @param int $price_id The variable price ID whose fees to retrieve
* @param null|int $price_id The variable price ID whose fees to retrieve
* @uses EDD_Session::get()
* @return array|bool List of fees when available, false when there are no fees
*/
public function get_fees( $type = 'fee', $download_id = 0, $price_id = NULL ) {
public function get_fees( $type = 'fee', $download_id = 0, $price_id = null ) {
$fees = EDD()->session->get( 'edd_cart_fees' );
if ( EDD()->cart->is_empty() ) {
@ -208,14 +208,17 @@ class EDD_Fees {
unset( $fees[ $key ] );
}
$fee_hash = md5( $fee['amount'] . $fee['label'] . $fee['type'] );
$string_to_hash = "{$key}_{$download_id}";
if ( ! is_null( $price_id ) && isset( $fee['price_id'] ) ) {
$string_to_hash .= "_{$fee['price_id']}";
}
$fee_hash = md5( $string_to_hash );
if ( in_array( $fee_hash, $applied_fees ) ) {
if ( in_array( $fee_hash, $applied_fees, true ) ) {
unset( $fees[ $key ] );
}
$applied_fees[] = $fee_hash;
}
}

View File

@ -100,12 +100,12 @@ class EDD_License {
*
* @see \EDD\Admin\Promos\Notices\License_Upgrade_Notice::__construct()
*/
if ( ! empty( $this->license ) && is_null( $this->api_url ) ) {
if ( is_null( $this->api_url ) ) {
global $edd_licensed_products;
if ( ! is_array( $edd_licensed_products ) ) {
$edd_licensed_products = array();
}
$edd_licensed_products[] = $this->item_shortname;
$edd_licensed_products[ $this->item_shortname ] = (int) (bool) ( $this->license && empty( $this->edd_license->error ) );
}
}

View File

@ -883,15 +883,7 @@ abstract class Table extends Base {
* @return bool
*/
private function is_testing() {
return (bool)
// Tests constant is being used
( defined( 'WP_TESTS_DIR' ) && WP_TESTS_DIR )
||
// Scaffolded (https://make.wordpress.org/cli/handbook/plugin-unit-tests/)
function_exists( '_manually_load_plugin' );
return edd_is_doing_unit_tests();
}
/**

View File

@ -2135,3 +2135,20 @@ function edd_ajax_filter_download_where( $where, $wp_query ) {
return $search->filter_where( $where, $wp_query );
}
/**
* Gets the next available order number.
*
* This is used when inserting a new order.
*
* @deprecated 3.1.2
* @since 2.0
* @return false|int $number The next available order number, unformatted.
*/
function edd_get_next_payment_number() {
_edd_deprecated_function( __FUNCTION__, '3.1.2', 'EDD\Orders\Number\get_next_payment_number' );
$order_number = new EDD\Orders\Number();
return $order_number->get_next_payment_number();
}

View File

@ -356,31 +356,21 @@ function edd_has_variable_prices( $download_id = 0 ) {
* none set.
*
* @since 2.2
* @since 3.1.2 Moved this behavior into the EDD_Download class as it really does belong there.
*
* @param int $download_id Download ID.
* @return int Price ID.
* @return int|null The default price ID, or false if the product does not have variable prices.
*/
function edd_get_default_variable_price( $download_id = 0 ) {
// Bail if no download ID was passed.
if ( empty( $download_id ) ) {
return false;
if ( ! is_numeric( $download_id ) || empty( $download_id ) ) {
return null;
}
// Bail if download has no variable prices.
if ( ! edd_has_variable_prices( $download_id ) ) {
return false;
}
$download = new EDD_Download( $download_id );
$prices = edd_get_variable_prices( $download_id );
$default_price_id = get_post_meta( $download_id, '_edd_default_price_id', true );
if ( '' === $default_price_id || ! isset( $prices[ $default_price_id ] ) ) {
$default_price_id = current( array_keys( $prices ) );
}
// Filter & return.
return apply_filters( 'edd_variable_default_price_id', absint( $default_price_id ), $download_id );
return $download->get_default_price_id();
}
/**
@ -474,33 +464,13 @@ function edd_get_lowest_price_option( $download_id = 0 ) {
return edd_get_download_price( $download_id );
}
// Fetch variables prices.
$prices = edd_get_variable_prices( $download_id );
// Set lowest to 0.
$lowest = 0.00;
// Loop through all the prices.
if ( ! empty( $prices ) ) {
foreach ( $prices as $key => $price ) {
// Skip if amount doesn't exist.
if ( empty( $price['amount'] ) ) {
continue;
}
if ( ! isset( $min ) ) {
$min = $price['amount'];
} else {
$min = min( $min, $price['amount'] );
}
if ( $price['amount'] == $min ) {
$min_id = $key;
}
}
$lowest = $prices[ $min_id ]['amount'];
$lowest = 0.00;
$prices = edd_get_variable_prices( $download_id );
$list_handler = new EDD\Utils\ListHandler( $prices );
$min_key = $list_handler->search( 'amount', 'min' );
if ( false !== $min_key ) {
$lowest = $prices[ $min_key ]['amount'];
}
return edd_sanitize_amount( $lowest );
@ -531,31 +501,10 @@ function edd_get_lowest_price_id( $download_id = 0 ) {
return edd_get_download_price( $download_id );
}
// Fetch variable prices.
$prices = edd_get_variable_prices( $download_id );
$list_handler = new EDD\Utils\ListHandler( edd_get_variable_prices( $download_id ) );
$min_key = $list_handler->search( 'amount', 'min' );
// Loop through all the prices.
if ( ! empty( $prices ) ) {
foreach ( $prices as $key => $price ) {
// Skip if amount doesn't exist.
if ( empty( $price['amount'] ) ) {
continue;
}
if ( ! isset( $min ) ) {
$min = $price['amount'];
} else {
$min = min( $min, $price['amount'] );
}
if ( $price['amount'] == $min ) {
$min_id = $key;
}
}
}
return absint( $min_id );
return false !== $min_key ? absint( $min_key ) : false;
}
/**
@ -582,31 +531,13 @@ function edd_get_highest_price_option( $download_id = 0 ) {
return edd_get_download_price( $download_id );
}
// Fetch variables prices.
$prices = edd_get_variable_prices( $download_id );
// Set highest to 0.
$highest = 0.00;
// Loop through all the prices.
if ( ! empty( $prices ) ) {
$max = 0;
foreach ( $prices as $key => $price ) {
// Skip if amount doesn't exist.
if ( empty( $price['amount'] ) ) {
continue;
}
$max = max( $max, $price['amount'] );
if ( $price['amount'] == $max ) {
$max_id = $key;
}
}
$highest = $prices[ $max_id ]['amount'];
$highest = 0.00;
$prices = edd_get_variable_prices( $download_id );
$list_handler = new EDD\Utils\ListHandler( $prices );
$max_key = $list_handler->search( 'amount', 'max' );
if ( false !== $max_key ) {
$highest = $prices[ $max_key ]['amount'];
}
return edd_sanitize_amount( $highest );
@ -671,7 +602,7 @@ function edd_single_price_option_mode( $download_id = 0 ) {
*/
function edd_get_download_types() {
$types = array(
'0' => __( 'Default', 'easy-digital-downloads' ),
'0' => __( 'Single Product', 'easy-digital-downloads' ),
'bundle' => __( 'Bundle', 'easy-digital-downloads' ),
);

View File

@ -65,6 +65,10 @@ add_action( 'edd_order_item_deleted', 'edd_recalculate_order_item_download' );
*/
function edd_recalculate_order_item_download( $order_item_id, $data = array(), $previous_order_item = false ) {
if ( get_option( '_edd_v30_doing_order_migration', false ) ) {
return;
}
// Recalculations do not need to run when the order item is first being added to the database if it's pending.
if ( 'edd_order_item_added' === current_action() && ( empty( $data['status'] ) || 'pending' === $data['status'] ) ) {
return;
@ -119,6 +123,10 @@ add_action( 'edd_order_adjustment_updated', 'edd_recalculate_order_adjustment_do
* @return void
*/
function edd_recalculate_order_adjustment_download( $order_adjustment_id, $data = array(), $previous_order_adjustment = false ) {
if ( get_option( '_edd_v30_doing_order_migration', false ) ) {
return;
}
if ( $previous_order_adjustment instanceof EDD\Orders\Order_Adjustment ) {
$columns_affecting_stats = array( 'total', 'subtotal', 'object_id', 'object_type' );

View File

@ -38,11 +38,10 @@ add_action( 'admin_init', function () {
* even if there are no licensed products.
*/
if ( empty( $saved_products['timeout'] ) || $saved_products['timeout'] < time() ) {
global $edd_licensed_products;
update_option( 'edd_licensed_extensions', json_encode( array(
'timeout' => strtotime( '+1 day' ),
'products' => $edd_licensed_products,
'products' => get_licensed_products(),
) ), false );
}
}, 200 );
@ -65,11 +64,7 @@ function get_licensed_extension_slugs() {
* the global is not, but worth a shot.
*/
if ( empty( $products ) ) {
global $edd_licensed_products;
return ! empty( $edd_licensed_products ) && is_array( $edd_licensed_products )
? $edd_licensed_products
: array();
return get_licensed_products();
}
$products = json_decode( $products, true );
@ -95,3 +90,25 @@ add_action( 'plugins_loaded', function() {
*/
do_action( 'edd_extension_license_init', EDD()->extensionRegistry );
}, PHP_INT_MAX );
/**
* Helper function to get the actually licensed products from the global.
* In 3.1.1.2, all products using the licensing class add their slug to the global,
* but we are now tracking unlicensed products as well as licensed ones.
*
* @return void
*/
function get_licensed_products() {
$products = array();
global $edd_licensed_products;
if ( empty( $edd_licensed_products ) || ! is_array( $edd_licensed_products ) ) {
return $products;
}
foreach ( $edd_licensed_products as $slug => $is_licensed ) {
if ( $is_licensed ) {
$products[] = $slug;
}
}
return $products;
}

View File

@ -57,6 +57,8 @@ add_action( 'wp_ajax_nopriv_edd_load_gateway', 'edd_load_ajax_gateway' );
* Sets an error on checkout if no gateways are enabled
*
* @since 1.3.4
* @since 3.1.2 Updated to include a different message for users who do not have the manage_shop_settings capability.
*
* @return void
*/
function edd_no_gateway_error() {
@ -65,7 +67,12 @@ function edd_no_gateway_error() {
if ( empty( $gateways ) && edd_get_cart_total() > 0 ) {
remove_action( 'edd_after_cc_fields', 'edd_default_cc_address_fields' );
remove_action( 'edd_cc_form', 'edd_get_cc_form' );
edd_set_error( 'no_gateways', __( 'You must enable a payment gateway to use Easy Digital Downloads', 'easy-digital-downloads' ) );
if ( current_user_can( 'manage_shop_settings' ) ) {
$error_message = __( 'You must enable a payment gateway to use Easy Digital Downloads', 'easy-digital-downloads' );
} else {
$error_message = __( 'Your order cannot be completed at this time. Please try again or contact site support.', 'easy-digital-downloads' );
}
edd_set_error( 'no_gateways', $error_message );
} else {
edd_unset_error( 'no_gateways' );
}

View File

@ -501,3 +501,119 @@ function edd_count_sales_by_gateway( $gateway_label = 'paypal', $status = 'compl
'status' => $status,
) );
}
/**
* Determines if a gateway is setup.
*
* @since 3.1.2
*
* @param string $gateway The gateway to check.
*
* @return bool True if the gateway is setup, false otherwise.
*/
function edd_is_gateway_setup( $gateway = '' ) {
// Return false if no gateway is passed.
if ( empty( $gateway ) ) {
return false;
}
$gateways = edd_get_payment_gateways();
// If the gateway is not registered, return false.
if ( ! array_key_exists( $gateway, $gateways ) ) {
return false;
}
// Some core gateways, we can just determine here, otherwise we'll use the default case to run the filter.
switch ( $gateway ) {
case 'stripe':
$api_key = edd_is_test_mode()
? edd_get_option( 'test_publishable_key' )
: edd_get_option( 'live_publishable_key' );
$is_setup = ! empty( $api_key );
break;
case 'paypal_commerce':
$is_setup = EDD\Gateways\PayPal\ready_to_accept_payments();
break;
default:
/**
* Run a filter to determine if a gateway is setup.
*
* This defaults to 'true' so that gateways that do not have a setup check to
* continue to work.
*
* This hook would fire on the gateway slug, prefixed with `edd_is_gateway_setup_`.
* Example: edd_is_gateway_setup_paypal_express
*
* @since 3.1.2
*
* @param bool $is_setup Whether or not the gateway is setup.
*/
$is_setup = apply_filters( 'edd_is_gateway_setup_' . $gateway, true );
break;
}
return $is_setup;
}
/**
* Gets the URL to the gateway settings page.
*
* @since 3.1.2
*
* @param string $gateway The gateway to get the settings URL for.
*
* @return string The URL to the gateway settings page.
*/
function edd_get_gateway_settings_url( $gateway = '' ) {
// Return false if no gateway is passed.
if ( empty( $gateway ) ) {
return '';
}
$gateways = edd_get_payment_gateways();
// If the gateway is not registered, return false.
if ( ! array_key_exists( $gateway, $gateways ) ) {
return '';
}
// Some core gateways, we can just determine here, otherwise we'll use the default case to run the filter.
switch ( $gateway ) {
case 'stripe':
$gateway_settings_url = edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'gateways',
'section' => 'edd-stripe',
)
);
break;
case 'paypal_commerce':
$gateway_settings_url = EDD\Gateways\PayPal\Admin\get_settings_url();
break;
default:
/**
* Run a filter to assign a settings URL for the gateway.
*
* This defaults to an empty string so that gateways that do not have
* a setup check to continue to work.
*
* This hook would fire on the gateway slug, prefixed with `edd_gateway_settings_url_`.
* Example: edd_gateway_settings_url_paypal_express
*
* @since 3.1.2
*
* @param string $gateway_settings_url The URL to the gateway settings.
*/
$gateway_settings_url = apply_filters( 'edd_gateway_settings_url_' . $gateway, '' );
break;
}
return $gateway_settings_url;
}

View File

@ -25,30 +25,22 @@ if ( ! defined( 'EDD_PAYPAL_PARTNER_CONNECT_URL' ) ) {
* If they are connected, their account details are shown instead.
*
* @since 2.11
* @return string
* @return void
*/
function connect_settings_field() {
$is_connected = PayPal\has_rest_api_connection();
$mode = edd_is_test_mode() ? __( 'sandbox', 'easy-digital-downloads' ) : __( 'live', 'easy-digital-downloads' );
ob_start();
if ( ! $is_connected ) {
/**
* Show Connect
*/
/*
* If we have Partner details but no REST credentials then that most likely means
* PayPal wasn't opened in the modal. We'll show an error message about popups.
*/
if ( get_partner_details() ) {
$onboarding_data = get_onboarding_data();
if ( 200 !== $onboarding_data['code'] || empty( $onboarding_data['body']->signupLink ) ) {
?>
<div class="notice notice-error inline">
<p>
<?php
echo wp_kses( sprintf(
/* Translators: %1$s opening <strong> tag; %2$s closing </strong> tag */
__( '%1$sConnection failure:%2$s This is most likely due to your browser blocking the connection. Most store owners have the best success with Chrome, but for some reason, a few select browsers/devices prevent the connection from EDD and PayPal from working. You might have to enable popups, then restart your browser. If that doesn\'t work, please try a different browser or device and see if that works. If you continue to experience this error, please contact support.', 'easy-digital-downloads' ),
__( '%1$sPayPal Communication Error:%2$s We are having trouble communicating with PayPal at the moment. Please try again later, and if the issue persists, reach out to our support team.', 'easy-digital-downloads' ),
'<strong>',
'</strong>'
), array( 'strong' => array() ) );
@ -56,17 +48,17 @@ function connect_settings_field() {
</p>
</div>
<?php
} else {
?>
<a type="button" target="_blank" id="edd-paypal-commerce-link" class="button button-secondary" href="<?php echo $onboarding_data['body']->signupLink; ?>&displayMode=minibrowser" data-paypal-onboard-complete="eddPayPalOnboardingCallback" data-paypal-button="true" data-paypal-onboard-button="true" data-nonce="<?php echo esc_attr( wp_create_nonce( 'edd_process_paypal_connect' ) ); ?>">
<?php
/* Translators: %s - the store mode, either `sandbox` or `live` */
printf( esc_html__( 'Connect with PayPal in %s mode', 'easy-digital-downloads' ), esc_html( $mode ) );
?>
</a>
<?php
}
?>
<button type="button" id="edd-paypal-commerce-connect" class="button" data-nonce="<?php echo esc_attr( wp_create_nonce( 'edd_process_paypal_connect' ) ); ?>">
<?php
/* Translators: %s - the store mode, either `sandbox` or `live` */
printf( esc_html__( 'Connect with PayPal in %s mode', 'easy-digital-downloads' ), esc_html( $mode ) );
?>
</button>
<a href="#" target="_blank" id="edd-paypal-commerce-link" class="edd-hidden" data-paypal-onboard-complete="eddPayPalOnboardingCallback" data-paypal-button="true">
<?php esc_html_e( 'Sign up for PayPal', 'easy-digital-downloads' ); ?>
</a>
<div id="edd-paypal-commerce-errors"></div>
<?php
} else {
@ -86,70 +78,121 @@ function connect_settings_field() {
?>
<?php
return ob_get_clean();
}
add_action( 'edd_paypal_connect_button', __NAMESPACE__ . '\connect_settings_field' );
/**
* Single function to make a request to get the onboarding URL and nonce.
*
* Previously we did this in process_connect method, but we've moved away from the AJAX useage of this
* in favor of doing it on loading the settings field, to make loading the modal more reliable and faster.
*
* @since 3.1.2
*/
function get_onboarding_data() {
if ( ! current_user_can( 'manage_options' ) ) {
return array(
'code' => 403,
'body' => array(
'message' => __( 'You do not have permission to perform this action.', 'easy-digital-downloads' ),
),
);
}
$mode = edd_is_test_mode() ? API::MODE_SANDBOX : API::MODE_LIVE;
$existing_connect_details = get_partner_details( $mode );
if ( ! empty( $existing_connect_details ) ) {
// Ensure the data we have contains all necessary details.
if (
( ! empty( $existing_connect_details->expires ) && $existing_connect_details->expires > time() ) &&
! empty( $existing_connect_details->nonce ) &&
! empty( $existing_connect_details->signupLink ) && // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
! empty( $existing_connect_details->product )
) {
return array(
'code' => 200,
'body' => $existing_connect_details,
);
}
}
$response = wp_remote_post(
EDD_PAYPAL_PARTNER_CONNECT_URL . 'signup-link',
array(
'headers' => array(
'Content-Type' => 'application/json',
),
'user-agent' => 'Easy Digital Downloads/' . EDD_VERSION . '; ' . get_bloginfo( 'name' ),
'body' => wp_json_encode(
array(
'mode' => $mode,
'country_code' => edd_get_shop_country(),
'currency_code' => edd_get_currency(),
'return_url' => get_settings_url(),
)
),
)
);
$code = wp_remote_retrieve_response_code( $response );
if ( is_wp_error( $response ) ) {
return array(
'code' => $code,
'body' => $response->get_error_message(),
);
}
$body = wp_remote_retrieve_body( $response );
$body = json_decode( $body );
// We're storing an expiration so we can get a new one if it's been a day.
$body->expires = time() + DAY_IN_SECONDS;
// We need to store this temporarily so we can use the nonce again in the next request.
update_option( 'edd_paypal_commerce_connect_details_' . $mode, wp_json_encode( $body ), false );
return array(
'code' => $code,
'body' => $body,
);
}
/**
* AJAX handler for processing the PayPal Connection.
*
* @since 2.11
* @deprecated 3.1.2 Instead of doing this via an AJAX request, we now do this on page load.
*
* @return void
*/
function process_connect() {
_edd_deprecated_function( __FUNCTION__, '3.1.2', 'EDD_PayPal_Commerce::get_onboarding_data()' );
// This validates the nonce.
check_ajax_referer( 'edd_process_paypal_connect' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( __( 'You do not have permission to perform this action.', 'easy-digital-downloads' ) );
}
$onboarding_data = get_onboarding_data();
$mode = edd_is_test_mode() ? API::MODE_SANDBOX : API::MODE_LIVE;
$response = wp_remote_post( EDD_PAYPAL_PARTNER_CONNECT_URL . 'signup-link', array(
'headers' => array(
'Content-Type' => 'application/json',
),
'body' => json_encode( array(
'mode' => $mode,
'country_code' => edd_get_shop_country(),
'currency_code' => edd_get_currency(),
'return_url' => get_settings_url()
) ),
'user-agent' => 'Easy Digital Downloads/' . EDD_VERSION . '; ' . get_bloginfo( 'name' ),
) );
if ( is_wp_error( $response ) ) {
wp_send_json_error( $response->get_error_message() );
}
$code = wp_remote_retrieve_response_code( $response );
$body = json_decode( wp_remote_retrieve_body( $response ) );
if ( 200 !== intval( $code ) ) {
if ( 200 !== intval( $onboarding_data['code'] ) ) {
wp_send_json_error( sprintf(
/* Translators: %d - HTTP response code; %s - Response from the API */
__( 'Unexpected response code: %d. Error: %s', 'easy-digital-downloads' ),
$code,
json_encode( $body )
$onboarding_data['code'],
wp_json_encode( $onboarding_data['body'] )
) );
}
if ( empty( $body->signupLink ) || empty( $body->nonce ) ) {
if ( empty( $onboarding_data['body']->signupLink ) || empty( $onboarding_data['body']->nonce ) ) {
wp_send_json_error( __( 'An unexpected error occurred.', 'easy-digital-downloads' ) );
}
/**
* We need to store this temporarily so we can use the nonce again in the next request.
*
* @see get_access_token()
*/
update_option( 'edd_paypal_commerce_connect_details_' . $mode, json_encode( $body ) );
wp_send_json_success( $body );
wp_send_json_success( $onboarding_data['body'] );
}
add_action( 'wp_ajax_edd_paypal_commerce_connect', __NAMESPACE__ . '\process_connect' );
/**
* AJAX handler for processing the PayPal Reconnect.
*
@ -187,7 +230,6 @@ function process_reconnect() {
wp_safe_redirect( esc_url_raw( get_settings_url() ) );
}
add_action( 'wp_ajax_edd_paypal_commerce_reconnect', __NAMESPACE__ . '\process_reconnect' );
/**
@ -195,7 +237,7 @@ add_action( 'wp_ajax_edd_paypal_commerce_reconnect', __NAMESPACE__ . '\process_r
*
* @param string $mode Store mode. If omitted, current mode is used.
*
* @return array|null
* @return stdObj|null
*/
function get_partner_details( $mode = '' ) {
if ( ! $mode ) {
@ -232,23 +274,27 @@ function get_and_save_credentials() {
$paypal_subdomain = edd_is_test_mode() ? '.sandbox' : '';
$api_url = 'https://api-m' . $paypal_subdomain . '.paypal.com/';
/*
* First get a temporary access token from PayPal.
*/
$response = wp_remote_post( $api_url . 'v1/oauth2/token', array(
$api_args = array(
'headers' => array(
'Content-Type' => 'application/x-www-form-urlencoded',
'Authorization' => sprintf( 'Basic %s', base64_encode( $_POST['share_id'] ) ),
'timeout' => 15
'timeout' => 15,
),
'body' => array(
'grant_type' => 'authorization_code',
'code' => $_POST['auth_code'],
'code_verifier' => $partner_details->nonce
'code_verifier' => $partner_details->nonce,
),
'user-agent' => 'Easy Digital Downloads/' . EDD_VERSION . '; ' . get_bloginfo( 'name' ),
) );
);
/*
* First get a temporary access token from PayPal.
*/
$response = wp_remote_post(
$api_url . 'v1/oauth2/token',
$api_args
);
if ( is_wp_error( $response ) ) {
wp_send_json_error( $response->get_error_message() );
@ -258,11 +304,13 @@ function get_and_save_credentials() {
$body = json_decode( wp_remote_retrieve_body( $response ) );
if ( empty( $body->access_token ) ) {
wp_send_json_error( sprintf(
/* Translators: %d - HTTP response code */
__( 'Unexpected response from PayPal while generating token. Response code: %d. Please try again.', 'easy-digital-downloads' ),
$code
) );
wp_send_json_error(
sprintf(
/* Translators: %d - HTTP response code */
__( 'Unexpected response from PayPal while generating token. Response code: %d. Please try again.', 'easy-digital-downloads' ),
$code
)
);
}
/*
@ -599,10 +647,16 @@ function process_delete() {
'paypal_' . $mode . '_client_id',
'paypal_' . $mode . '_client_secret',
);
foreach ( $edd_settings_to_delete as $option_name ) {
edd_delete_option( $option_name );
}
// Unset the PayPal Commerce gateway as an enabled gateway.
$enabled_gateways = edd_get_option( 'gateways', array() );
unset( $enabled_gateways['paypal_commerce'] );
edd_update_option( 'gateways', $enabled_gateways );
wp_safe_redirect( esc_url_raw( get_settings_url() ) );
exit;
}

View File

@ -10,29 +10,51 @@
namespace EDD\Gateways\PayPal\Admin;
use EDD\Gateways\PayPal;
/**
* Enqueue PayPal connect admin JS.
*
* @since 2.11
*/
function enqueue_connect_scripts() {
if ( edd_is_admin_page( 'settings' ) && isset( $_GET['section'] ) && 'paypal_commerce' === $_GET['section'] ) {
\EDD\Gateways\PayPal\maybe_enqueue_polyfills();
if ( edd_is_admin_page( 'settings' ) && isset( $_GET['section'] ) && 'paypal_commerce' === $_GET['section'] ) { /* phpcs:ignore WordPress.Security.NonceVerification.Recommended */
PayPal\maybe_enqueue_polyfills();
$subdomain = edd_is_test_mode() ? 'sandbox.' : '';
wp_enqueue_script(
'sandhills-paypal-partner-js',
'https://www.' . $subdomain . 'paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js',
array(),
null,
true
wp_localize_script(
'edd-admin-settings',
'eddPayPalConnectVars',
array(
'defaultError' => esc_html__( 'An unexpected error occurred. Please refresh the page and try again.', 'easy-digital-downloads' ),
'isConnected' => PayPal\has_rest_api_connection(),
)
);
wp_localize_script( 'edd-admin-settings', 'eddPayPalConnectVars', array(
'defaultError' => esc_html__( 'An unexpected error occurred. Please refresh the page and try again.', 'easy-digital-downloads' )
) );
}
}
add_action( 'admin_enqueue_scripts', __NAMESPACE__ . '\enqueue_connect_scripts' );
/**
* Forces the Cache-Control header on the PayPal Commerce settings page to send the no-store header
* which prevents the back-forward cache (bfcache) from storing a copy of this page in local
* cache. This helps make sure that page elements modified via AJAX and DOM manipulations aren't
* incorrectly shown as if they never changed.
*
* See: https://github.com/easydigitaldownloads/EDD-Software-Licensing/issues/1346#issuecomment-382159918
*
* @since 3.6
* @param array $headers An array of nocache headers.
*
* @return array
*/
function _bfcache_buster( $headers ) {
if ( ! is_admin() ) {
return $headers;
}
if ( edd_is_admin_page( 'settings' ) && isset( $_GET['section'] ) && 'paypal_commerce' === $_GET['section'] ) { /* phpcs:ignore WordPress.Security.NonceVerification.Recommended */
$headers['Cache-Control'] = 'no-cache, must-revalidate, max-age=0, no-store';
}
return $headers;
}
add_filter( 'nocache_headers', __NAMESPACE__ . '\_bfcache_buster', 10, 1 );

View File

@ -23,6 +23,7 @@ function get_settings_url() {
return admin_url( 'edit.php?post_type=download&page=edd-settings&tab=gateways&section=paypal_commerce' );
}
/**
* Register the PayPal Standard gateway subsection
*
@ -36,7 +37,6 @@ function register_paypal_gateway_section( $gateway_sections ) {
return $gateway_sections;
}
add_filter( 'edd_settings_sections_gateways', __NAMESPACE__ . '\register_paypal_gateway_section', 1, 1 );
/**
@ -55,58 +55,55 @@ function register_gateway_settings( $gateway_settings ) {
'name' => '<h3>' . __( 'PayPal Settings', 'easy-digital-downloads' ) . '</h3>',
'type' => 'header',
),
'paypal_documentation' => array(
'id' => 'paypal_documentation',
'name' => __( 'Documentation', 'easy-digital-downloads' ),
'desc' => documentation_settings_field(),
'type' => 'descriptive_text'
),
'paypal_connect_button' => array(
'id' => 'paypal_connect_button',
'name' => __( 'Connection Status', 'easy-digital-downloads' ),
'desc' => connect_settings_field(),
'type' => 'descriptive_text',
'class' => 'edd-paypal-connect-row',
'type' => 'hook',
),
'paypal_sandbox_client_id' => array(
'id' => 'paypal_sandbox_client_id',
'name' => __( 'Test Client ID', 'easy-digital-downloads' ),
'desc' => __( 'Enter your test client ID.', 'easy-digital-downloads' ),
'type' => 'text',
'size' => 'regular',
'class' => 'edd-hidden'
'desc' => __( 'Enter your test client ID.', 'easy-digital-downloads' ),
'type' => 'text',
'size' => 'regular',
'class' => 'edd-hidden',
),
'paypal_sandbox_client_secret' => array(
'id' => 'paypal_sandbox_client_secret',
'name' => __( 'Test Client Secret', 'easy-digital-downloads' ),
'desc' => __( 'Enter your test client secret.', 'easy-digital-downloads' ),
'type' => 'password',
'size' => 'regular',
'class' => 'edd-hidden'
'id' => 'paypal_sandbox_client_secret',
'name' => __( 'Test Client Secret', 'easy-digital-downloads' ),
'desc' => __( 'Enter your test client secret.', 'easy-digital-downloads' ),
'type' => 'password',
'size' => 'regular',
'class' => 'edd-hidden',
),
'paypal_live_client_id' => array(
'id' => 'paypal_live_client_id',
'name' => __( 'Live Client ID', 'easy-digital-downloads' ),
'desc' => __( 'Enter your live client ID.', 'easy-digital-downloads' ),
'type' => 'text',
'size' => 'regular',
'class' => 'edd-hidden'
'id' => 'paypal_live_client_id',
'name' => __( 'Live Client ID', 'easy-digital-downloads' ),
'desc' => __( 'Enter your live client ID.', 'easy-digital-downloads' ),
'type' => 'text',
'size' => 'regular',
'class' => 'edd-hidden',
),
'paypal_live_client_secret' => array(
'id' => 'paypal_live_client_secret',
'name' => __( 'Live Client Secret', 'easy-digital-downloads' ),
'desc' => __( 'Enter your live client secret.', 'easy-digital-downloads' ),
'type' => 'password',
'size' => 'regular',
'class' => 'edd-hidden'
'id' => 'paypal_live_client_secret',
'name' => __( 'Live Client Secret', 'easy-digital-downloads' ),
'desc' => __( 'Enter your live client secret.', 'easy-digital-downloads' ),
'type' => 'password',
'size' => 'regular',
'class' => 'edd-hidden',
),
'paypal_documentation' => array(
'id' => 'paypal_documentation',
'name' => '',
'type' => 'hook',
),
);
$is_connected = PayPal\has_rest_api_connection();
if ( ! $is_connected ) {
$paypal_settings['paypal_settings']['tooltip_title'] = __( 'Connect with PayPal', 'easy-digital-downloads' );
$paypal_settings['paypal_settings']['tooltip_desc'] = __( 'Connecting your store with PayPal allows Easy Digital Downloads to automatically configure your store to securely communicate PayPal.<br \><br \>You may see "Sandhills Development, LLC", mentioned during the process&mdash;that is the company behind Easy Digital Downloads.', 'easy-digital-downloads' );
$paypal_settings['paypal_settings']['tooltip_desc'] = __( 'Connecting your store with PayPal allows Easy Digital Downloads to automatically configure your store to securely communicate with PayPal.<br \><br \>You may see "Sandhills Development, LLC", mentioned during the process&mdash;that is the company behind Easy Digital Downloads.', 'easy-digital-downloads' );
}
/**
@ -129,15 +126,15 @@ add_filter( 'edd_settings_gateways', __NAMESPACE__ . '\register_gateway_settings
* @return string
*/
function documentation_settings_field() {
ob_start();
?>
<p>
<?php
echo wp_kses( sprintf(
__( 'To learn more about the PayPal gateway, visit <a href="%s" target="_blank">our documentation</a>.', 'easy-digital-downloads' ),
'https://easydigitaldownloads.com/docs/paypal-setup/'
), array( 'a' => array( 'href' => true, 'target' => true ) ) )
?>
<a class="button button-secondary" href="https://easydigitaldownloads.com/docs/paypal-setup/" target="_blank">
<?php esc_html_e( 'View Documentation', 'easy-digital-downloads' ); ?>
</a>
<a id="edd-paypal-commerce-get-help" class="edd-hidden" href="https://easydigitaldownloads.com/support/" target="_blank">
<?php esc_html_e( 'Get Help', 'easy-digital-downloads' ); ?>
</a>
</p>
<?php
if ( ! is_ssl() ) {
@ -154,6 +151,5 @@ function documentation_settings_field() {
</div>
<?php
}
return ob_get_clean();
}
add_action( 'edd_paypal_documentation', __NAMESPACE__ . '\documentation_settings_field' );

View File

@ -27,6 +27,11 @@ function maybe_remove_paypal_standard( $gateways ) {
unset( $gateways['paypal'] );
}
// Ensures we don't show the PayPal Standard option in Site Health.
if ( did_action( 'admin_head-site-health.php' ) && ! paypal_standard_enabled() ) {
unset( $gateways['paypal'] );
}
return $gateways;
}

View File

@ -30,18 +30,8 @@ function maybe_enqueue_polyfills() {
return;
}
global $wp_version;
if ( version_compare( $wp_version, '5.0', '>=' ) ) {
wp_enqueue_script( 'wp-polyfill' );
} else {
wp_enqueue_script(
'wp-polyfill',
EDD_PLUGIN_URL . 'assets/js/wp-polyfill.min.js',
array(),
false,
false
);
}
wp_enqueue_script( 'wp-polyfill' );
}
/**

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=109)}({109:function(e,n,t){(function(e){jQuery((function(){jQuery(".edds-admin-notice").each((function(){var n=e(this),t=n.data("id"),r=n.data("nonce");n.on("click",".notice-dismiss",(function(e){return e.preventDefault(),e.stopPropagation(),wp.ajax.post("edds_admin_notices_dismiss_ajax",{id:t,nonce:r})}))}))}))}).call(this,t(6))},6:function(e,n){e.exports=jQuery}});
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=113)}({113:function(e,n,t){(function(e){jQuery((function(){jQuery(".edds-admin-notice").each((function(){var n=e(this),t=n.data("id"),r=n.data("nonce");n.on("click",".notice-dismiss",(function(e){return e.preventDefault(),e.stopPropagation(),wp.ajax.post("edds_admin_notices_dismiss_ajax",{id:t,nonce:r})}))}))}))}).call(this,t(6))},6:function(e,n){e.exports=jQuery}});

View File

@ -3,7 +3,7 @@
* Plugin Name: Easy Digital Downloads - Stripe Pro Payment Gateway
* Plugin URI: https://easydigitaldownloads.com/downloads/stripe-gateway/
* Description: Adds support for pre-authorized credit card payments and removes additional transaction fees.
* Version: 2.9.2.2
* Version: 2.9.5.1
* Requires at least: 5.4
* Requires PHP: 7.1
* Author: Easy Digital Downloads
@ -44,7 +44,7 @@ function edd_stripe_core_bootstrap() {
}
if ( ! defined( 'EDD_STRIPE_VERSION' ) ) {
define( 'EDD_STRIPE_VERSION', '2.9.2.2' );
define( 'EDD_STRIPE_VERSION', '2.9.5.1' );
}
if ( ! defined( 'EDD_STRIPE_API_VERSION' ) ) {

View File

@ -214,3 +214,64 @@ function edds_show_refund_checkbox( \EDD\Orders\Order $order ) {
<?php
}
add_action( 'edd_after_submit_refund_table', 'edds_show_refund_checkbox' );
/**
* Allows processing flags for the EDD Stripe settings.
*
* As we transition settings like the Card Elements, we need a way to be able to toggle
* these things back on for some people. Enabling debug mode, setting flags, and then disabling
* debug mode allows us to handle this.
*
* @since 2.9.4
*/
function edds_process_settings_flags() {
// If we're not on the settings page, bail.
if ( ! edd_is_admin_page( 'settings', 'gateways' ) ) {
return;
}
// If it isn't the Stripe section, bail.
if ( ! isset( $_GET['section'] ) || 'edd-stripe' !== $_GET['section'] ) {
return;
}
// Gather the flag we're trying to set.
$flag = isset( $_GET['flag'] ) ? $_GET['flag'] : false;
if ( false === $flag ) {
return;
}
if ( ! current_user_can( 'manage_shop_settings' ) ) {
return;
}
$nonce = isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : false;
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, $flag ) ) {
return;
}
switch( $flag ) {
case 'disable-card-elements':
delete_option( '_edds_legacy_elements_enabled' );
break;
case 'enable-card-elements':
add_option( '_edds_legacy_elements_enabled', 1, false );
break;
}
// Redirect to the settings page.
wp_safe_redirect(
edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'gateways',
'section' => 'edd-stripe',
)
)
);
exit;
}
add_action( 'admin_init', 'edds_process_settings_flags', 1 );

View File

@ -198,6 +198,47 @@ function edds_add_settings( $settings ) {
$settings['edd-stripe'] = $stripe_settings;
// If EDD is in Debug Mode, add some 'hidden' settings to the Stripe settings.
if ( edd_is_debug_mode() ) {
$card_elements_enabled = get_option( '_edds_legacy_elements_enabled', false );
$debug_settings = array(
'stripe_debug' => array(
'id' => 'stripe_debug',
'name' => __( 'Debugging Settings', 'easy-digital-downloads' ),
'desc' => '<div class="notice inline notice-warning">' .
'<p>' . __( 'The following settings are available while Easy Digital Downloads is in debug mode. They are not designed to be primary settings and should be used only while debugging or when instructed to be used by the Easy Digital Downloads Team.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'There is no guarantee that these settings will remain available in future versions of Easy Digital Downloads. Easy Digital Downloads Debug Mode should be disabled once changes to these settings have been made.', 'easy-digital-downloads' ) . '</p>' .
'</p></div>',
'type' => 'descriptive_text',
),
);
$card_elements_action = $card_elements_enabled ? 'disable-card-elements' : 'enable-card-elements';
$card_elements_button_label = $card_elements_enabled ? __( 'Disable access to Card Elements', 'easy-digital-downloads' ) : __( 'Enable access to Card Elements', 'easy-digital-downloads' );
$card_elements_state_label = $card_elements_enabled ? __( 'Access to Legacy Card Elements is Enabled', 'easy-digital-downloads' ) : __( 'Access to Legacy Card Elements is Disabled', 'easy-digital-downloads' );
$link_class = $card_elements_enabled ? 'edd-button__toggle--enabled' : 'edd-button__toggle--disabled';
$debug_settings['toggle_card_elements'] = array(
'id' => 'stripe_toggle_card_elements',
'name' => __( 'Toggle Card Elements', 'easy-digital-downloads' ),
'type' => 'descriptive_text',
'desc' => sprintf(
'%1$s<span class="screen-reader-text">' . $card_elements_button_label . '</span>%2$s',
'<a class="edd-button__toggle ' . $link_class . '" href="' . wp_nonce_url( edd_get_admin_url( array(
'page' => 'edd-settings',
'tab' => 'gateways',
'section' => 'edd-stripe',
'flag' => $card_elements_action,
) ), $card_elements_action ) . '">',
'</a>'
) .'<strong>' . $card_elements_state_label . '</strong><br />' . __( 'Card Elements is the legacy Stripe integration. Easy Digital Downloads has updated to use the more secure and reliable Payment Elements feature of Stripe. This toggle allows sites without access to Card Elements to enable or disable it.', 'easy-digital-downloads' ),
);
$settings['edd-stripe'] = array_merge( $settings['edd-stripe'], $debug_settings );
}
// Set up the new setting field for the Test Mode toggle notice.
$notice = array(
'stripe_connect_test_mode_toggle_notice' => array(

View File

@ -242,6 +242,11 @@ function edds_stripe_connect_process_disconnect() {
edd_delete_option( $option );
}
// Remove Stripe from the enabled gateways.
$gateways = edd_get_option( 'gateways', array() );
unset( $gateways['stripe'] );
edd_update_option( 'gateways', $gateways );
$redirect = remove_query_arg(
array(
'_wpnonce',
@ -265,9 +270,9 @@ function edds_stripe_connect_maybe_refresh_account_country() {
return;
}
// Stripe Connect has not been used, bail.
$account_id = edd_get_option( 'stripe_connect_account_id', '' );
$account_id = edd_stripe()->connect()->get_connect_id();
// Stripe Connect has not been used, bail.
if ( empty( $account_id ) ) {
return;
}
@ -307,10 +312,10 @@ add_action( 'admin_init', 'edds_stripe_connect_maybe_refresh_account_country' );
* @since 2.8.0
*/
function edds_stripe_connect_setting_field() {
$stripe_connect_url = edds_stripe_connect_url();
$stripe_disconnect_url = edds_stripe_connect_disconnect_url();
$stripe_connect_url = edds_stripe_connect_url();
$stripe_disconnect_url = edds_stripe_connect_disconnect_url();
$stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id' );
$stripe_connect_account_id = edd_stripe()->connect()->get_connect_id();
$api_key = edd_is_test_mode()
? edd_get_option( 'test_publishable_key' )
@ -678,20 +683,6 @@ function edds_stripe_connect_admin_notices_register() {
);
try {
// Stripe Connect - Manually managed keys.
$registry->add(
'stripe-connect-manual',
array(
'message' => sprintf(
'<p>%s</p><p>%s</p>',
esc_html__( 'Your current Stripe payment connection is out of date. Enable more secure and reliable payments by clicking the button below to enable Stripe Connect.', 'easy-digital-downloads' ),
$connect_button
),
'type' => 'error',
'dismissible' => true,
)
);
// Stripe Connect.
$registry->add(
'stripe-connect',
@ -768,20 +759,11 @@ function edds_stripe_connect_admin_notices_print() {
$mode_toggle = isset( $_GET['edd-message'] ) && 'connect-to-stripe' === $_GET['edd-message'];
if ( array_key_exists( 'stripe', $enabled_gateways ) && empty( $api_key ) ) {
wp_enqueue_style(
'edd-stripe-admin-styles',
EDDSTRIPE_PLUGIN_URL . 'assets/css/build/admin.min.css',
array(),
EDD_STRIPE_VERSION
);
edd_stripe_connect_admin_style();
// Stripe Connect.
if ( false === $mode_toggle ) {
if ( edds_stripe_connect_can_manage_keys() ) {
$notices->output( 'stripe-connect-manual' );
} else {
$notices->output( 'stripe-connect' );
}
$notices->output( 'stripe-connect' );
// Stripe Connect reconnect.
} else {
$notices->output( 'stripe-connect-reconnect' );
@ -790,3 +772,94 @@ function edds_stripe_connect_admin_notices_print() {
} catch( Exception $e ) {}
}
add_action( 'admin_notices', 'edds_stripe_connect_admin_notices_print' );
/**
* Adds a Stripe Connect site health test.
*
* @since 2.9.3
* @param array $tests The array of Site Health tests.
* @return array
*/
function edds_stripe_connect_site_health_test( $tests ) {
$active_gateways = edd_get_enabled_payment_gateways();
if ( ! empty( $active_gateways['stripe'] ) && current_user_can( 'manage_shop_settings' ) ) {
$tests['direct']['edds_stripe_connect'] = array(
'label' => __( 'Stripe Connect', 'easy-digital-downloads' ),
'test' => 'edds_get_test_stripe_connect',
);
}
return $tests;
}
add_filter( 'site_status_tests', 'edds_stripe_connect_site_health_test' );
/**
* Adds the Stripe Connect Site Health test.
*
* @since 2.9.3
* @return array
*/
function edds_get_test_stripe_connect() {
$result = array(
'label' => __( 'You are securely connected to Stripe', 'easy-digital-downloads' ),
'status' => 'good',
'badge' => array(
'label' => __( 'Easy Digital Downloads: Stripe', 'easy-digital-downloads' ),
'color' => 'blue',
),
'description' => sprintf(
'<p>%s</p>',
__( 'Stripe Connect helps ensure easy setup and security.', 'easy-digital-downloads' )
),
'actions' => '',
'test' => 'edds_stripe_connect',
);
$elements_mode = edds_get_elements_mode();
if ( edd_stripe()->connect()->is_connected ) {
if ( 'payment-elements' === $elements_mode ) {
return $result;
}
// User is connected but on the Card Elements, we should give them a recommendation to use the Payment Elements.
$result['label'] = __( 'You are using the legacy Card Elements fields', 'easy-digital-downloads' );
$result['status'] = 'recommended';
$result['badge']['color'] = 'orange';
$result['description'] = sprintf(
'<p>%s</p>',
esc_html__( 'Increase conversions, security, and reliability by using the Payment Elements integration for Stripe.', 'easy-digital-downloads' )
);
$result['actions'] = sprintf(
'<a href="%s" class="button button-primary"><span>%s</span></a>',
esc_url(
edd_get_admin_url(
array(
'page' => 'edd-settings',
'tab' => 'gateways',
'section' => 'edd-stripe',
)
)
),
esc_html__( 'Switch to Payment Elements', 'easy-digital-downloads' )
);
} else {
$result['label'] = __( 'You are using manually managed Stripe API keys', 'easy-digital-downloads' );
$result['status'] = 'critical';
$result['badge']['color'] = 'red';
$result['description'] = sprintf(
'<p>%s</p>',
esc_html__( 'By securely connecting your Easy Digital Downloads store with Stripe Connect, you\'ll get access to more reliable payments and use managed API keys which are more secure.', 'easy-digital-downloads' )
);
$result['actions'] = sprintf(
'<a href="%s" class="edd-stripe-connect"><span>%s</span></a>',
esc_url( edds_stripe_connect_url() ),
esc_html__( 'Connect with Stripe', 'easy-digital-downloads' )
);
}
edd_stripe_connect_admin_style();
return $result;
}

View File

@ -40,19 +40,17 @@ add_action( 'admin_init', function() {
}
$elements_mode = 'payment-elements';
$connect = edd_stripe()->connect();
if (
edds_stripe_connect_can_manage_keys() ||
! empty( edd_get_option( 'stripe_connect_account_id', false ) )
! empty( $connect->get_connect_id() ) ||
edds_stripe_connect_can_manage_keys()
) {
$elements_mode = 'card-elements';
add_option( '_edds_legacy_elements_enabled', 1, false );
}
edd_update_option( 'stripe_elements_mode', $elements_mode );
if ( 'card-elements' === $elements_mode ) {
add_option( '_edds_legacy_elements_enabled', 1, false );
}
} );
/**

View File

@ -52,6 +52,14 @@ class EDD_Stripe {
*/
public $regional_support;
/**
* Stripe Connect status class.
*
* @since 2.9.3
* @var \EDD\Stripe\Connect
*/
public $connect;
/**
* Instantiates or returns the singleton instance.
*
@ -93,6 +101,7 @@ class EDD_Stripe {
require_once EDDS_PLUGIN_DIR . '/vendor/autoload.php';
}
require_once EDDS_PLUGIN_DIR . '/includes/functions.php';
require_once EDDS_PLUGIN_DIR . '/includes/class-stripe-api.php';
// We need this one to load early so we can use it in the upcoming includes.
@ -107,7 +116,6 @@ class EDD_Stripe {
require_once EDDS_PLUGIN_DIR . '/includes/utils/class-registry.php';
require_once EDDS_PLUGIN_DIR . '/includes/utils/modal.php';
require_once EDDS_PLUGIN_DIR . '/includes/functions.php';
require_once EDDS_PLUGIN_DIR . '/includes/deprecated.php';
require_once EDDS_PLUGIN_DIR . '/includes/compat.php';
require_once EDDS_PLUGIN_DIR . '/includes/i18n.php';
@ -137,7 +145,6 @@ class EDD_Stripe {
// Load Apple Pay functions.
require_once EDDS_PLUGIN_DIR . '/includes/payment-methods/apple-pay.php';
// Stripe Elements, separated by elements type.
switch ( $elements_mode ) {
case 'card-elements':
@ -216,6 +223,21 @@ class EDD_Stripe {
$this->rate_limiting = new EDD_Stripe_Rate_Limiting();
}
/**
* Gets the Stripe Connect utility class.
*
* @since 2.9.3
*/
public function connect() {
if ( ! is_null( $this->connect ) ) {
return $this->connect;
}
require_once EDDS_PLUGIN_DIR . '/includes/class-stripe-connect.php';
$this->connect = new EDD\Stripe\Connect();
return $this->connect;
}
/**
* Performs database upgrades.
*

View File

@ -0,0 +1,34 @@
<?php
namespace EDD\Stripe;
defined( 'ABSPATH' ) || exit;
/**
* The class to manage the Stripe Connect properties.
*/
class Connect {
/**
* Whether the site is connected to Stripe with Stripe Connect.
*
* @var bool
*/
public $is_connected;
/**
* Class constructor.
*/
public function __construct() {
$this->is_connected = ! empty( $this->get_connect_id() );
}
/**
* Gets the connect ID.
*
* @return string|false
*/
public function get_connect_id() {
return edd_get_option( 'stripe_connect_account_id', false );
}
}

View File

@ -9,10 +9,9 @@
*/
function edds_stripe_connect_can_manage_keys() {
$stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id', false );
$secret = edd_is_test_mode() ? edd_get_option( 'test_secret_key' ) : edd_get_option( 'live_secret_key' );
$secret = edd_is_test_mode() ? edd_get_option( 'test_secret_key' ) : edd_get_option( 'live_secret_key' );
return empty( $stripe_connect_account_id ) && $secret;
return $secret && empty( edd_stripe()->connect()->get_connect_id() );
}
/**
@ -21,6 +20,7 @@ function edds_stripe_connect_can_manage_keys() {
* If the user is gated into the legacy mode, set the default to card-elements.
*
* @since 2.9.0
* @since 2.9.5.1 We're now listening for an elements_mode flag in POST requests.
*
* @return string The elements mode string.
*/
@ -43,6 +43,17 @@ function edds_get_elements_mode() {
( isset( $_GET['action'] ) && 'update' === $_GET['action'] ) &&
( isset( $_GET['subscription_id'] ) && is_numeric( $_GET['subscription_id'] ) )
) {
add_filter( 'edd_get_option_stripe_split_payment_fields', '__return_false' );
return 'card-elements';
}
/**
* Card elements does a lot with AJAX requests, which will lose the context of being on the Subscription update form, so
* we are sending in a flag for using card elements with the elements_mode equal to 'card-elements' in those POST requests.
*
* @since 2.9.5.1
*/
if ( isset( $_POST['elements_mode'] ) && 'card-elements' === $_POST['elements_mode'] ) {
return 'card-elements';
}

View File

@ -250,6 +250,28 @@ function edds_get_stripe_payment_elements_fields() {
return apply_filters( 'edds_stripe_payment_elements_fields', $default_fields );
}
/**
* Returns an array of terms for the payment elements.
*
* @since 2.9.4
*
* @return array The terms array by payment method.
*/
function edds_get_stripe_payment_elements_terms() {
$terms = array( 'card' => 'auto' );
/**
* Allows filtering the payment elements terms.
*
* @see https://stripe.com/docs/js/elements_object/create_payment_element#payment_element_create-options-terms
*
* @since 2.9.4
* @param array The terms array by payment method.
*/
return apply_filters( 'edds_stripe_payment_elements_terms', $terms );
}
/**
* Gathers all the possible customizations for the Stripe Payment Elements.
*
@ -273,6 +295,7 @@ function edds_gather_payment_element_customizations() {
'fonts' => edds_get_stripe_payment_elements_fonts(),
'paymentMethodTypes' => edds_payment_element_payment_method_types(),
'fields' => edds_get_stripe_payment_elements_fields(),
'terms' => edds_get_stripe_payment_elements_terms(),
'i18n' => array(
'errorMessages' => edds_get_localized_error_messages(),
),

View File

@ -283,10 +283,8 @@ function edds_process_purchase_form( $purchase_data ) {
$intent_args
);
$stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id' );
if (
! empty( $stripe_connect_account_id ) &&
! empty( edd_stripe()->connect()->get_connect_id() ) &&
true === edds_stripe_connect_account_country_supports_application_fees()
) {
$intent_args['application_fee_amount'] = round( $amount * 0.02 );

View File

@ -234,10 +234,10 @@ function edds_process_purchase_form( $purchase_data ) {
$intent_args
);
$stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id' );
$intent_type = 'PaymentIntent';
if (
! empty( $stripe_connect_account_id ) &&
! empty( edd_stripe()->connect()->get_connect_id() ) &&
true === edds_stripe_connect_account_country_supports_application_fees()
) {
$intent_args['application_fee_amount'] = round( $amount * 0.02 );

View File

@ -78,11 +78,10 @@ function edds_apple_pay_admin_notices_print() {
wp_enqueue_script( 'edds-admin-notices' );
try {
$is_connected = edd_get_option( 'stripe_connect_account_id', '' );
$error = edd_get_option( 'stripe_apple_pay_domain_error', '' );
$test_mode = edd_is_test_mode();
$error = edd_get_option( 'stripe_apple_pay_domain_error', '' );
$test_mode = edd_is_test_mode();
if ( ! empty( $is_connected ) && ! empty( $error ) && false === $test_mode ) {
if ( ! empty( edd_stripe()->connect()->is_connected ) && ! empty( $error ) && false === $test_mode ) {
$notices->output( 'apple-pay-' . $_SERVER['HTTP_HOST'] );
}
} catch( Exception $e ) {}
@ -189,8 +188,7 @@ function edds_apple_pay_create_directory_and_move_file() {
* @since 2.8.0
*/
function edds_apple_pay_check_domain() {
$is_connected = edd_get_option( 'stripe_connect_account_id', '' );
if ( empty( $is_connected ) ) {
if ( empty( edd_stripe()->connect()->is_connected ) ) {
return;
}
@ -221,7 +219,7 @@ add_action( 'admin_init', 'edds_apple_pay_check_domain', 10 );
*/
function edds_apple_pay_verify_domain() {
// If Stripe isn't connected, just return.
if ( empty( edd_get_option( 'stripe_connect_account_id', '' ) ) ) {
if ( empty( edd_stripe()->connect()->is_connected ) ) {
return;
}
@ -258,7 +256,7 @@ function edds_apple_pay_verify_domain() {
// Create directory and move file if needed.
edds_apple_pay_create_directory_and_move_file();
$stripe_connect_account_id = edd_get_option( 'stripe_connect_account_id', '' );
$stripe_connect_account_id = edd_stripe()->connect()->get_connect_id();
if (
empty( $stripe_connect_account_id ) || // If we don't have a stripe connect account ID

View File

@ -160,7 +160,7 @@ function edd_stripe_connect_admin_script( $hook ) {
return;
}
wp_enqueue_style( 'edd-stripe-admin-styles', EDDSTRIPE_PLUGIN_URL . 'assets/css/build/admin.min.css', array(), EDD_STRIPE_VERSION );
edd_stripe_connect_admin_style();
wp_enqueue_script( 'edd-stripe-admin-scripts', EDDSTRIPE_PLUGIN_URL . 'assets/js/build/admin.min.js', array( 'jquery' ), EDD_STRIPE_VERSION );
@ -180,3 +180,19 @@ function edd_stripe_connect_admin_script( $hook ) {
);
}
add_action( 'admin_enqueue_scripts', 'edd_stripe_connect_admin_script' );
/**
* Enqueues the Stripe admin style.
*
* @since 2.9.3
*
* @return void
*/
function edd_stripe_connect_admin_style() {
wp_enqueue_style(
'edd-stripe-admin-styles',
EDDSTRIPE_PLUGIN_URL . 'assets/css/build/admin.min.css',
array(),
EDD_STRIPE_VERSION
);
}

View File

@ -120,6 +120,7 @@ function edds_output_payment_elements_form() {
// Payment Elements needs to not allow checking out with mixed carts or multiple subscriptions.
if ( function_exists( 'edd_recurring' ) ) {
if ( ( count( edd_get_cart_contents() ) > 1 && edd_recurring()->cart_contains_recurring() ) || edd_recurring()->cart_is_mixed() ) {
add_filter( 'edd_checkout_button_purchase', '__return_empty_string', 999 );
?>
<div class="edd_errors edd-alert edd-alert-info">
<p class="edd_error" id="edd_error_edd-stripe-incompatible-cart"><?php echo edds_get_single_subscription_cart_error(); ?></p>

View File

@ -98,7 +98,7 @@ class InstalledVersions
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
}
}
@ -119,7 +119,7 @@ class InstalledVersions
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints((string) $constraint);
$constraint = $parser->parseConstraints($constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
@ -328,9 +328,7 @@ class InstalledVersions
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
@ -342,17 +340,12 @@ class InstalledVersions
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
self::$installed = require __DIR__ . '/installed.php';
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
$installed[] = self::$installed;
return $installed;
}

View File

@ -1,9 +1,9 @@
<?php return array(
'root' => array(
'name' => 'easy-digital-downloads/edd-stripe',
'pretty_version' => '2.9.2.2',
'version' => '2.9.2.2',
'reference' => '7e59ac4f4357cb3b388182e0601056f60f0b2407',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '53b4520542b33c13127f604da77f09f7cf9cf902',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@ -11,9 +11,9 @@
),
'versions' => array(
'easy-digital-downloads/edd-stripe' => array(
'pretty_version' => '2.9.2.2',
'version' => '2.9.2.2',
'reference' => '7e59ac4f4357cb3b388182e0601056f60f0b2407',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '53b4520542b33c13127f604da77f09f7cf9cf902',
'type' => 'wordpress-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

View File

@ -1260,7 +1260,7 @@ function edd_get_bot_name() {
function edd_redirect( $location = '', $status = 302 ) {
// Prevent redirects in unit tests.
if ( (bool) ( defined( 'WP_TESTS_DIR' ) && WP_TESTS_DIR ) || function_exists( '_manually_load_plugin' ) ) {
if ( edd_is_doing_unit_tests() ) {
return;
}
@ -1932,6 +1932,16 @@ function edd_is_inactive_pro() {
return ! $pass_manager->isPro();
}
/**
* Whether unit tests are running.
*
* @since 3.1.2
* @return bool
*/
function edd_is_doing_unit_tests() {
return (bool) ( ( defined( 'EDD_DOING_TESTS' ) && EDD_DOING_TESTS ) || function_exists( '_manually_load_plugin' ) );
}
/**
* Polyfills for is_countable and is_iterable
*

View File

@ -187,6 +187,7 @@ function edd_add_manual_order( $args = array() ) {
'discount' => $order_discount,
'total' => $order_total,
'date_created' => $date,
'order_number' => edd_set_order_number(),
)
);
@ -425,22 +426,6 @@ function edd_add_manual_order( $args = array() ) {
edd_update_order_meta( $order_id, 'unlimited_downloads', 1 );
}
// Setup order number.
$order_number = '';
if ( edd_get_option( 'enable_sequential' ) ) {
$number = edd_get_next_payment_number();
$order_number = edd_format_payment_number( $number );
update_option( 'edd_last_payment_number', $number );
// Update totals & maybe add order number.
edd_update_order( $order_id, array(
'order_number' => $order_number,
) );
}
// Stop purchase receipt from being sent.
if ( ! isset( $order_data['edd_order_send_receipt'] ) ) {
remove_action( 'edd_complete_purchase', 'edd_trigger_purchase_receipt', 999 );

View File

@ -791,7 +791,8 @@ function edd_build_order( $order_data = array() ) {
unset( $order_args['date_created'] );
edd_update_order( $order_id, $order_args );
} else {
$order_id = edd_add_order( $order_args );
$order_args['order_number'] = edd_set_order_number();
$order_id = edd_add_order( $order_args );
}
// If there is no order ID at this point, something went wrong.
@ -1141,18 +1142,8 @@ function edd_build_order( $order_data = array() ) {
}
}
// Setup order number.
if ( edd_get_option( 'enable_sequential' ) ) {
$number = edd_get_next_payment_number();
$order_args['order_number'] = edd_format_payment_number( $number );
update_option( 'edd_last_payment_number', $number );
}
// Update the order with all of the newly computed values.
edd_update_order( $order_id, array(
'order_number' => $order_args['order_number'],
'subtotal' => $subtotal,
'tax' => $total_tax,
'discount' => $total_discount,
@ -1373,3 +1364,15 @@ function edd_generate_order_payment_key( $key ) {
*/
return apply_filters( 'edd_generate_order_payment_key', $payment_key, $key );
}
/**
* Helper function to get and maybe update the order number.
*
* @since 3.1.1.2
* @return string
*/
function edd_set_order_number() {
$order_number = new EDD\Orders\Number();
return $order_number->apply();
}

View File

@ -634,14 +634,12 @@ class EDD_Payment {
}
}
if ( edd_get_option( 'enable_sequential' ) ) {
$number = edd_get_next_payment_number();
$this->number = edd_format_payment_number( $number );
$order_number = edd_set_order_number();
if ( $order_number ) {
$this->number = $order_number;
$this->update_meta( '_edd_payment_number', $this->number );
$order_data['order_number'] = $this->number;
update_option( 'edd_last_payment_number', $number );
}
edd_update_order( $order_id, $order_data );

View File

@ -696,7 +696,7 @@ class EDD_Payments_Query extends EDD_Stats {
}
if ( ! is_null( $this->args['post__not_in'] ) ) {
$arguments['id__in'] = $this->args['post__not_in'];
$arguments['id__not_in'] = $this->args['post__not_in'];
}
if ( ! empty( $this->args['mode'] ) && 'all' !== $this->args['mode'] ) {

View File

@ -1143,106 +1143,30 @@ function edd_get_payment_number( $order = 0 ) {
/**
* Formats the order number with the prefix and postfix.
*
* @todo As of 3.1.2, no longer used, but not officially deprecated. Deprecate.
* @since 2.4
*
* @param int $number The order number to format.
* @return string The formatted order number
*/
function edd_format_payment_number( $number ) {
if ( ! edd_get_option( 'enable_sequential' ) ) {
return $number;
}
$order_number = new EDD\Orders\Number();
if ( ! is_numeric( $number ) ) {
return $number;
}
$prefix = edd_get_option( 'sequential_prefix' );
$number = absint( $number );
$postfix = edd_get_option( 'sequential_postfix' );
$formatted_number = $prefix . $number . $postfix;
return apply_filters( 'edd_format_payment_number', $formatted_number, $prefix, $number, $postfix );
}
/**
* Gets the next available order number.
*
* This is used when inserting a new order.
*
* @since 2.0
*
* @return string $number The next available order number.
*/
function edd_get_next_payment_number() {
if ( ! edd_get_option( 'enable_sequential' ) ) {
return false;
}
$number = get_option( 'edd_last_payment_number' );
$start = edd_get_option( 'sequential_start', 1 );
$increment_number = true;
if ( false !== $number ) {
if ( empty( $number ) ) {
$number = $start;
$increment_number = false;
}
} else {
$last_order = edd_get_orders( array(
'number' => 1,
'orderby' => 'id',
'order' => 'desc',
) );
if ( ! empty( $last_order ) && $last_order[0] instanceof EDD\Orders\Order ) {
$number = (int) $last_order[0]->get_number();
}
if ( ! empty( $number ) && $number !== (int) $last_order[0]->id ) {
$number = edd_remove_payment_prefix_postfix( $number );
} else {
$number = $start;
$increment_number = false;
}
}
$increment_number = apply_filters( 'edd_increment_payment_number', $increment_number, $number );
if ( $increment_number ) {
$number++;
}
return apply_filters( 'edd_get_next_payment_number', $number );
return $order_number->format( $number );
}
/**
* Given a given a number, remove the pre/postfix.
*
* @since 2.4
*
* @todo As of 3.1.2, no longer used, but not officially deprecated. Deprecate.
* @param string $number The formatted number to increment.
* @return string The new order number without prefix and postfix.
*/
function edd_remove_payment_prefix_postfix( $number ) {
$prefix = (string) edd_get_option( 'sequential_prefix' );
$postfix = (string) edd_get_option( 'sequential_postfix' );
$order_number = new EDD\Orders\Number();
// Remove prefix
$number = preg_replace( '/' . $prefix . '/', '', $number, 1 );
// Remove the postfix
$length = strlen( $number );
$postfix_pos = strrpos( $number, strval( $postfix ) );
if ( false !== $postfix_pos ) {
$number = substr_replace( $number, '', $postfix_pos, $length );
}
// Ensure it's a whole number
$number = intval( $number );
return apply_filters( 'edd_remove_payment_prefix_postfix', $number, $prefix, $postfix );
return $order_number->unformat( $number );
}
/**

View File

@ -1310,6 +1310,10 @@ add_action( 'edd_checkout_error_checks', 'edd_check_purchase_email_length', 10,
*/
function edd_process_straight_to_gateway( $data ) {
if ( empty( $data['edd_straight_to_gateway'] ) || ! wp_verify_nonce( $data['edd_straight_to_gateway'], 'edd_straight_to_gateway' ) ) {
return;
}
$download_id = $data['download_id'];
$options = isset( $data['edd_options'] ) ? $data['edd_options'] : array();
$quantity = isset( $data['edd_download_quantity'] ) ? $data['edd_download_quantity'] : 1;

View File

@ -797,6 +797,9 @@ function edd_process_profile_editor_updates( $data ) {
// Fetch customer record.
$customer = edd_get_customer_by( 'user_id', $user_id );
if ( empty( $customer->user_id ) || $customer->user_id != $user_id ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
return false;
}
$display_name = isset( $data['edd_display_name'] ) ? sanitize_text_field( $data['edd_display_name'] ) : $old_user_data->display_name;
$first_name = isset( $data['edd_first_name'] ) ? sanitize_text_field( $data['edd_first_name'] ) : $old_user_data->first_name;
@ -947,43 +950,46 @@ function edd_process_profile_editor_updates( $data ) {
add_action( 'edd_edit_user_profile', 'edd_process_profile_editor_updates' );
/**
* Process the 'remove' URL on the profile editor when customers wish to remove an email address
* Process the 'remove' URL on the profile editor when customers wish to remove an email address.
*
* @since 2.6
* @param array $data The array of data passed from the profile editor.
* @return void
*/
function edd_process_profile_editor_remove_email() {
function edd_process_profile_editor_remove_email( $data ) {
if ( ! is_user_logged_in() ) {
return false;
return;
}
// Pending users can't edit their profile
if ( edd_user_pending_verification() ) {
return false;
return;
}
// Nonce security
if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'edd-remove-customer-email' ) ) {
return false;
if ( ! wp_verify_nonce( $data['_wpnonce'], 'edd-remove-customer-email' ) ) {
return;
}
if ( empty( $_GET['email'] ) || ! is_email( $_GET['email'] ) ) {
return false;
if ( empty( $data['email'] ) || ! is_email( $data['email'] ) ) {
return;
}
$customer = new EDD_Customer( get_current_user_id(), true );
if ( $customer->remove_email( $_GET['email'] ) ) {
$user_id = get_current_user_id();
$customer = new EDD_Customer( $user_id, true );
$url = add_query_arg( 'updated', true, $_GET['redirect'] );
if ( $customer->user_id == $user_id && $customer->remove_email( $data['email'] ) ) {
$url = add_query_arg( 'updated', true, $data['redirect'] );
$user = wp_get_current_user();
$user_login = ! empty( $user->user_login ) ? $user->user_login : edd_get_bot_name();
$customer_note = sprintf( __( 'Email address %s removed by %s', 'easy-digital-downloads' ), sanitize_email( $_GET['email'] ), $user_login );
$customer_note = sprintf( __( 'Email address %s removed by %s', 'easy-digital-downloads' ), sanitize_email( $data['email'] ), $user_login );
$customer->add_note( $customer_note );
} else {
edd_set_error( 'profile-remove-email-failure', __( 'Error removing email address from profile. Please try again later.', 'easy-digital-downloads' ) );
$url = $_GET['redirect'];
$url = $data['redirect'];
}
edd_redirect( $url );

View File

@ -224,6 +224,7 @@ function edd_get_purchase_link( $args = array() ) {
<?php endif; ?>
<?php if( ! empty( $args['direct'] ) && ! $download->is_free( $args['price_id'] ) ) { ?>
<input type="hidden" name="edd_action" class="edd_action_input" value="straight_to_gateway">
<?php wp_nonce_field( 'edd_straight_to_gateway', 'edd_straight_to_gateway', false ); ?>
<?php } else { ?>
<input type="hidden" name="edd_action" class="edd_action_input" value="add_to_cart">
<?php } ?>

View File

@ -161,7 +161,7 @@ add_filter( 'login_url', 'edd_update_login_url', 10, 3 );
function edd_update_login_url( $url, $redirect_to, $force_reauth ) {
// Don't change the login URL if the request is an admin request.
if ( is_admin() ) {
if ( ! edd_doing_ajax() && is_admin() ) {
return $url;
}

View File

@ -117,6 +117,13 @@ add_action( 'edd_user_lost_password', 'edd_handle_lost_password_request' );
* @return void
*/
function edd_handle_lost_password_request( $data ) {
// Verify the nonce.
if ( empty( $data['edd_lost-password_nonce'] ) || ! wp_verify_nonce( $data['edd_lost-password_nonce'], 'edd-lost-password-nonce' ) ) {
edd_set_error( 'edd_lost_password', __( 'Your request could not be completed.', 'easy-digital-downloads' ) );
return;
}
if ( 'POST' === $_SERVER['REQUEST_METHOD'] ) {
$errors = retrieve_password();
if ( ! is_wp_error( $errors ) ) {
@ -127,8 +134,12 @@ function edd_handle_lost_password_request( $data ) {
if ( $message ) {
// WP_Error messages include "Error:" so we remove that here to prevent duplication.
$message = explode( ':', $message );
$message = ! empty( $message[1] ) ? trim( $message[1] ) : trim( $message[0] );
edd_set_error( $id, $message );
$output = trim( $message[0] );
if ( ! empty( $message[1] ) ) {
unset( $message[0] );
$output = trim( implode( ':', $message ) );
}
edd_set_error( $error_code, $output );
}
}
}
@ -253,6 +264,11 @@ function edd_validate_password_reset( $data ) {
wp_die( __( 'Invalid password reset request.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 400 ) );
}
// Verify the nonce.
if ( ! isset( $data['edd_resetpassword_nonce'] ) || ! wp_verify_nonce( $data['edd_resetpassword_nonce'], 'edd-reset-password-nonce' ) ) {
edd_set_error( 'password_reset_failed', __( 'Invalid password reset request.', 'easy-digital-downloads' ) );
}
if ( empty( $data['rp_key'] ) ) {
edd_set_error( 'password_reset_failed', __( 'Invalid password reset request.', 'easy-digital-downloads' ) );
}

View File

@ -6,7 +6,7 @@ Tags: ecommerce, payments, sell, digital store, stripe
Requires at least: 5.4
Tested up to: 6.2
Requires PHP: 7.1
Stable Tag: 3.1.1.4.2
Stable Tag: 3.1.2
License: GNU Version 2 or Any Later Version
Sell your digital products with the #1 eCommerce plugin written for digital creators by digital creators.
@ -225,13 +225,51 @@ Yes, with an Extended Pass you get access to [Recurring Payments](https://easydi
8. Checkout - Default Theme
== Changelog ==
= 3.1.1.4.2, May 1, 2023 =
= 3.1.2 =
* New: The EDD "System Info" has been retired and instead our data is registered with WordPress Core's Site Health.
* Improvement: We've drastically reduced the possibility of a collision when using Sequential Order Numbers.
* Improvement: We've changed the 'Default' item in the Product Type dropdown to 'Single Product' to avoid confusion.
* Improvement: Gateways can now inform EDD if they are properly set up, and prevent enabling them if they are not configured.
* Improvement: The PayPal Commerce onboarding process has been revamped for speed and reliability.
* Improvement: The EDD 3.x migration process has been updated to defer all customer and product calculations until the migration is complete, with improved messaging.
* Improvement - Stripe: We've added a filter to allow users to remove the 'Terms' text that shows below card fields.
* Improvement - Stripe: When a user disconnects from Stripe Connect, Stripe is unchecked as an 'active' gateway.
* Improvement - Blocks: When no downloads are created, download related blocks were not correctly showing the button to add a new download.
* Improvement - Blocks: EDD's blocks were not respecting custom Download labels.
* Fix: Pass license keys did not always hold their activation status on multisite installs.
* Fix: In some edge cases, it was possible to produce a fatal error in PHP 8.0 when adding items to the cart.
* Fix: Improved capability checks and nonce detection on some actions.
* Fix: Item fees could fail validation in some cases, resulting in missed fees.
* Fix: The Payments Query class was incorrectly passing the `id__not_in` as `id__in`.
* Fix: The AJAX cart content response was not using the new method of getting cart item names.
* Fix: A more user friendly error message is shown to non-privileged users if no gateways are enabled.
* Fix: The Login URL in user registration emails was not correct when the purchase was made with Stripe.
* Fix: The calculated fees could differ from the fees that are displayed in the cart contents.
* Fix: When importing downloads, in some cases, the images were not identified as local files.
* Fix: The Download Tag taxonomy admin area was not being identified as an EDD Admin area.
* Fix: There was a possibility of an undefined variable when requesting a password reset.
* Fix - Stripe: The Recurring Payments update form could load incorrectly if split fields was enabled prior to swtiching to Payment Elements.
* Fix - Stripe: Multiple improvements to the Stripe form load states when cart recalculations are being run.
* Fix - Stripe: In some cases, the purchase form was not re-enabled after fixing HTML5 validation errors.
* Fix - Stripe: Customers updating the payment method for a failing subscription could see an error message when the failed invoice was voided, even though the subscription was updated successfully.
* Fix - Blocks: The reCAPTCHA key field is now a Password field type.
* Fix - Blocks: The User Downloads blocks could show duplicate items.
* Fix - Blocks: Extensions which added data to the cart could display without styling.
* Dev: The functions to get the lowest & highest price options have been abstracted, improved, and now have unit tests.
* Dev: Upgrade routines prior to 3.0 have been deprecated.
* Dev: A new CLI command, `recalculate_customer_values` has been registered to recalculate sales and earnings for all customers.
* Dev - Stripe: It is now possible to force 'Card Fields' to be available on new installs, by switching on EDD's Debug Mode.
View the full changelog at [https://easydigitaldownloads.com/changelog/](https://easydigitaldownloads.com/changelog/?utm_medium=readme&utm_source=wporg&utm_campaign=edd-plugin&utm_term=description)
= 3.1.1.4.2 =
* Security: Improved validation for edd hooks.
= 3.1.1.4.1, April 21, 2023 =
= 3.1.1.4.1 =
* Fix - Blocks: Harden blocks loader to verify files exist before requiring them.
= 3.1.1.4, April 20, 2023 =
= 3.1.1.4 =
* Improvement: Removed a possible unsupported PHP configuration from the email summaries.
* Improvement: The edd_get_users_purchases function has been updated to account for customer email address changes.
* Improvement: Reports have been updated to more accurately account for timezones and date ranges.
@ -253,8 +291,7 @@ Yes, with an Extended Pass you get access to [Recurring Payments](https://easydi
* Fix - Blocks: Cart section headings were not always displayed when reloading the section via AJAX.
* Dev: New custom hooks in database row transitions have been added.
= 3.1.1.3, March 23, 2023 =
= 3.1.1.3 =
* Improvement: The orders list table in the admin now sorts orders by date as the default.
* Improvement: Removed unnecessary options in the onboarding wizard.
* Improvement - Stripe: Store owners can now [control which payment methods to accept within their Stripe account](https://easydigitaldownloads.com/docs/stripe/#how-to-manage-payment-methods).
@ -263,7 +300,7 @@ Yes, with an Extended Pass you get access to [Recurring Payments](https://easydi
* Fix: Existing tables might not have been updated correctly.
* Fix: Attempting to update the default email address from the profile editor could fail in some circumstances.
= 3.1.1.2, March 17, 2023 =
= 3.1.1.2 =
* Improvement: The order details screen in the admin has been updated to use the Currency class to be consistent with customer receipts.
* Improvement: Determining whether a plugin is a core extension for telemetry data has been improved.
* Fix: Enabling/disabling the sequential order numbers setting no longer prompts an upgrade notice, since that setting does not affect past orders.
@ -275,7 +312,7 @@ Yes, with an Extended Pass you get access to [Recurring Payments](https://easydi
* Dev: Using `get_page_by_title` has been deprecated in WordPress 6.2; our importer has been updated accordingly.
* Dev - Stripe: Unneeded source files are no longer included in the release.
= 3.1.1.1, March 14, 2023 =
= 3.1.1.1 =
* Fix: Ensure that Stripe only tries to verify the domain for Apple Pay when Stripe is connected.
* Fix: PHP 7.1 Compatibility with Stripe.
* Improvement: Avoid a race condition when updating where a function might not be available for a moment.
@ -315,261 +352,5 @@ Yes, with an Extended Pass you get access to [Recurring Payments](https://easydi
* Dev: The discounts HTML is now always filterable, even if there are no discounts applied.
* Dev: Code for the legacy WordPress media loader has been removed.
= 3.1.0.6, February 9, 2023 =
* Improvement: The PayPal Backup IPN now sends the payment date when handling a renewal from Recurring Payments.
* Improvement: Further improve the AJAX download search.
* Fix: Improved reliability with the PayPal API.
* Fix: Some plugins could conflict with the login URL filter to customize the login page.
* Fix: It is now possible to deselect a page in the settings after it's been set.
* Fix: All documentation links have been updated to use the new locations.
* Fix: Some passwords could not be validated when using the login form on the checkout page.
* Fix: The orders export did not allow only orders with a specific status to be exported.
= 3.1.0.5, January 25, 2023 =
* Improvement: New customer report tiles now only count customers with purchases.
* Improvement: The email address field at checkout now adheres to the database schema and limits to 100 characters.
* Improvement: Further improve the AJAX download search to be more accurate.
* Fix: Earnings exports report now accounts for partially refunded orders.
* Fix: Added validation to prevent duplicate order addresses from being inserted.
* Fix: When saving a non-variable product, an empty post meta value was being saved.
* Improvement - Blocks: Updating the wording for the Disable Redownload setting if the block is available.
* Fix - Blocks: Added sanitization to the 'additional classes' block setting before rendering the block.
= 3.1.0.4, January 5, 2023 =
* Improvement: The cart performance has been improved by disabling tax rate lookups when a customer address is supplied, but taxes are disabled.
* Improvement: Reports now factor in order item adjustments like negative fees.
* Improvement: The Downloads list table now loads faster on sites with a large number of download categories.
* Improvement: The Sales REST API Endpoint was updated to respect the new order statuses in EDD 3.0.
* Improvement: Improve semantic markup by not allowing two of the same ID attribute for redirect to checkout buttons.
* Improvement: Discount code lookup performance has been improved when looking up a discount by the discount code.
* Fix: Looking up payments with a Download ID that was a string or integer would return incorrect or no orders.
* Fix: Reduced the number of HTTP calls that the notifications API can make per day.
* Fix: Avoid the "Request-URI Too Long" error when performing multiple actions in a row on list tables.
* Fix: Negative fee amounts are now properly considered when determining an item's final price in the cart.
* Fix: PayPal: Arabic characters in download names could cause an unexpected error during checkout.
* Fix: PayPal: The backup IPN is not loaded if the PayPal integration is not connected.
* Fix: PayPal: The payment_date field was assumed to be present when processing the backup IPN.
* Fix: The edd_get_payment_amount function could improperly return an empty string instead of a float value.
* Fix: Add to cart buttons were not using the token values to improve caching compatibility.
* Fix: When many items were purchased at once, some order item download links were not working due to an improper status.
* Fix: Hardened the search query for the AJAX endpoint for searching for downloads by title.
= 3.1.0.3, November 23, 2022 =
* Improvement: The PayPal webhook connect/disconnect process has been improved to ensure proper webhook delivery.
* Improvement: An IPN Backup has been added to the PayPal gateway, to avoid missing webhooks that may have been disconnected.
* Fix: PayPal Buy Now functionality has been fixed for guest users.
* Fix: Exporting orders was including orders with the Trash status.
* Fix: Trashed orders were showing in the purchase history shortcode (templates updated: history-downloads.php and history-purchases.php).
* Fix: The file downloads graph was formatting integers as currency.
* Fix: Searching by download ID on the Orders list table was not working.
* Fix: In some timezone settings, the reports could incorrectly display.
* Fix: Determining if a product can be purchased was improved for performance.
* Fix: Switching gateways when resuming an order was resulting in the wrong gateway value being added to the database.
* Fix: The migration process can now identify custom discount meta for migration to the new adjustment meta table.
* Fix: Non-Standard (but still supported by WordPress) directory structures could fail if the site_url and home_url were different.
* Fix: Discount amount calculations were assuming that the discount has Price ID assignments.
* Fix: Logging in from the {receipt_link} in emails now properly redirects the user to the receipt page.
* Fix - Blocks: The checkout block could prevent purchases if a logged in user did not have a name already.
* Fix - Blocks: The Order History block no longer shows Trashed orders.
* Fix - Blocks: Incompatible combinations of settings on the Checkout block could produce a fatal error.
= 3.1.0.2, October 27, 2022 =
* New - Blocks: The registration block now supports the WordPress password strength script.
* Improvement: The products API now includes the product permalink.
* Improvement: The user registration process and messaging has been updated to more closely match WordPress Core.
* Improvement: Searching in the product dropdown is now restricted to titles only.
* Improvement: The no-js/js class switcher has been prefixed and made more specific.
* Improvement: Editing a bundled product has been updated to be more performant.
* Improvement - Blocks: Fees in the cart/checkout blocks have been updated to more closely match cart items and other amounts.
* Improvement - Blocks: Update block definitions so that icons show on the repository.
* Improvement - Blocks: The order history block filter has been updated to not override filtered values.
* Improvement - Blocks: A filter has been added to the Terms block to allow users to filter the query.
* Fix: The 3.0 migration for customer addresses could create duplicate addresses.
* Fix: A redundant database update for customer addresses was removed from the 3.0 migration.
* Fix: The main checkout function now checks directly for the checkout block rather than relying on a filter.
* Fix: The Tools screen could time out on a site with a large number of products.
* Fix: The options for bundled products now show the general product in addition to each price option.
* Fix: For some time zones, reports could show incorrect dates for a range such as "last quarter".
* Fix: The block editor was not showing the correct list of authors for a download.
* Fix: Some settings for the legacy cart widget could not be disabled once saved.
* Fix: Customer names with unexpected characters could be improperly interpreted by spreadsheet apps.
* Fix - Blocks: The checkout helper function was incorrectly returning true.
* Fix - Blocks: The cart block is now disabled in the block editor.
* Fix - Blocks: The purchase link filter could incorrectly override previous adjustments to the button class.
* Dev: The CLI order migration has been updated to allow partial order migrations.
= 3.1.0.1.1, October 21, 2022 =
This is a very minor point release, with a single change to try and correct an issue within the PayPal API that is causing 403 and 400 errors.
It is not intended to resolve the issue within PayPal's API, but offer us some time to continue to work with PayPal to solve the issue long term without it impacting customer's purchases.
* IMPORTANT: If you have been experiencing issues with the PayPal webhooks, please update EDD and visit Downloads > Settings > Payments > PayPal and re-check your payment status and sync webhooks.
* Fix: Attempts to create a specific user-agent to send to PayPal for webhook validation to avoid 403/400 errors.
= 3.1.0.1, October 8, 2022 =
* Fix: With taxes enabled, updating the address fields in the shortcode would replace the cart with the cart block.
* Fix: The dashboard widget was not using the order currency to display amounts for recent orders.
* Fix: No JS fallback buttons were being improperly toggled by JavaScript changes.
= 3.1, October 6, 2022 =
* New: Websites running WordPress 5.8 and above (and PHP 7.0 or greater) have access to ten new registered EDD blocks.
* New: Store owners can receive weekly or monthly email summaries of their store's performance.
* New - Blocks: A new EDD Products block has been registered to display downloads.
* New - Blocks: A new EDD Terms block has been registered to display download categories or tags.
* New - Blocks: A new EDD Buy Button block has been registered to display a purchase button for any download.
* New - Blocks: A new EDD Cart block has been registered to show either a mini or full cart anywhere on your site.
* New - Blocks: A new EDD Order History block has been registered to show a customer's order history.
* New - Blocks: A new EDD Login block has been registered to render a login form which supports a full lost password recovery flow and reCAPTCHA support.
* New - Blocks: A new EDD Registration block has been registered to render a registration form which includes reCAPTCHA support.
* New - Blocks: A new EDD Receipt block has been registered to show a customer's receipt. This receipt supports guest purchases.
* New - Blocks: A new EDD Confirmation block has been registered to show some order details when successfully completing a purchase.
* New - Blocks: A new EDD Checkout block has been registered to completely update the EDD checkout experience. This block is still considered to be in beta.
* Improvement: Store owners can now require that a user be logged into their account to download files.
* Improvement: The CLI migration to EDD 3.0 has been updated to improve memory usage for larger stores.
* Improvement: The PayPal Commerce button is disabled until required fields have been completed.
* Improvement: Relative date ranges are now compared against similar ranges in reports.
* Improvement: Report line graphs with multiple scales now use unique y-axes to display data.
* Improvement: Development asset files have been removed from the final build.
* Improvement: Updating download calculations has been moved from the order completion process to a slightly delayed cron event.
* Improvement: Dismissing the advanced filters on the order table has been improved.
* Improvement: Filters have been added to prevent certain logs from being recorded.
* Improvement: EDD registered pages now show in the pages list table.
* Improvement: The order ID column in the orders table no longer has a constrained width.
* Improvement: Store admins can now view the customer receipt from a link on the orders table.
* Improvement - Blocks: A confirmation page/block has been registered to separate the order completion view from the receipt.
* Improvement - Blocks: If the core EDD cart and terms widgets are not already in use on the site, they will not be displayed in the block editor as legacy widgets.
* Improvement - Stripe: Session validation throughout Stripe actions has been updated to improve reliability.
* Improvement - Stripe: Error messages have been updated to help customers with failed purchases know what action to take.
* Improvement - Stripe: Supported payment methods are included in the gateway registration.
* Improvement - Stripe: Optimized validation during checkout.
* Improvement - Stripe: Optimized cleanup of logging.
* Improvement - Stripe: Added better checkout session handling.
* Fix: Resetting the store was incorrectly deleting discounts and tax rates.
* Fix: The price option assignment for variably priced bundled product conditions could be incorrectly assigned.
* Fix: Report graphs could be inaccurate when grouping by month due to time zone adjustments.
* Fix: Querying the Stats API for a store using a UTC relative time zone would crash the site.
* Fix: Calculations for report tiles have been updated for consistency.
* Fix: The `edd_load_gateway` JavaScript hook is now triggered when only one gateway is active.
* Fix: Adding an adjustment on a manual order could cause unexpected cursor behavior.
* Fix: Using `edd_insert_payment` with incomplete data now creates an order if possible, or fails without errors if not.
* Fix: Legacy log functions now query logs correctly.
* Fix: Stores with more than 30 tax rates now can view all rates on the settings screen.
* Fix: Deleting a customer now properly deletes their orders as well.
* Fix: It is now possible to set a 0% tax rate for a region to exclude taxes from being collected for that region even if a country wide rate exists.
* Fix: When selecting a gateway and refreshing the checkout screen, some browsers could fail to load the payment fields.
* Fix: Searching the orders table for a discount code which does not exist now correctly returns no orders.
* Fix: The customers API endpoint now uses the correct parameters to return data.
* Fix: When registering a new user from an EDD form, spaces were incorrectly removed from user names.
* Fix: When the browser timezone differed from that of the Store, line graphs could offset the points from the gridlines.
* Fix: Users with the shop worker role were not able to create new downloads.
* Fix: Upon activation, EDD could have thrown a PHP notice about the orders table not existing on new installs.
* Fix - Stripe: Customers were not always automatically logged in with Auto Register's successful purchase setting.
* Fix - Stripe: When changing the store mode, the Stripe admin notice displayed incorrectly.
* Dev: Legacy compatibility code has been removed from the downloads metabox.
* Dev: A filter has been added to the customer row actions.
* Dev: Drop-ins have been added to the system information file.
* Dev: Templates which have been overridden now show in the system information file.
* Dev: Test mode can now be activated by setting a constant and the setting will reflect this.
= 3.0.4, September 6, 2022 =
* Fix: Stripe Pro license key detection was not working on older versions of the Stripe Pro gateway.
* Fix: Hour by hour graphs that spanned more than one day would group all data into the first day.
* Fix: Reports that span more than one year would group stats by month only.
* Fix: Some of the report tiles were not accurately accounting for refunded orders.
* Fix: The purchase receipt was limited to only showing 30 items.
* Fix: When using persistent object caching, discount codes would not always update immediately.
* Fix: When manually adding a new order, region based tax rates were not updating.
* Fix: Improved migration of order address data when checking tax rates of previous orders.
* Fix: The `stats` API endpoint data did not match the reports data. This improves the iOS app accuracy.
* Fix: The template modification checks for 3.0 compatibility were checking for modifications too often.
* Fix: Guest customers using an email address associated with an existing user were not always connected.
* Fix: When editing an order's address, it was not always saving changes.
* Dev: Actions were added to the `edd_add_customer` and `edd_update_customer` functions.
= 3.0.3, August 16, 2022 =
* New: Added support for Global Tax rates as a fallback with the new Tax Rates UI.
* Fix: The old 'fallback tax rate' was not imported as a new tax rate.
* Fix: Improved discount code validation with product restrictions and requirements.
* Fix: Viewing a custom report with a date range over 2 days could throw an undefined variable notice.
* Fix: Single priced downloads were showing incorrect stats in reports.
* Fix: Adding a download to a new order would not let you manually set prices in Safari.
* Fix: When an order with a discount code is deleted, the discount code's usage count is decreased.
* Fix: The total refund amount tile was incorrectly calculating the relative percentage.
* Fix: The customer table upgrade assumed the table prefix hadn't been changed after installation of EDD 2.x.
* Fix: The 3.0 migration could incorrectly identify a price ID as invalid and set it to the default price ID.
* Fix: The file download log could produce an notice if a file had been deleted from a product.
= 3.0.2.1, July 28, 2022 =
* Fix: Upgrade warning notices were showing incorrectly for some sites.
= 3.0.2, July 26, 2022 =
* Fix: Customer verification URL was not working in the admin.
* Fix: When cancelling an order once at PayPal, the checkout page could produce a Javascript error.
* Fix: Swedish postal codes would not pass validation.
* Fix: Non-Shop Manager roles could no longer leave notes on orders.
* Fix: Searching orders was not working in the admin.
* Fix: Template: Download History shortcode was not providing access to bundled products.
* Fix: 3.0 Migration: Stores with no orders, but other data like discounts, did not prompt the user to run the migration.
* Fix: EDD admin menu bar styles were not always loading correctly.
* Fix: An admin notice is now shown if EDD detects that it was unable to create the proper database tables.
* Fix: When showing taxes on product pricing, the % character was showing twice.
* Fix: Improved error handling around importer tools.
= 3.0.1, July 15, 2022 =
* Fix: Setting the EDD_USE_PHP_SESSIONS constant to 'false' could result in empty carts.
* Fix: Exporting reports with 'All Statuses' and a country/region fails.
* Fix: Adding more than one additional customer email address in a row failed.
* Fix: A fatal error could be triggered when attempting to output the JSON-LD structured data.
* Fix: Adjust the debug mode setting to be more clearly stated.
* Fix: Report graphs did not support hour-by-hour for some custom date queries.
= 3.0, July 13, 2022 =
* IMPORTANT: This is a major release, and should be tested in your staging environments prior to running on your live site.
* Upgrade: This update will ask you to perform database maintenance once installed. Your site should remain functional during this time, but access to historical store data will be limited until the migration is complete.
* New: Custom database tables have been added for all transactional data types in EDD.
* New: Migrate orders, order items, tax rates, discount codes, fees, customer addresses, and transaction details to custom tables with the UI or WP-CLI migration tool.
* New: All new reporting with advanced features for orders, downloads, customers, refunds, taxes, and more.
* New: Downloads now use the Block Editor and are available in the REST API.
* New: Improved tax settings, allowing historical data to be determined.
* New: Fully featured Refund system, for accurate reporting which includes partial and full refund support.
* New: Refunds can be initiated from within EDD for gateways which support it.
* New: Filter orders with advanced rules like purchase total, product, country, or state.
* New: New email marker insertion interface to assist in creating emails.
* New: Ability to manually add orders, without an extension; the Manual Purchases extension will be deactivated automatically.
* New: Discounts support start and end times, in addition to dates.
* New: Discounts now support notes.
* New: Use JSON-LD format for schema output.
* New: The order details views have been redesigned completely to make managing orders easier.
* Improvement: CSS styles have been updated and modernized throughout, including for jQuery and Chosen, as well as to improve mobile responsiveness.
* Improvement: Chosen has been updated for improved performance and accessibility.
* Improvement: Admin table views have been revised to be more responsive and consistent with WordPress core.
* Improvement: Dates for orders and related data are stored in the database in UTC, and displayed in the stores time zone.
* Improvement: Discounts which have been used at least once can no longer be deleted.
* Improvement: Admin screens, settings and input fields have been revised for improved accessibility.
* Improvement: Order items for variably priced products now include the price option name.
* Improvement: Language files have been removed from the deliverable package, and will rely on translate.wordpress.org going forward.
* Improvement: Introduce a "Store Gateway" to handle free orders and orders not handled through another gateway.
* Improvement: EDD HTML fields can now be required.
* Improvement: Admin table views have been rewritten to more accurately represent object status counts.
* Improvement: Because orders can be partially refunded, file deliverability is evaluated per order item, not order.
* Improvement: Download and customer sales and earnings are now dynamically calculated.
* Fix: Additional order statuses (like renewals) were not consistently included when querying for orders.
* Fix: Customers were failing to be created when their email address exceeded 50 characters.
* Fix: Improved performance of the `edd_has_user_purchased()` function.
* Fix: Average earnings now accounts for fees.
* Fix: The customer's list table could show an empty customer name.
* Fix: Greatly improved the performance of the cart total calculation.
* Fix: Single price products are saved to the order items table with a null price ID, to differentiate from variable products with a 0 price ID.
* Templates: The receipt, order history, and download history templates have been updated to work with new order functions.
* Dev: Introduced `edd_get_`, `edd_add_`, and `edd_delete_` helper functions to access new database methods.
* Dev: Introduced `edd_maybe_add_customer_address` to ensure that only unique physical addresses are added to a customer.
* Dev: Introduced helper functions such as `edd_get_admin_url`, `edd_is_dev_environment`, and `edd_redirect` to reduce the need to write repeated code.
* Dev: The minimum PHP version has been updated to 5.6.
* Dev: The minimum WordPress version has been updated to 4.9.
* Dev: Added new helper functions to retrieve order status by state like gross, net, recoverable, deliverable.
* Dev: A new `edd_is_cart_empty()` function was added.
* Dev: Orders now use 'complete' as the final state instead of 'publish'.
* Dev: Moved all script and style generation to use webpack.
* Dev: EDD style settings have been deprecated.
== Upgrade Notice ==
IMPORTANT: Upgrading from Easy Digital Downloads 2.9.x to 3.0+ is a major release that includes many improvements and changes. You will be asked to perform database maintenance once installed. Please ensure you make a backup of your site prior to upgrading. Your site should remain functional during this maintenance, but as with all updates, it is best to make a backup of your site prior to updating.

View File

@ -34,6 +34,31 @@ class DownloadURL {
* @return bool|string
*/
public function get_url() {
return false !== strpos( $this->plugin, 'https://downloads.wordpress.org/plugin' ) ? $this->plugin : false;
if ( ! $this->plugin ) {
return false;
}
if ( false === strpos( $this->plugin, 'https://downloads.wordpress.org/plugin' ) ) {
return false;
}
if ( ! in_array( $this->plugin, $this->get_allowed_urls(), true ) ) {
return false;
}
return $this->plugin;
}
/**
* Gets an array of allowed download URLs.
*
* @since 3.1.2
* @return array
*/
private function get_allowed_urls() {
return array(
'https://downloads.wordpress.org/plugin/edd-auto-register.zip',
'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip',
'https://downloads.wordpress.org/plugin/google-analytics-for-wordpress.zip',
'https://downloads.wordpress.org/plugin/all-in-one-seo-pack.zip',
);
}
}

View File

@ -42,10 +42,7 @@ class Actions implements SubscriberInterface {
* @return void
*/
public function refresh() {
if ( ! current_user_can( 'manage_options' ) ) {
edd_redirect( $this->handler->get_extensions_url() );
}
if ( get_transient( 'edd_pass_refreshed' ) ) {
if ( ! $this->can_refresh() ) {
edd_redirect( $this->handler->get_extensions_url() );
}
@ -65,7 +62,6 @@ class Actions implements SubscriberInterface {
'edd_action' => 'check_license',
'license' => $pass_data->key,
'item_id' => $pass_data->pass_id,
'item_name' => $pass_data->item_name,
);
$license_data = $this->handler->remote_request( $api_params );
@ -80,4 +76,20 @@ class Actions implements SubscriberInterface {
edd_redirect( $this->handler->get_extensions_url() );
}
/**
* Check if the current user can refresh the pass status.
*
* @return bool
*/
private function can_refresh() {
if ( ! current_user_can( 'manage_options' ) ) {
return false;
}
if ( get_transient( 'edd_pass_refreshed' ) ) {
return false;
}
return true;
}
}

View File

@ -94,7 +94,7 @@ class Ajax implements SubscriberInterface {
'endpoint' => $endpoint,
'version' => EDD_VERSION,
'siteurl' => admin_url(),
'homeurl' => home_url(),
'homeurl' => network_home_url(),
'redirect' => rawurldecode( base64_encode( $redirect ) ), // phpcs:ignore
),
'https://upgrade.easydigitaldownloads.com'

Some files were not shown because too many files have changed in this diff Show More