updated plugin Easy Digital Downloads
version 3.1.1.2
This commit is contained in:
@ -1,181 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin Add-ons
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Admin/Add-ons
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 1.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly.
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Add-ons Page
|
||||
*
|
||||
* Renders the add-ons page content.
|
||||
*
|
||||
* @since 1.0
|
||||
* @return void
|
||||
*/
|
||||
function edd_add_ons_page() {
|
||||
|
||||
// Filter the add-ons tabs.
|
||||
$add_ons_tabs = apply_filters( 'edd_add_ons_tabs', array(
|
||||
'popular' => __( 'Popular', 'easy-digital-downloads' ),
|
||||
'new' => __( 'New', 'easy-digital-downloads' ),
|
||||
'all' => __( 'All', 'easy-digital-downloads' )
|
||||
) );
|
||||
|
||||
// Active tab.
|
||||
$active_tab = isset( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $add_ons_tabs )
|
||||
? sanitize_key( $_GET['tab'] )
|
||||
: 'popular';
|
||||
|
||||
// Empty tabs array.
|
||||
$tabs = array();
|
||||
|
||||
// Loop through add-ons and make array of tabs.
|
||||
foreach ( $add_ons_tabs as $tab_id => $tab_name ) {
|
||||
|
||||
// "All"
|
||||
if ( 'all' === $tab_id ) {
|
||||
$tab_url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/downloads/',
|
||||
array(
|
||||
'utm_medium' => 'addons-page',
|
||||
'utm_content' => 'all-extensions',
|
||||
)
|
||||
);
|
||||
|
||||
// All other tabs besides "All".
|
||||
} else {
|
||||
$tab_url = add_query_arg( array(
|
||||
'settings-updated' => false,
|
||||
'tab' => sanitize_key( $tab_id ),
|
||||
) );
|
||||
}
|
||||
|
||||
// Active?
|
||||
$active = ( $active_tab === $tab_id )
|
||||
? 'current'
|
||||
: '';
|
||||
|
||||
// Count.
|
||||
$count = ( 'all' === $tab_id )
|
||||
? '150+'
|
||||
: '29';
|
||||
|
||||
// The link.
|
||||
$tab = '<li class="' . esc_attr( $tab_id ) . '">';
|
||||
$tab .= ( 'all' === $tab_id )
|
||||
? '<a href="' . esc_url( $tab_url ) . '" class="' . esc_attr( $active ) . '" target="_blank">'
|
||||
: '<a href="' . esc_url( $tab_url ) . '" class="' . esc_attr( $active ) . '">';
|
||||
|
||||
$tab .= esc_html( $tab_name );
|
||||
$tab .= ' <span class="count">(' . esc_html( $count ) . ')</span>';
|
||||
|
||||
// "All" is an external link, so denote it as such.
|
||||
if ( 'all' === $tab_id ) {
|
||||
$tab .= '<span class="dashicons dashicons-external"></span>';
|
||||
}
|
||||
|
||||
$tab .= '</a>';
|
||||
$tab .= '</li>';
|
||||
|
||||
// Set the tab.
|
||||
$tabs[] = $tab;
|
||||
}
|
||||
|
||||
// Start a buffer.
|
||||
ob_start(); ?>
|
||||
|
||||
<div class="wrap" id="edd-add-ons">
|
||||
<h1>
|
||||
<?php _e( 'Apps and Integrations for Easy Digital Downloads', 'easy-digital-downloads' ); ?>
|
||||
<span>
|
||||
<?php
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/downloads/',
|
||||
array(
|
||||
'utm_medium' => 'addons-page',
|
||||
'utm_content' => 'browse-all',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<a href="<?php echo $url; ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Browse All Integrations', 'easy-digital-downloads' ); ?></a>
|
||||
</span>
|
||||
</h1>
|
||||
<p><?php _e( 'These <em><strong>add functionality</strong></em> to your Easy Digital Downloads powered store.', 'easy-digital-downloads' ); ?></p>
|
||||
|
||||
<ul class="subsubsub"><?php echo implode( ' | ', $tabs ); ?></ul>
|
||||
|
||||
<div class="edd-add-ons-container">
|
||||
<?php
|
||||
// Display all add ons.
|
||||
echo wp_kses_post( edd_add_ons_get_feed( $active_tab ) );
|
||||
?>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div class="edd-add-ons-footer">
|
||||
<?php
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/downloads/',
|
||||
array(
|
||||
'utm_medium' => 'addons-page',
|
||||
'utm_content' => 'browse-all',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<a href="<?php echo $url; ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Browse All Integrations', 'easy-digital-downloads' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
// Output the current buffer.
|
||||
echo ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add-ons Get Feed
|
||||
*
|
||||
* Gets the add-ons page feed.
|
||||
*
|
||||
* @since 1.0
|
||||
* @return void
|
||||
*/
|
||||
function edd_add_ons_get_feed( $tab = 'popular' ) {
|
||||
|
||||
// Transient.
|
||||
$trans_key = 'easydigitaldownloads_add_ons_feed_' . $tab;
|
||||
$cache = get_transient( $trans_key );
|
||||
|
||||
// No add ons, so reach out and get some.
|
||||
if ( false === $cache ) {
|
||||
$url = 'https://easydigitaldownloads.com/?feed=addons';
|
||||
|
||||
// Popular.
|
||||
if ( 'popular' !== $tab ) {
|
||||
$url = add_query_arg( array( 'display' => sanitize_key( $tab ) ), $url );
|
||||
}
|
||||
|
||||
// Remote request.
|
||||
$feed = wp_remote_get( esc_url_raw( $url ), array( 'sslverify' => false ) );
|
||||
|
||||
// Handle error.
|
||||
if ( empty( $feed ) || is_wp_error( $feed ) ) {
|
||||
$cache = '<div class="error"><p>' . __( 'These extensions could not be retrieved from the server. Please try again later.', 'easy-digital-downloads' ) . '</div>';
|
||||
|
||||
// Cache the results.
|
||||
} elseif ( isset( $feed['body'] ) && strlen( $feed['body'] ) > 0 ) {
|
||||
$cache = wp_remote_retrieve_body( $feed );
|
||||
set_transient( $trans_key, $cache, HOUR_IN_SECONDS );
|
||||
}
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
@ -115,8 +115,7 @@ function edd_maybe_add_store_mode_admin_bar_menu( $wp_admin_bar ) {
|
||||
),
|
||||
) );
|
||||
|
||||
$pass_manager = new \EDD\Admin\Pass_Manager();
|
||||
if ( false === $pass_manager->has_pass() ) {
|
||||
if ( ! edd_is_pro() ) {
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/lite-upgrade/',
|
||||
array(
|
||||
|
@ -73,3 +73,212 @@ function edd_trigger_purchase_delete( $data ) {
|
||||
}
|
||||
}
|
||||
add_action( 'edd_delete_payment', 'edd_trigger_purchase_delete' );
|
||||
|
||||
/**
|
||||
* Add-ons Page
|
||||
*
|
||||
* Renders the add-ons page content.
|
||||
*
|
||||
* @since 1.0
|
||||
* @deprecated 3.1.1
|
||||
* @return void
|
||||
*/
|
||||
function edd_add_ons_page() {
|
||||
|
||||
_edd_deprecated_function( __FUNCTION__, '3.1.1' );
|
||||
|
||||
// Filter the add-ons tabs.
|
||||
$add_ons_tabs = apply_filters( 'edd_add_ons_tabs', array(
|
||||
'popular' => __( 'Popular', 'easy-digital-downloads' ),
|
||||
'new' => __( 'New', 'easy-digital-downloads' ),
|
||||
'all' => __( 'All', 'easy-digital-downloads' )
|
||||
) );
|
||||
|
||||
// Active tab.
|
||||
$active_tab = isset( $_GET['tab'] ) && array_key_exists( $_GET['tab'], $add_ons_tabs )
|
||||
? sanitize_key( $_GET['tab'] )
|
||||
: 'popular';
|
||||
|
||||
// Empty tabs array.
|
||||
$tabs = array();
|
||||
|
||||
// Loop through add-ons and make array of tabs.
|
||||
foreach ( $add_ons_tabs as $tab_id => $tab_name ) {
|
||||
|
||||
// "All"
|
||||
if ( 'all' === $tab_id ) {
|
||||
$tab_url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/downloads/',
|
||||
array(
|
||||
'utm_medium' => 'addons-page',
|
||||
'utm_content' => 'all-extensions',
|
||||
)
|
||||
);
|
||||
|
||||
// All other tabs besides "All".
|
||||
} else {
|
||||
$tab_url = add_query_arg( array(
|
||||
'settings-updated' => false,
|
||||
'tab' => sanitize_key( $tab_id ),
|
||||
) );
|
||||
}
|
||||
|
||||
// Active?
|
||||
$active = ( $active_tab === $tab_id )
|
||||
? 'current'
|
||||
: '';
|
||||
|
||||
// Count.
|
||||
$count = ( 'all' === $tab_id )
|
||||
? '150+'
|
||||
: '29';
|
||||
|
||||
// The link.
|
||||
$tab = '<li class="' . esc_attr( $tab_id ) . '">';
|
||||
$tab .= ( 'all' === $tab_id )
|
||||
? '<a href="' . esc_url( $tab_url ) . '" class="' . esc_attr( $active ) . '" target="_blank">'
|
||||
: '<a href="' . esc_url( $tab_url ) . '" class="' . esc_attr( $active ) . '">';
|
||||
|
||||
$tab .= esc_html( $tab_name );
|
||||
$tab .= ' <span class="count">(' . esc_html( $count ) . ')</span>';
|
||||
|
||||
// "All" is an external link, so denote it as such.
|
||||
if ( 'all' === $tab_id ) {
|
||||
$tab .= '<span class="dashicons dashicons-external"></span>';
|
||||
}
|
||||
|
||||
$tab .= '</a>';
|
||||
$tab .= '</li>';
|
||||
|
||||
// Set the tab.
|
||||
$tabs[] = $tab;
|
||||
}
|
||||
|
||||
// Start a buffer.
|
||||
ob_start(); ?>
|
||||
|
||||
<div class="wrap" id="edd-add-ons">
|
||||
<h1>
|
||||
<?php _e( 'Apps and Integrations for Easy Digital Downloads', 'easy-digital-downloads' ); ?>
|
||||
<span>
|
||||
<?php
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/downloads/',
|
||||
array(
|
||||
'utm_medium' => 'addons-page',
|
||||
'utm_content' => 'browse-all',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<a href="<?php echo $url; ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Browse All Integrations', 'easy-digital-downloads' ); ?></a>
|
||||
</span>
|
||||
</h1>
|
||||
<p><?php _e( 'These <em><strong>add functionality</strong></em> to your Easy Digital Downloads powered store.', 'easy-digital-downloads' ); ?></p>
|
||||
|
||||
<ul class="subsubsub"><?php echo implode( ' | ', $tabs ); ?></ul>
|
||||
|
||||
<div class="edd-add-ons-container">
|
||||
<?php
|
||||
// Display all add ons.
|
||||
echo wp_kses_post( edd_add_ons_get_feed( $active_tab ) );
|
||||
?>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div class="edd-add-ons-footer">
|
||||
<?php
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/downloads/',
|
||||
array(
|
||||
'utm_medium' => 'addons-page',
|
||||
'utm_content' => 'browse-all',
|
||||
)
|
||||
);
|
||||
?>
|
||||
<a href="<?php echo $url; ?>" class="button button-primary" target="_blank"><?php esc_html_e( 'Browse All Integrations', 'easy-digital-downloads' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
|
||||
// Output the current buffer.
|
||||
echo ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add-ons Get Feed
|
||||
*
|
||||
* Gets the add-ons page feed.
|
||||
*
|
||||
* @since 1.0
|
||||
* @deprecated 3.1.1
|
||||
* @return void
|
||||
*/
|
||||
function edd_add_ons_get_feed( $tab = 'popular' ) {
|
||||
_edd_deprecated_function( __FUNCTION__, '3.1.1' );
|
||||
|
||||
// Transient.
|
||||
$trans_key = 'easydigitaldownloads_add_ons_feed_' . $tab;
|
||||
$cache = get_transient( $trans_key );
|
||||
|
||||
// No add ons, so reach out and get some.
|
||||
if ( false === $cache ) {
|
||||
$url = 'https://easydigitaldownloads.com/?feed=addons';
|
||||
|
||||
// Popular.
|
||||
if ( 'popular' !== $tab ) {
|
||||
$url = add_query_arg( array( 'display' => sanitize_key( $tab ) ), $url );
|
||||
}
|
||||
|
||||
// Remote request.
|
||||
$feed = wp_remote_get( esc_url_raw( $url ), array( 'sslverify' => false ) );
|
||||
|
||||
// Handle error.
|
||||
if ( empty( $feed ) || is_wp_error( $feed ) ) {
|
||||
$cache = '<div class="error"><p>' . __( 'These extensions could not be retrieved from the server. Please try again later.', 'easy-digital-downloads' ) . '</div>';
|
||||
|
||||
// Cache the results.
|
||||
} elseif ( isset( $feed['body'] ) && strlen( $feed['body'] ) > 0 ) {
|
||||
$cache = wp_remote_retrieve_body( $feed );
|
||||
set_transient( $trans_key, $cache, HOUR_IN_SECONDS );
|
||||
}
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the Extensions submenu page under the "Downloads" menu
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @global $edd_add_ons_page
|
||||
*/
|
||||
function edd_add_extentions_link() {
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
global $submenu, $edd_add_ons_page;
|
||||
|
||||
$edd_add_ons_page = add_submenu_page( 'edit.php?post_type=download', __( 'EDD Extensions', 'easy-digital-downloads' ), __( 'Extensions', 'easy-digital-downloads' ), 'manage_shop_settings', 'edd-addons', 'edd_add_ons_page' );
|
||||
$pass_manager = new \EDD\Admin\Pass_Manager();
|
||||
if ( ! $pass_manager->has_pass() ) {
|
||||
$submenu[ 'edit.php?post_type=download' ][] = array(
|
||||
'<span class="edd-menu-highlight">' . esc_html__( 'Upgrade to Pro', 'easy-digital-downloads' ) . '</span>',
|
||||
'manage_shop_settings',
|
||||
edd_link_helper(
|
||||
'https://easydigitaldownloads.com/lite-upgrade',
|
||||
array(
|
||||
'utm_medium' => 'admin-menu',
|
||||
'utm_content' => 'upgrade-to-pro',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
add_action( 'admin_print_styles', function() {
|
||||
?>
|
||||
<style>#menu-posts-download li:last-child {background-color: #1da867;}#menu-posts-download li:last-child a,#menu-posts-download li:last-child a:hover{color: #FFFFFF !important;font-weight: 600;}</style>
|
||||
<?php
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@ -102,43 +102,6 @@ function edd_add_options_link() {
|
||||
}
|
||||
add_action( 'admin_menu', 'edd_add_options_link', 10 );
|
||||
|
||||
/**
|
||||
* Create the Extensions submenu page under the "Downloads" menu
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @global $edd_add_ons_page
|
||||
*/
|
||||
function edd_add_extentions_link() {
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
global $submenu, $edd_add_ons_page;
|
||||
|
||||
$edd_add_ons_page = add_submenu_page( 'edit.php?post_type=download', __( 'EDD Extensions', 'easy-digital-downloads' ), __( 'Extensions', 'easy-digital-downloads' ), 'manage_shop_settings', 'edd-addons', 'edd_add_ons_page' );
|
||||
$pass_manager = new \EDD\Admin\Pass_Manager();
|
||||
if ( ! $pass_manager->has_pass() ) {
|
||||
$submenu[ 'edit.php?post_type=download' ][] = array(
|
||||
'<span class="edd-menu-highlight">' . esc_html__( 'Upgrade to Pro', 'easy-digital-downloads' ) . '</span>',
|
||||
'manage_shop_settings',
|
||||
edd_link_helper(
|
||||
'https://easydigitaldownloads.com/lite-upgrade',
|
||||
array(
|
||||
'utm_medium' => 'admin-menu',
|
||||
'utm_content' => 'upgrade-to-pro',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
add_action( 'admin_print_styles', function() {
|
||||
?>
|
||||
<style>#menu-posts-download li:last-child {background-color: #1da867;}#menu-posts-download li:last-child a,#menu-posts-download li:last-child a:hover{color: #FFFFFF !important;font-weight: 600;}</style>
|
||||
<?php
|
||||
} );
|
||||
}
|
||||
}
|
||||
add_action( 'admin_menu', 'edd_add_extentions_link', 99999 );
|
||||
|
||||
/**
|
||||
* Whether the current admin area page is one that allows the insertion of a
|
||||
* button to make inserting Downloads easier.
|
||||
|
@ -30,6 +30,7 @@ class EDD_Notices {
|
||||
* @since 2.3
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'admin_notices', array( $this, 'remove_notices' ), 0 );
|
||||
add_action( 'edd_dismiss_notices', array( $this, 'dismiss_notices' ) );
|
||||
add_action( 'admin_init', array( $this, 'add_notices' ), 20 );
|
||||
add_action( 'admin_notices', array( $this, 'display_notices' ), 30 );
|
||||
@ -55,10 +56,10 @@ class EDD_Notices {
|
||||
'id' => '',
|
||||
'message' => '',
|
||||
'class' => false,
|
||||
'is_dismissible' => true
|
||||
'is_dismissible' => true,
|
||||
) );
|
||||
|
||||
$default_class ='updated';
|
||||
$default_class = 'updated';
|
||||
|
||||
// One message as string
|
||||
if ( is_string( $r['message'] ) ) {
|
||||
@ -142,6 +143,8 @@ class EDD_Notices {
|
||||
if ( ! empty( $_REQUEST['edd-message'] ) ) {
|
||||
$this->add_user_action_notices( $_REQUEST['edd-message'] );
|
||||
}
|
||||
|
||||
$_SERVER['REQUEST_URI'] = remove_query_arg( array( 'edd-message' ), $_SERVER['REQUEST_URI'] );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,6 +208,47 @@ class EDD_Notices {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unneed admin notices from EDD admin screens.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @return void
|
||||
*/
|
||||
public function remove_notices() {
|
||||
if ( ! edd_is_admin_page() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wp_filter;
|
||||
$all_hooks = $wp_filter['admin_notices']->callbacks;
|
||||
|
||||
foreach ( $all_hooks as $priority => $priority_actions ) {
|
||||
|
||||
$priority_functions = wp_list_pluck( $priority_actions, 'function' );
|
||||
|
||||
foreach ( $priority_functions as $key => $function ) {
|
||||
if ( is_array( $function ) ) {
|
||||
|
||||
if ( ! empty( $function[0] ) && is_object( $function[0] ) ) {
|
||||
$class_name = strtolower( get_class( $function[0] ) );
|
||||
|
||||
if ( false === strpos( $class_name, 'edd' ) ) {
|
||||
unset( $all_hooks[ $priority ][ $key ] );
|
||||
}
|
||||
}
|
||||
} elseif ( is_string( $function ) ) {
|
||||
|
||||
$function = strtolower( $function );
|
||||
if ( false === strpos( $function, 'edd' ) ) {
|
||||
|
||||
unset( $all_hooks[ $priority ][ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$wp_filter['admin_notices']->callbacks = $all_hooks;
|
||||
}
|
||||
|
||||
/** Private Methods *******************************************************/
|
||||
|
||||
/**
|
||||
@ -274,7 +318,7 @@ class EDD_Notices {
|
||||
'is_dismissible' => false,
|
||||
'message' => array(
|
||||
sprintf( __( 'The files in %s are not currently protected.', 'easy-digital-downloads' ), '<code>' . $upload_directory . '</code>' ),
|
||||
__( 'To protect them, you must add this <a href="https://docs.easydigitaldownloads.com/article/682-protected-download-files-on-nginx">NGINX redirect rule</a>.', 'easy-digital-downloads' ),
|
||||
__( 'To protect them, you must add this <a href="https://easydigitaldownloads.com/docs/download-files-not-protected-on-nginx/">NGINX redirect rule</a>.', 'easy-digital-downloads' ),
|
||||
sprintf( __( 'If you have already done this, or it does not apply to your site, you may permenently %s.', 'easy-digital-downloads' ), '<a href="' . esc_url( $dismiss_notice_url ) . '">' . __( 'dismiss this notice', 'easy-digital-downloads' ) . '</a>' )
|
||||
)
|
||||
) );
|
||||
@ -588,6 +632,16 @@ class EDD_Notices {
|
||||
)
|
||||
);
|
||||
break;
|
||||
|
||||
case 'missing-pass-key':
|
||||
$this->add_notice(
|
||||
array(
|
||||
'id' => 'edd-missing-pass-key',
|
||||
'message' => __( 'Your extensions could not be refreshed because you have not verified your license key.', 'easy-digital-downloads' ),
|
||||
'class' => 'error',
|
||||
)
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,6 +767,20 @@ class EDD_Notices {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'one-click-upgrade' === $notice && edd_is_pro() && current_user_can( 'install_plugins' ) && edd_is_admin_page( 'settings' ) ) {
|
||||
$this->add_notice(
|
||||
array(
|
||||
'id' => 'edd-upgraded',
|
||||
'message' => sprintf(
|
||||
/* Translators: 1. opening strong tag, do not translate; 2. closing strong tag, do not translate */
|
||||
__( 'Congratulations! You are now running %1$sEasy Digital Downloads (Pro)%2$s.', 'easy-digital-downloads' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,277 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Pass Manager
|
||||
*
|
||||
* Tool for determining what kind of pass, if any, is activated on the site.
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license GPL2+
|
||||
* @since 2.10.6
|
||||
*/
|
||||
|
||||
namespace EDD\Admin;
|
||||
|
||||
class Pass_Manager {
|
||||
|
||||
const PERSONAL_PASS_ID = 1245715;
|
||||
const EXTENDED_PASS_ID = 1245716;
|
||||
const PROFESSIONAL_PASS_ID = 1245717;
|
||||
const ALL_ACCESS_PASS_ID = 1150319;
|
||||
const ALL_ACCESS_PASS_LIFETIME_ID = 1464807;
|
||||
|
||||
/**
|
||||
* ID of the highest tier pass that's activated.
|
||||
*
|
||||
* @var int|null
|
||||
*/
|
||||
public $highest_pass_id = null;
|
||||
|
||||
/**
|
||||
* License key of the highest tier pass that's activated.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public $highest_license_key = null;
|
||||
|
||||
/**
|
||||
* Pass data from the database. This will be an array with
|
||||
* the key being the license key, and the value being another
|
||||
* array with the `pass_id` and `time_checked`.
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
public $pass_data;
|
||||
|
||||
/**
|
||||
* Whether or not we've stored any pass data yet.
|
||||
* If no pass data has been stored, then that means the user
|
||||
* might have a pass activated, we just haven't figured it out
|
||||
* yet and we're still waiting for the first cron to run.
|
||||
*
|
||||
* @see \EDD_License::weekly_license_check()
|
||||
* @see \EDD_License::activate_license()
|
||||
* @see \EDD_License::maybe_set_pass_flag()
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
public $has_pass_data = false;
|
||||
|
||||
/**
|
||||
* Number of license keys entered on this site.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $number_license_keys;
|
||||
|
||||
/**
|
||||
* Hierarchy of passes. This helps us determine if one pass
|
||||
* is "higher" than another.
|
||||
*
|
||||
* @see Pass_Manager::pass_compare()
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
private static $pass_hierarchy = array(
|
||||
self::PERSONAL_PASS_ID => 10,
|
||||
self::EXTENDED_PASS_ID => 20,
|
||||
self::PROFESSIONAL_PASS_ID => 30,
|
||||
self::ALL_ACCESS_PASS_ID => 40,
|
||||
self::ALL_ACCESS_PASS_LIFETIME_ID => 50
|
||||
);
|
||||
|
||||
/**
|
||||
* Pass_Manager constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$pass_data = get_option( 'edd_pass_licenses' );
|
||||
if ( false !== $pass_data ) {
|
||||
$this->pass_data = json_decode( $pass_data, true );
|
||||
$this->has_pass_data = true;
|
||||
}
|
||||
|
||||
// Set up the highest pass data.
|
||||
$this->set_highest_pass_data();
|
||||
|
||||
$this->number_license_keys = count( \EDD\Extensions\get_licensed_extension_slugs() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the highest pass and defines its data.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return void
|
||||
*/
|
||||
private function set_highest_pass_data() {
|
||||
|
||||
if ( ! $this->has_pass_data || ! is_array( $this->pass_data ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$highest_license_key = null;
|
||||
$highest_pass_id = null;
|
||||
|
||||
foreach ( $this->pass_data as $license_key => $pass_data ) {
|
||||
/*
|
||||
* If this pass was last verified more than 2 months ago, we're not using it.
|
||||
* This ensures we never deal with a "stale" record for a pass that's no longer
|
||||
* actually activated, but still exists in our DB array for some reason.
|
||||
*
|
||||
* Our cron job should always be updating with active data once per week.
|
||||
*/
|
||||
if ( empty( $pass_data['time_checked'] ) || strtotime( '-2 months' ) > $pass_data['time_checked'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We need a pass ID.
|
||||
if ( empty( $pass_data['pass_id'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we don't yet have a "highest pass", then this one is it automatically.
|
||||
if ( empty( $highest_pass_id ) ) {
|
||||
$highest_license_key = $license_key;
|
||||
$highest_pass_id = intval( $pass_data['pass_id'] );
|
||||
continue;
|
||||
}
|
||||
|
||||
// Otherwise, this pass only takes over the highest pass if it's actually higher.
|
||||
if ( self::pass_compare( (int) $pass_data['pass_id'], $highest_pass_id, '>' ) ) {
|
||||
$highest_license_key = $license_key;
|
||||
$highest_pass_id = intval( $pass_data['pass_id'] );
|
||||
}
|
||||
}
|
||||
|
||||
$this->highest_license_key = $highest_license_key;
|
||||
$this->highest_pass_id = $highest_pass_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not a pass is activated.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function has_pass() {
|
||||
return ! empty( $this->highest_pass_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is a "free install". That means there are no à la carte or pass licenses activated.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isFree() {
|
||||
return 0 === $this->number_license_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is a "pro install". This means they have the pro version of EDD installed.
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function isPro() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this site has an individual product license active (à la carte), but no pass active.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasIndividualLicense() {
|
||||
return ! $this->isFree() && ! $this->has_pass();
|
||||
}
|
||||
|
||||
/**
|
||||
* If this site has a Personal Pass active.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPersonalPass() {
|
||||
try {
|
||||
return self::pass_compare( $this->highest_pass_id, self::PERSONAL_PASS_ID, '=' );
|
||||
} catch ( \Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this site has an Extended Pass active.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasExtendedPass() {
|
||||
try {
|
||||
return self::pass_compare( $this->highest_pass_id, self::EXTENDED_PASS_ID, '=' );
|
||||
} catch ( \Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this site has a Professional Pass active.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasProfessionalPass() {
|
||||
try {
|
||||
return self::pass_compare( $this->highest_pass_id, self::PROFESSIONAL_PASS_ID, '=' );
|
||||
} catch( \Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If this site has an All Access Pass active.
|
||||
* Note: This uses >= to account for both All Access and lifetime All Access.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAllAccessPass() {
|
||||
try {
|
||||
return self::pass_compare( $this->highest_pass_id, self::ALL_ACCESS_PASS_ID, '>=' );
|
||||
} catch( \Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two passes with each other according to the supplied operator.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @param int $pass_1 ID of the first pass.
|
||||
* @param int $pass_2 ID of the second pass
|
||||
* @param string $comparison Comparison operator.
|
||||
*
|
||||
* @return bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function pass_compare( $pass_1, $pass_2, $comparison = '>' ) {
|
||||
if ( ! array_key_exists( $pass_1, self::$pass_hierarchy ) ) {
|
||||
throw new \InvalidArgumentException( 'Invalid pass 1: ' . $pass_1 );
|
||||
}
|
||||
if ( ! array_key_exists( $pass_2, self::$pass_hierarchy ) ) {
|
||||
throw new \InvalidArgumentException( 'Invalid pass 2: ' . $pass_2 );
|
||||
}
|
||||
|
||||
return version_compare( self::$pass_hierarchy[ $pass_1 ], self::$pass_hierarchy[ $pass_2 ], $comparison );
|
||||
}
|
||||
|
||||
}
|
@ -96,9 +96,9 @@ function edd_downloads_contextual_help() {
|
||||
);
|
||||
|
||||
$screen->add_help_tab( array(
|
||||
'id' => 'edd-purchase-shortcode',
|
||||
'title' => __( 'Purchase Shortcode', 'easy-digital-downloads' ),
|
||||
'content' =>
|
||||
'id' => 'edd-purchase-shortcode',
|
||||
'title' => __( 'Purchase Shortcode', 'easy-digital-downloads' ),
|
||||
'content' =>
|
||||
'<p>' . __( '<strong>Purchase Shortcode</strong> - If the automatic output of the purchase button has been disabled via the Download Configuration box, a shortcode can be used to output the button or link.', 'easy-digital-downloads' ) . '</p>' .
|
||||
'<p><code>[purchase_link id="#" price="1" text="Add to Cart" color="blue"]</code></p>' .
|
||||
'<ul>
|
||||
@ -109,7 +109,11 @@ function edd_downloads_contextual_help() {
|
||||
<li><strong>color</strong> - <em>' . implode( '</em> | <em>', $colors ) . '</em></li>
|
||||
<li><strong>class</strong> - ' . __( 'One or more custom CSS classes you want applied to the button.', 'easy-digital-downloads' ) . '</li>
|
||||
</ul>' .
|
||||
'<p>' . sprintf( __( 'For more information, see <a href="%s">using Shortcodes</a> on the WordPress.org Codex or <a href="%s">Easy Digital Downloads Documentation</a>', 'easy-digital-downloads' ), 'https://codex.wordpress.org/Shortcode', 'https://docs.easydigitaldownloads.com/article/229-purchaselink' ) . '</p>'
|
||||
'<p>' . sprintf(
|
||||
__( 'For more information, see <a href="%s">using Shortcodes</a> on the WordPress.org Codex or <a href="%s">Easy Digital Downloads Documentation</a>', 'easy-digital-downloads' ),
|
||||
'https://codex.wordpress.org/Shortcode',
|
||||
'https://easydigitaldownloads.com/docs/purchase_link-shortcode/'
|
||||
) . '</p>'
|
||||
) );
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ function edd_add_download_meta_box() {
|
||||
}
|
||||
}
|
||||
}
|
||||
add_action( 'add_meta_boxes', 'edd_add_download_meta_box' );
|
||||
add_action( 'add_meta_boxes', 'edd_add_download_meta_box', 9 );
|
||||
|
||||
/**
|
||||
* Returns default EDD Download meta fields.
|
||||
@ -111,6 +111,25 @@ function edd_download_meta_box_save( $post_id, $post ) {
|
||||
return;
|
||||
}
|
||||
|
||||
edd_download_meta_box_fields_save( $post_id, $post );
|
||||
}
|
||||
|
||||
add_action( 'save_post', 'edd_download_meta_box_save', 10, 2 );
|
||||
|
||||
|
||||
/**
|
||||
* Save post meta when the save_post action is called
|
||||
*
|
||||
* @since 3.2
|
||||
* @param int $post_id Download (Post) ID.
|
||||
* @global array $post All the data of the the current post.
|
||||
* @return void
|
||||
*/
|
||||
function edd_download_meta_box_fields_save( $post_id, $post ) {
|
||||
if ( ! current_user_can( 'edit_product', $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The default fields that get saved
|
||||
$fields = edd_download_metabox_fields();
|
||||
foreach ( $fields as $field ) {
|
||||
@ -148,7 +167,6 @@ function edd_download_meta_box_save( $post_id, $post ) {
|
||||
do_action( 'edd_save_download', $post_id, $post );
|
||||
}
|
||||
|
||||
add_action( 'save_post', 'edd_download_meta_box_save', 10, 2 );
|
||||
|
||||
/**
|
||||
* Sanitize bundled products on save
|
||||
@ -312,7 +330,7 @@ function edd_render_price_field( $post_id ) {
|
||||
<strong><?php echo apply_filters( 'edd_price_options_heading', __( 'Pricing Options:', 'easy-digital-downloads' ) ); ?></strong>
|
||||
</p>
|
||||
|
||||
<div class="edd-form-group">
|
||||
<div id="edd_variable_pricing_control" class="edd-form-group">
|
||||
<div class="edd-form-group__control">
|
||||
<input type="checkbox" class="edd-form-group__input" name="_variable_pricing" id="edd_variable_pricing" value="1" <?php checked( 1, $variable_pricing ); ?> />
|
||||
<label for="edd_variable_pricing">
|
||||
|
@ -1,346 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Extensions;
|
||||
|
||||
use \EDD\Admin\Pass_Manager;
|
||||
|
||||
abstract class Extension {
|
||||
|
||||
/**
|
||||
* The product ID. This only needs to be set if the extending class is
|
||||
* for a single product.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var int
|
||||
*/
|
||||
protected $item_id;
|
||||
|
||||
/**
|
||||
* The settings tab where this item will show.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_tab = '';
|
||||
|
||||
/**
|
||||
* The required AA pass level.
|
||||
*/
|
||||
const PASS_LEVEL = Pass_Manager::PERSONAL_PASS_ID;
|
||||
|
||||
/**
|
||||
* The Extension Manager
|
||||
*
|
||||
* @var \EDD\Admin\Extensions\Extension_Manager
|
||||
*/
|
||||
protected $manager;
|
||||
|
||||
/**
|
||||
* The settings section for this item.
|
||||
*
|
||||
* @since 2.11.5
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_section = 'general';
|
||||
|
||||
public function __construct() {
|
||||
$this->manager = new \EDD\Admin\Extensions\Extension_Manager( static::PASS_LEVEL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the extension is activated.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return bool
|
||||
*/
|
||||
abstract protected function is_activated();
|
||||
|
||||
/**
|
||||
* Output the settings field (installation helper).
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function settings_field() {
|
||||
if ( $this->is_activated() ) {
|
||||
return;
|
||||
}
|
||||
$this->do_single_extension_card();
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a single extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param false|int $item_id Optional: the individual extension product ID.
|
||||
* @return void
|
||||
*/
|
||||
public function do_single_extension_card( $item_id = false ) {
|
||||
if ( empty( $item_id ) && empty( $this->item_id ) ) {
|
||||
return;
|
||||
}
|
||||
$product_data = $this->get_product_data( $item_id );
|
||||
if ( ! $product_data || empty( $product_data->title ) ) {
|
||||
return;
|
||||
}
|
||||
$this->manager->do_extension_card(
|
||||
$product_data,
|
||||
$this->get_button_parameters( $product_data, $item_id ),
|
||||
$this->get_link_parameters( $product_data ),
|
||||
$this->get_configuration( $product_data )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product data for a specific extension.
|
||||
*
|
||||
* @param false|int $item_id
|
||||
* @return bool|ProductData|array False if there is no data; product data object if there is, or possibly an array of arrays.
|
||||
*/
|
||||
public function get_product_data( $item_id = false ) {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/class-extensions-api.php';
|
||||
$api = new ExtensionsAPI();
|
||||
$body = $this->get_api_body();
|
||||
$api_item_id = $item_id ?: $this->item_id;
|
||||
$product_data = $api->get_product_data( $body, $api_item_id );
|
||||
if ( ! $product_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $api_item_id ) {
|
||||
return $product_data;
|
||||
}
|
||||
|
||||
if ( $item_id && ! empty( $product_data[ $item_id ] ) ) {
|
||||
return $product_data[ $item_id ];
|
||||
}
|
||||
|
||||
return $product_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the custom configuration for the extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param ProductData $product_data Optionally allows the product data to be parsed in the configuration.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_configuration( ProductData $product_data ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a custom description array by running wpautop and converting it to a string.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $description The custom product description.
|
||||
* @return string
|
||||
*/
|
||||
protected function format_description( array $description ) {
|
||||
return implode( '', array_map( 'wpautop', $description ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current screen is an EDD setings screen.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_edd_settings_screen() {
|
||||
return edd_is_admin_page( 'settings', $this->settings_tab );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current screen is a download new/edit screen.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return bool
|
||||
*/
|
||||
protected function is_download_edit_screen() {
|
||||
return edd_is_admin_page( 'download', 'edit' ) || edd_is_admin_page( 'download', 'new' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the section for an individual product can be registered/shown.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return bool
|
||||
*/
|
||||
protected function can_show_product_section() {
|
||||
if ( ! $this->is_edd_settings_screen() ) {
|
||||
return false;
|
||||
}
|
||||
if ( $this->is_activated() ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! $this->get_product_data() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array for the body of the API request.
|
||||
* Classes may need to override this (for example, to query a specific tag).
|
||||
* Note that the first array key/value pair are used to create the option name.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function get_api_body() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type for the button data-type attribute.
|
||||
* This is intended to sync with the Products API request.
|
||||
* Default is product.
|
||||
*
|
||||
* Really a shim for array_key_first.
|
||||
*
|
||||
* @param array $array
|
||||
* @return string
|
||||
*/
|
||||
private function get_type( array $array ) {
|
||||
$type = 'product';
|
||||
if ( empty( $array ) ) {
|
||||
return $type;
|
||||
}
|
||||
if ( function_exists( 'array_key_first' ) ) {
|
||||
return array_key_first( $array );
|
||||
}
|
||||
foreach ( $array as $key => $unused ) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the button parameters.
|
||||
* Classes should not need to replace this method.
|
||||
*
|
||||
* @param ProductData $product_data The extension data returned from the Products API.
|
||||
* @param int|false $item_id Optional: the item ID.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_button_parameters( ProductData $product_data, $item_id = false ) {
|
||||
if ( empty( $item_id ) ) {
|
||||
$item_id = $this->item_id;
|
||||
}
|
||||
$body = $this->get_api_body();
|
||||
$type = $this->get_type( $body );
|
||||
$id = ! empty( $body[ $type ] ) ? $body[ $type ] : $this->item_id;
|
||||
$button = array(
|
||||
'type' => $type,
|
||||
'id' => $id,
|
||||
'product' => $item_id,
|
||||
);
|
||||
// If the extension is not installed, the button will prompt to install and activate it.
|
||||
if ( ! $this->manager->is_plugin_installed( $product_data->basename ) ) {
|
||||
if ( $this->manager->pass_can_download() ) {
|
||||
$button = array(
|
||||
/* translators: The extension name. */
|
||||
'button_text' => sprintf( __( 'Log In to Your Account to Download %s', 'easy-digital-downloads' ), $product_data->title ),
|
||||
'href' => $this->get_upgrade_url( $product_data, $item_id, true ),
|
||||
'new_tab' => true,
|
||||
'type' => $type,
|
||||
);
|
||||
} else {
|
||||
$button = array(
|
||||
/* translators: The extension name. */
|
||||
'button_text' => sprintf( __( 'Upgrade Today to Access %s!', 'easy-digital-downloads' ), $product_data->title ),
|
||||
'href' => $this->get_upgrade_url( $product_data, $item_id ),
|
||||
'new_tab' => true,
|
||||
'type' => $type,
|
||||
);
|
||||
}
|
||||
} elseif ( ! empty( $product_data->basename ) && ! $this->manager->is_plugin_active( $product_data->basename ) ) {
|
||||
// If the extension is installed, but not activated, the button will prompt to activate it.
|
||||
$button['plugin'] = $product_data->basename;
|
||||
$button['action'] = 'activate';
|
||||
/* translators: The extension name. */
|
||||
$button['button_text'] = sprintf( __( 'Activate %s', 'easy-digital-downloads' ), $product_data->title );
|
||||
}
|
||||
|
||||
return $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the upgrade URL for the button.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param ProductData $product_data The product data object.
|
||||
* @param int $item_id The item/product ID.
|
||||
* @param bool $has_access Whether the user already has access to the extension (based on pass level).
|
||||
* @return string
|
||||
*/
|
||||
private function get_upgrade_url( ProductData $product_data, $item_id, $has_access = false ) {
|
||||
if ( $has_access ) {
|
||||
$url = 'https://easydigitaldownloads.com/your-account/your-downloads/';
|
||||
} else {
|
||||
$url = 'https://easydigitaldownloads.com/lite-upgrade';
|
||||
}
|
||||
|
||||
$utm_parameters = array(
|
||||
'utm_medium' => $this->settings_section,
|
||||
'utm_content' => $product_data->slug,
|
||||
);
|
||||
|
||||
return edd_link_helper(
|
||||
$url,
|
||||
$utm_parameters
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of parameters for the link to configure the extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param ProductData $product_data The product data object.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_link_parameters( ProductData $product_data ) {
|
||||
$configuration = $this->get_configuration( $product_data );
|
||||
$tab = ! empty( $configuration['tab'] ) ? $configuration['tab'] : $product_data->tab;
|
||||
$section = ! empty( $configuration['section'] ) ? $configuration['section'] : $product_data->section;
|
||||
if ( empty( $tab ) && empty( $section ) ) {
|
||||
return array(
|
||||
/* translators: the plural Downloads label. */
|
||||
'button_text' => sprintf( __( 'View %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
'href' => add_query_arg(
|
||||
array(
|
||||
'post_type' => 'download',
|
||||
),
|
||||
admin_url( 'edit.php' )
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
/* translators: The extension name. */
|
||||
'button_text' => sprintf( __( 'Configure %s', 'easy-digital-downloads' ), $product_data->title ),
|
||||
'href' => edd_get_admin_url(
|
||||
array(
|
||||
'page' => 'edd-settings',
|
||||
'tab' => urlencode( $tab ),
|
||||
'section' => urlencode( $section ),
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optionally hides the submit button on screens where it's not needed.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return void
|
||||
*/
|
||||
public function hide_submit_button() {
|
||||
if ( ! $this->can_show_product_section() ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<style>p.submit{display:none;}</style>
|
||||
<?php
|
||||
}
|
||||
}
|
@ -1,483 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Extensions;
|
||||
|
||||
use \EDD\Admin\Pass_Manager;
|
||||
|
||||
class Extension_Manager {
|
||||
|
||||
/**
|
||||
* All of the installed plugins on the site.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var array
|
||||
*/
|
||||
public $all_plugins;
|
||||
|
||||
/**
|
||||
* The minimum pass ID required to install the extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var int
|
||||
*/
|
||||
private $required_pass_id;
|
||||
|
||||
/**
|
||||
* Pass Manager class
|
||||
*
|
||||
* @var Pass_Manager
|
||||
*/
|
||||
protected $pass_manager;
|
||||
|
||||
public function __construct( $required_pass_id = null ) {
|
||||
if ( $required_pass_id ) {
|
||||
$this->required_pass_id = $required_pass_id;
|
||||
}
|
||||
$this->pass_manager = new Pass_Manager();
|
||||
|
||||
add_action( 'wp_ajax_edd_activate_extension', array( $this, 'activate' ) );
|
||||
add_action( 'wp_ajax_edd_install_extension', array( $this, 'install' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'register_assets' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the extension manager script and style.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return void
|
||||
*/
|
||||
public function register_assets() {
|
||||
if ( wp_script_is( 'edd-extension-manager', 'registered' ) ) {
|
||||
return;
|
||||
}
|
||||
$minify = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
wp_register_style( 'edd-extension-manager', EDD_PLUGIN_URL . "assets/css/edd-admin-extension-manager.min.css", array(), EDD_VERSION );
|
||||
wp_register_script( 'edd-extension-manager', EDD_PLUGIN_URL . "assets/js/edd-admin-extension-manager.js", array( 'jquery' ), EDD_VERSION, true );
|
||||
wp_localize_script(
|
||||
'edd-extension-manager',
|
||||
'EDDExtensionManager',
|
||||
array(
|
||||
'activating' => __( 'Activating', 'easy-digital-downloads' ),
|
||||
'installing' => __( 'Installing', 'easy-digital-downloads' ),
|
||||
'plugin_install_failed' => __( 'Could not install the plugin. Please download and install it manually via Plugins > Add New.', 'easy-digital-downloads' ),
|
||||
'extension_install_failed' => sprintf(
|
||||
/* translators: 1. opening anchor tag, do not translate; 2. closing anchor tag, do not translate */
|
||||
__( 'Could not install the extension. Please %1$sdownload it from your account%2$s and install it manually.', 'easy-digital-downloads' ),
|
||||
'<a href="https://easydigitaldownloads.com/your-account/" target="_blank" rel="noopener noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'extension_manager_nonce' => wp_create_nonce( 'edd_extensionmanager' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues the extension manager script/style.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue() {
|
||||
wp_enqueue_style( 'edd-extension-manager' );
|
||||
wp_enqueue_script( 'edd-extension-manager' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a standard extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param ProductData $product The product data object.
|
||||
* @param array $inactive_parameters The array of information to build the button for an inactive/not installed plugin.
|
||||
* @param array $active_parameters The array of information needed to build the link to configure an active plugin.
|
||||
* @param array $configuration The optional array of data to override the product data retrieved from the API.
|
||||
* @return void
|
||||
*/
|
||||
public function do_extension_card( ProductData $product, $inactive_parameters, $active_parameters, $configuration = array() ) {
|
||||
$this->enqueue();
|
||||
if ( ! empty( $configuration ) ) {
|
||||
$product = $product->mergeConfig( $configuration );
|
||||
}
|
||||
?>
|
||||
<div class="<?php echo esc_attr( implode( ' ', array_map( 'sanitize_html_class', $this->get_card_classes( $product ) ) ) ); ?>">
|
||||
<h3 class="edd-extension-manager__title"><?php echo esc_html( $product->title ); ?></h3>
|
||||
<div class="edd-extension-manager__body">
|
||||
<?php if ( ! empty( $product->image ) ) : ?>
|
||||
<div class="edd-extension-manager__image">
|
||||
<img alt="" src="<?php echo esc_url( $product->image ); ?>" />
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $product->description ) ) : ?>
|
||||
<div class="edd-extension-manager__description"><?php echo wp_kses_post( wpautop( $product->description ) ); ?></div>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $product->features ) && is_array( $product->features ) ) : ?>
|
||||
<div class="edd-extension-manager__features">
|
||||
<ul>
|
||||
<?php foreach ( $product->features as $feature ) : ?>
|
||||
<li><span class="dashicons dashicons-yes"></span><?php echo esc_html( $feature ); ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="edd-extension-manager__group">
|
||||
<?php
|
||||
if ( ! empty( $product->basename ) && ! $this->is_plugin_active( $product->basename ) ) {
|
||||
?>
|
||||
<div class="edd-extension-manager__step">
|
||||
<?php $this->button( $inactive_parameters ); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<div class="edd-extension-manager__step">
|
||||
<?php $this->link( $active_parameters ); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the CSS classes for the single extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param ProductData $product The product data object.
|
||||
* @return array The array of CSS classes.
|
||||
*/
|
||||
private function get_card_classes( $product ) {
|
||||
$base_class = 'edd-extension-manager__card';
|
||||
$card_classes = array(
|
||||
$base_class,
|
||||
);
|
||||
$variation = 'stacked';
|
||||
if ( ! empty( $product->style ) ) {
|
||||
$variation = $product->style;
|
||||
}
|
||||
if ( 'detailed-2col' === $variation && ( empty( $product->features ) || ! is_array( $product->features ) ) ) {
|
||||
$variation = 'detailed';
|
||||
}
|
||||
$card_classes[] = "{$base_class}--{$variation}";
|
||||
|
||||
return $card_classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the button to activate/install a plugin/extension.
|
||||
* If a link is passed in the args, create a button style link instead (@uses $this->link()).
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $args The array of parameters for the button.
|
||||
* @return void
|
||||
*/
|
||||
public function button( $args ) {
|
||||
if ( ! empty( $args['href'] ) ) {
|
||||
$this->link( $args );
|
||||
return;
|
||||
}
|
||||
$defaults = array(
|
||||
'button_class' => 'button-primary',
|
||||
'plugin' => '',
|
||||
'action' => '',
|
||||
'button_text' => '',
|
||||
'type' => 'plugin',
|
||||
'id' => '',
|
||||
'product' => '',
|
||||
'pass' => $this->required_pass_id,
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
if ( empty( $args['button_text'] ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<button
|
||||
class="button <?php echo esc_attr( $args['button_class'] ); ?> edd-extension-manager__action"
|
||||
<?php
|
||||
foreach ( $args as $key => $attribute ) {
|
||||
if ( empty( $attribute ) || in_array( $key, array( 'button_class', 'button_text' ), true ) ) {
|
||||
continue;
|
||||
}
|
||||
printf(
|
||||
' data-%s="%s"',
|
||||
esc_attr( $key ),
|
||||
esc_attr( $attribute )
|
||||
);
|
||||
}
|
||||
?>
|
||||
>
|
||||
<?php echo esc_html( $args['button_text'] ); ?>
|
||||
</button>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs the link, if it should be a link.
|
||||
*
|
||||
* @param array $args
|
||||
* @return void
|
||||
*/
|
||||
public function link( $args ) {
|
||||
$defaults = array(
|
||||
'button_class' => 'button-primary',
|
||||
'button_text' => '',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
if ( empty( $args['button_text'] ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<a
|
||||
class="button <?php echo esc_attr( $args['button_class'] ); ?>"
|
||||
href="<?php echo esc_url( $args['href'] ); ?>"
|
||||
<?php echo ! empty( $args['new_tab'] ) ? ' target="_blank" rel="noopener noreferrer"' : ''; ?>
|
||||
>
|
||||
<?php echo esc_html( $args['button_text'] ); ?>
|
||||
</a>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs and maybe activates a plugin or extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
public function install() {
|
||||
|
||||
// Run a security check.
|
||||
check_ajax_referer( 'edd_extensionmanager', 'nonce', true );
|
||||
|
||||
$generic_error = esc_html__( 'There was an error while performing your request.', 'easy-digital-downloads' );
|
||||
$type = ! empty( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : '';
|
||||
$required_pass = ! empty( $_POST['pass'] ) ? sanitize_text_field( $_POST['pass'] ) : '';
|
||||
$result = array(
|
||||
'message' => $generic_error,
|
||||
'is_activated' => false,
|
||||
);
|
||||
if ( ! $type ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
// Check if new installations are allowed.
|
||||
if ( ! $this->can_install( $type, $required_pass ) ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
$result['message'] = 'plugin' === $type
|
||||
? __( 'Could not install the plugin. Please download and install it manually via Plugins > Add New.', 'easy-digital-downloads' )
|
||||
: sprintf(
|
||||
/* translators: 1. opening anchor tag, do not translate; 2. closing anchor tag, do not translate */
|
||||
__( 'Could not install the extension. Please %1$sdownload it from your account%2$s and install it manually.', 'easy-digital-downloads' ),
|
||||
'<a href="https://easydigitaldownloads.com/your-account/" target="_blank" rel="noopener noreferrer">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$plugin = ! empty( $_POST['plugin'] ) ? sanitize_text_field( $_POST['plugin'] ) : '';
|
||||
if ( empty( $plugin ) ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
// Set the current screen to avoid undefined notices.
|
||||
set_current_screen( 'download_page_edd-settings' );
|
||||
|
||||
// Prepare variables.
|
||||
$url = esc_url_raw(
|
||||
edd_get_admin_url(
|
||||
array(
|
||||
'page' => 'edd-addons',
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
ob_start();
|
||||
$creds = request_filesystem_credentials( $url, '', false, false, null );
|
||||
|
||||
// Hide the filesystem credentials form.
|
||||
ob_end_clean();
|
||||
|
||||
// Check for file system permissions.
|
||||
if ( ! $creds ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
if ( ! WP_Filesystem( $creds ) ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
/*
|
||||
* We do not need any extra credentials if we have gotten this far, so let's install the plugin.
|
||||
*/
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/installers/class-plugin-silent-upgrader.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/installers/class-plugin-silent-upgrader-skin.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/installers/class-install-skin.php';
|
||||
|
||||
// Do not allow WordPress to search/download translations, as this will break JS output.
|
||||
remove_action( 'upgrader_process_complete', array( 'Language_Pack_Upgrader', 'async_upgrade' ), 20 );
|
||||
|
||||
// Create the plugin upgrader with our custom skin.
|
||||
$installer = new \EDD\Admin\Installers\PluginSilentUpgrader( new \EDD\Admin\Installers\Install_Skin() );
|
||||
|
||||
// Error check.
|
||||
if ( ! method_exists( $installer, 'install' ) || empty( $plugin ) ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
$installer->install( $plugin ); // phpcs:ignore
|
||||
|
||||
// Flush the cache and return the newly installed plugin basename.
|
||||
wp_cache_flush();
|
||||
|
||||
$plugin_basename = $installer->plugin_info();
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! current_user_can( 'activate_plugins' ) ) {
|
||||
$result['message'] = 'plugin' === $type ? esc_html__( 'Plugin installed.', 'easy-digital-downloads' ) : esc_html__( 'Extension installed.', 'easy-digital-downloads' );
|
||||
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
$this->activate( $plugin_basename );
|
||||
}
|
||||
|
||||
/**
|
||||
* Activates an existing extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param string $plugin_basename Optional: the plugin basename.
|
||||
*/
|
||||
public function activate( $plugin_basename = '' ) {
|
||||
|
||||
$result = array(
|
||||
'message' => __( 'There was an error while performing your request.', 'easy-digital-downloads' ),
|
||||
'is_activated' => false,
|
||||
);
|
||||
|
||||
// Check for permissions.
|
||||
if ( ! check_ajax_referer( 'edd_extensionmanager', 'nonce', false ) || ! current_user_can( 'activate_plugins' ) ) {
|
||||
$result['message'] = __( 'Plugin activation is not available for you on this site.', 'easy-digital-downloads' );
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
$already_installed = false;
|
||||
if ( empty( $plugin_basename ) ) {
|
||||
$plugin_basename = ! empty( $_POST['plugin'] ) ? sanitize_text_field( $_POST['plugin'] ) : '';
|
||||
$already_installed = true;
|
||||
}
|
||||
|
||||
$plugin_basename = sanitize_text_field( wp_unslash( $plugin_basename ) );
|
||||
$type = ! empty( $_POST['type'] ) ? sanitize_text_field( $_POST['type'] ) : '';
|
||||
if ( 'plugin' !== $type ) {
|
||||
$type = 'extension';
|
||||
}
|
||||
$result = array(
|
||||
/* translators: "extension" or "plugin" as defined by $type */
|
||||
'message' => sprintf( __( 'Could not activate the %s.', 'easy-digital-downloads' ), esc_html( $type ) ),
|
||||
'is_activated' => false,
|
||||
);
|
||||
if ( empty( $plugin_basename ) || empty( $type ) ) {
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
$result['basename'] = $plugin_basename;
|
||||
|
||||
// Activate the plugin silently.
|
||||
$activated = activate_plugin( $plugin_basename );
|
||||
|
||||
if ( ! is_wp_error( $activated ) ) {
|
||||
|
||||
if ( $already_installed ) {
|
||||
$message = 'plugin' === $type ? esc_html__( 'Plugin activated.', 'easy-digital-downloads' ) : esc_html__( 'Extension activated.', 'easy-digital-downloads' );
|
||||
} else {
|
||||
$message = 'plugin' === $type ? esc_html__( 'Plugin installed & activated.', 'easy-digital-downloads' ) : esc_html__( 'Extension installed & activated.', 'easy-digital-downloads' );
|
||||
}
|
||||
$result['is_activated'] = true;
|
||||
$result['message'] = $message;
|
||||
|
||||
wp_send_json_success( $result );
|
||||
}
|
||||
|
||||
// Fallback error just in case.
|
||||
wp_send_json_error( $result );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the plugin/extension installations are allowed.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param string $type Should be `plugin` or `extension`.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function can_install( $type, $required_pass_id = false ) {
|
||||
|
||||
if ( ! current_user_can( 'install_plugins' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Determine whether file modifications are allowed.
|
||||
if ( ! wp_is_file_mod_allowed( 'edd_can_install' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All plugin checks are done.
|
||||
if ( 'plugin' === $type ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->pass_can_download( $required_pass_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a user's pass can download an extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return bool Returns true if the current site has an active pass and it is greater than or equal to the extension's minimum pass.
|
||||
*/
|
||||
public function pass_can_download( $required_pass_id = false ) {
|
||||
$highest_pass_id = $this->pass_manager->highest_pass_id;
|
||||
if ( ! $required_pass_id ) {
|
||||
$required_pass_id = $this->required_pass_id;
|
||||
}
|
||||
|
||||
return ! empty( $highest_pass_id ) && ! empty( $required_pass_id ) && $this->pass_manager->pass_compare( $highest_pass_id, $required_pass_id, '>=' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all installed plugins.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return array
|
||||
*/
|
||||
public function get_plugins() {
|
||||
if ( $this->all_plugins ) {
|
||||
return $this->all_plugins;
|
||||
}
|
||||
|
||||
$this->all_plugins = get_plugins();
|
||||
|
||||
return $this->all_plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a plugin is installed.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param string $plugin The path to the main plugin file, eg 'my-plugin/my-plugin.php'.
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_plugin_installed( $plugin ) {
|
||||
return array_key_exists( $plugin, $this->get_plugins() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether a given plugin is active or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param string|ProductData $basename_or_data The path to the main plugin file, eg 'my-plugin/my-plugin.php', or the product data object.
|
||||
* @return boolean
|
||||
*/
|
||||
public function is_plugin_active( $basename_or_data ) {
|
||||
$basename = ! empty( $basename_or_data->basename ) ? $basename_or_data->basename : $basename_or_data;
|
||||
|
||||
return ! empty( $basename ) && is_plugin_active( $basename );
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Extensions;
|
||||
|
||||
class ProductData {
|
||||
|
||||
/**
|
||||
* The product name.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* The product slug.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $slug = '';
|
||||
|
||||
/**
|
||||
* The URL for the product featured image.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $image;
|
||||
|
||||
/**
|
||||
* The product description.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* The extension basename.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $basename;
|
||||
|
||||
/**
|
||||
* The settings tab where the extension settings will show.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $tab;
|
||||
|
||||
/**
|
||||
* The settings section for the extension.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
public $section;
|
||||
|
||||
/**
|
||||
* The product features.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var array
|
||||
*/
|
||||
public $features = array();
|
||||
|
||||
/**
|
||||
* Take array and return object.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $array
|
||||
* @return ProductData
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function fromArray( $array ) {
|
||||
$expected_keys = array( 'title', 'slug', 'description', 'basename' );
|
||||
$array_to_check = array_intersect_key( $array, array_flip( $expected_keys ) );
|
||||
|
||||
if ( empty( $array_to_check ) ) {
|
||||
throw new \InvalidArgumentException(
|
||||
'Invalid ProductData object, must have the exact following keys: ' . implode( ', ', $expected_keys )
|
||||
);
|
||||
}
|
||||
|
||||
$product_data = new self();
|
||||
foreach ( $array as $key => $value ) {
|
||||
$product_data->$key = $value;
|
||||
}
|
||||
|
||||
return $product_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge an array of data into an object.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $configuration The custom configuration data.
|
||||
* @return ProductData
|
||||
*/
|
||||
public function mergeConfig( array $configuration ) {
|
||||
foreach ( $configuration as $key => $value ) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
@ -1,222 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Extensions;
|
||||
|
||||
class ExtensionsAPI {
|
||||
|
||||
/**
|
||||
* Gets the product data from the EDD Products API.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $body The body for the API request.
|
||||
* @param int $item_id The product ID, if querying a single product.
|
||||
* @return false|array|ProductData
|
||||
*/
|
||||
public function get_product_data( $body = array(), $item_id = false ) {
|
||||
if ( empty( $body ) ) {
|
||||
if ( empty( $item_id ) ) {
|
||||
return false;
|
||||
}
|
||||
$body = $this->get_api_body( $item_id );
|
||||
}
|
||||
$key = $this->array_key_first( $body );
|
||||
// The option name is created from the first key/value pair of the API "body".
|
||||
$option_name = sanitize_key( "edd_extension_{$key}_{$body[ $key ]}_data" );
|
||||
$option = get_option( $option_name );
|
||||
$is_stale = $this->option_has_expired( $option );
|
||||
|
||||
// The ProductData class.
|
||||
$product_data = new ProductData();
|
||||
|
||||
// If the data is "fresh" and what we want exists, return it.
|
||||
if ( $option && ! $is_stale ) {
|
||||
if ( $item_id && ! empty( $option[ $item_id ] ) ) {
|
||||
return $product_data->fromArray( $option[ $item_id ] );
|
||||
} elseif ( ! empty( $option['timeout'] ) ) {
|
||||
unset( $option['timeout'] );
|
||||
|
||||
return $option;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all of the product data.
|
||||
$all_product_data = $this->get_all_product_data();
|
||||
|
||||
// If no product data was retrieved, let the option sit for an hour.
|
||||
if ( empty( $all_product_data ) ) {
|
||||
$data = array(
|
||||
'timeout' => strtotime( '+1 hour', time() ),
|
||||
);
|
||||
if ( $option && $is_stale ) {
|
||||
$data = array_merge( $option, $data );
|
||||
}
|
||||
update_option(
|
||||
$option_name,
|
||||
$data,
|
||||
false
|
||||
);
|
||||
|
||||
if ( $item_id && ! empty( $option[ $item_id ] ) ) {
|
||||
return $product_data->fromArray( $option[ $item_id ] );
|
||||
}
|
||||
unset( $option['timeout'] );
|
||||
|
||||
return $option;
|
||||
}
|
||||
|
||||
$value = array(
|
||||
'timeout' => strtotime( '+1 week', time() ),
|
||||
);
|
||||
if ( $item_id && ! empty( $all_product_data->$item_id ) ) {
|
||||
$item = $all_product_data->$item_id;
|
||||
$value[ $item_id ] = $this->get_item_data( $item );
|
||||
} elseif ( in_array( $key, array( 'category', 'tag' ), true ) ) {
|
||||
$term_id = $body[ $key ];
|
||||
foreach ( $all_product_data as $item_id => $item ) {
|
||||
if ( 'category' === $key && ( empty( $item->categories ) || ! in_array( $term_id, $item->categories, true ) ) ) {
|
||||
continue;
|
||||
} elseif ( 'tag' === $key && ( empty( $item->tags ) || ! in_array( $term_id, $item->tags, true ) ) ) {
|
||||
continue;
|
||||
}
|
||||
$value[ $item_id ] = $this->get_item_data( $item );
|
||||
}
|
||||
}
|
||||
|
||||
update_option( $option_name, $value, false );
|
||||
unset( $value['timeout'] );
|
||||
|
||||
return $item_id && ! empty( $value[ $item_id ] ) ? $product_data->fromArray( $value[ $item_id ] ) : $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the product data, either from an option or an API request.
|
||||
* If the option exists and has data, it will be an object.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return object|false
|
||||
*/
|
||||
private function get_all_product_data() {
|
||||
// Possibly all product data is in an option. If it is, return it.
|
||||
$all_product_data = get_option( 'edd_all_extension_data' );
|
||||
if ( $all_product_data && ! $this->option_has_expired( $all_product_data ) ) {
|
||||
return ! empty( $all_product_data['products'] ) ? $all_product_data['products'] : false;
|
||||
}
|
||||
|
||||
// Otherwise, query the API.
|
||||
$url = add_query_arg(
|
||||
array(
|
||||
'edd_action' => 'extension_data',
|
||||
),
|
||||
$this->get_products_url()
|
||||
);
|
||||
$request = wp_remote_get(
|
||||
esc_url_raw( $url ),
|
||||
array(
|
||||
'timeout' => 15,
|
||||
'sslverify' => true,
|
||||
)
|
||||
);
|
||||
|
||||
// If there was an API error, set option and return false.
|
||||
if ( is_wp_error( $request ) || ( 200 !== wp_remote_retrieve_response_code( $request ) ) ) {
|
||||
update_option(
|
||||
'edd_all_extension_data',
|
||||
array(
|
||||
'timeout' => strtotime( '+1 hour', time() ),
|
||||
),
|
||||
false
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Fresh data has been retrieved, so update the option with a four hour timeout.
|
||||
$all_product_data = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
$data = array(
|
||||
'timeout' => strtotime( '+4 hours', time() ),
|
||||
'products' => $all_product_data,
|
||||
);
|
||||
|
||||
update_option( 'edd_all_extension_data', $data, false );
|
||||
|
||||
return $all_product_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the product data as needed for the extension manager.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param object $item
|
||||
* @return array
|
||||
*/
|
||||
private function get_item_data( $item ) {
|
||||
return array(
|
||||
'title' => ! empty( $item->title ) ? $item->title : '',
|
||||
'slug' => ! empty( $item->slug ) ? $item->slug : '',
|
||||
'image' => ! empty( $item->image ) ? $item->image : '',
|
||||
'description' => ! empty( $item->excerpt ) ? $item->excerpt : '',
|
||||
'basename' => ! empty( $item->custom_meta->basename ) ? $item->custom_meta->basename : '',
|
||||
'tab' => ! empty( $item->custom_meta->settings_tab ) ? $item->custom_meta->settings_tab : '',
|
||||
'section' => ! empty( $item->custom_meta->settings_section ) ? $item->custom_meta->settings_section : '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the base url for the products remote request.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return string
|
||||
*/
|
||||
private function get_products_url() {
|
||||
if ( defined( 'EDD_PRODUCTS_URL' ) ) {
|
||||
return EDD_PRODUCTS_URL;
|
||||
}
|
||||
|
||||
return 'https://easydigitaldownloads.com/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default array for the body of the API request.
|
||||
* A class may override this by setting an array to query a tag or category.
|
||||
* Note that the first array key/value pair are used to create the option name.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param int $item_id The product ID.
|
||||
* @return array
|
||||
*/
|
||||
private function get_api_body( $item_id ) {
|
||||
return array(
|
||||
'product' => $item_id,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first key of an array.
|
||||
* (Shims array_key_first for PHP < 7.3)
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $array
|
||||
* @return string|null
|
||||
*/
|
||||
private function array_key_first( array $array ) {
|
||||
if ( function_exists( 'array_key_first' ) ) {
|
||||
return array_key_first( $array );
|
||||
}
|
||||
foreach ( $array as $key => $unused ) {
|
||||
return $key;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given option has "expired".
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array|false $option
|
||||
* @return bool
|
||||
*/
|
||||
private function option_has_expired( $option ) {
|
||||
return empty( $option['timeout'] ) || time() > $option['timeout'];
|
||||
}
|
||||
}
|
@ -1,132 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Email Marketing
|
||||
*
|
||||
* Manages automatic installation/activation for email marketing extensions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage EmailMarketing
|
||||
* @copyright Copyright (c) 2021, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 2.11.4
|
||||
*/
|
||||
namespace EDD\Admin\Settings;
|
||||
|
||||
use \EDD\Admin\Extensions\Extension;
|
||||
|
||||
class EmailMarketing extends Extension {
|
||||
|
||||
/**
|
||||
* The EDD settings tab where this extension should show.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_tab = 'marketing';
|
||||
|
||||
/**
|
||||
* The settings section for this item.
|
||||
*
|
||||
* @since 2.11.5
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_section = 'email_marketing';
|
||||
|
||||
public function __construct() {
|
||||
add_filter( 'edd_settings_sections_marketing', array( $this, 'add_section' ) );
|
||||
add_action( 'edd_settings_tab_top_marketing_email_marketing', array( $this, 'field' ) );
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an email marketing section to the Marketing tab.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param array $sections
|
||||
* @return array
|
||||
*/
|
||||
public function add_section( $sections ) {
|
||||
if ( ! $this->is_edd_settings_screen() ) {
|
||||
return $sections;
|
||||
}
|
||||
$product_data = $this->get_product_data();
|
||||
if ( ! $product_data || ! is_array( $product_data ) ) {
|
||||
return $sections;
|
||||
}
|
||||
$sections[ $this->settings_section ] = __( 'Email Marketing', 'easy-digital-downloads' );
|
||||
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the customized configuration for the extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
|
||||
$configuration = array();
|
||||
if ( ! empty( $product_data->title ) ) {
|
||||
/* translators: the product name */
|
||||
$configuration['title'] = sprintf( __( 'Get %s Today!', 'easy-digital-downloads' ), $product_data->title );
|
||||
}
|
||||
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the email marketing extensions as cards.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return void
|
||||
*/
|
||||
public function field() {
|
||||
$this->hide_submit_button();
|
||||
if ( $this->is_activated() ) {
|
||||
printf( '<p>%s</p>', esc_html__( 'Looks like you have an email marketing extension installed, but we support more providers!', 'easy-digital-downloads' ) );
|
||||
}
|
||||
?>
|
||||
<div class="edd-extension-manager__card-group">
|
||||
<?php
|
||||
foreach ( $this->get_product_data() as $item_id => $extension ) {
|
||||
$this->do_single_extension_card( $item_id );
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the body array sent to the Products API.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return array
|
||||
*/
|
||||
protected function get_api_body() {
|
||||
return array(
|
||||
'tag' => 1578,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether any email marketing extension is active.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool True if any email marketing extension is active.
|
||||
*/
|
||||
protected function is_activated() {
|
||||
foreach ( $this->get_product_data() as $extension ) {
|
||||
// The data is stored in the database as an array--at this point it has not been converted to an object.
|
||||
if ( ! empty( $extension['basename'] ) && $this->manager->is_plugin_active( $extension['basename'] ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
new EmailMarketing();
|
@ -1,124 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoices
|
||||
*
|
||||
* Manages automatic installation/activation for Invoices.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Invoices
|
||||
* @copyright Copyright (c) 2021, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 2.11.4
|
||||
*/
|
||||
namespace EDD\Admin\Settings;
|
||||
|
||||
use \EDD\Admin\Extensions\Extension;
|
||||
|
||||
class Invoices extends Extension {
|
||||
|
||||
/**
|
||||
* The product ID on EDD.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $item_id = 375153;
|
||||
|
||||
/**
|
||||
* The EDD settings tab where this extension should show.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_tab = 'gateways';
|
||||
|
||||
/**
|
||||
* The settings section for this item.
|
||||
*
|
||||
* @since 2.11.5
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_section = 'invoices';
|
||||
|
||||
/**
|
||||
* The pass level required to access this extension.
|
||||
*/
|
||||
const PASS_LEVEL = \EDD\Admin\Pass_Manager::EXTENDED_PASS_ID;
|
||||
|
||||
public function __construct() {
|
||||
add_filter( 'edd_settings_sections_gateways', array( $this, 'add_section' ) );
|
||||
add_action( 'edd_settings_tab_top_gateways_invoices', array( $this, 'settings_field' ) );
|
||||
add_action( 'edd_settings_tab_top_gateways_invoices', array( $this, 'hide_submit_button' ) );
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the custom configuration for Invoices.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
|
||||
return array(
|
||||
'style' => 'detailed-2col',
|
||||
'title' => 'Attractive Invoices For Your Customers',
|
||||
'description' => $this->get_custom_description(),
|
||||
'features' => array(
|
||||
'Generate Attractive Invoices',
|
||||
'Build Customer Confidence',
|
||||
'PDF Download Support',
|
||||
'Include in Purchase Emails',
|
||||
'Customizable Templates',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a custom description for the Invoices extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return string
|
||||
*/
|
||||
private function get_custom_description() {
|
||||
$description = array(
|
||||
'Impress customers and build customer loyalty with attractive invoices. Making it easy to locate, save, and print purchase history builds trust with customers.',
|
||||
'Provide a professional experience with customizable templates and one-click PDF downloads. ',
|
||||
);
|
||||
|
||||
return $this->format_description( $description );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Invoices Payments section to the settings.
|
||||
*
|
||||
* @param array $sections
|
||||
* @return array
|
||||
*/
|
||||
public function add_section( $sections ) {
|
||||
if ( ! $this->can_show_product_section() ) {
|
||||
return $sections;
|
||||
}
|
||||
|
||||
$sections[ $this->settings_section ] = __( 'Invoices', 'easy-digital-downloads' );
|
||||
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether EDD Invoices active or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool True if Invoices is active.
|
||||
*/
|
||||
protected function is_activated() {
|
||||
if ( $this->manager->is_plugin_active( $this->get_product_data() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return class_exists( 'EDDInvoices' );
|
||||
}
|
||||
}
|
||||
|
||||
new Invoices();
|
@ -1,124 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Recurring Payments
|
||||
*
|
||||
* Manages automatic activation for Recurring Payments.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Recurring
|
||||
* @copyright Copyright (c) 2021, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 2.11.4
|
||||
*/
|
||||
namespace EDD\Admin\Settings;
|
||||
|
||||
use \EDD\Admin\Extensions\Extension;
|
||||
|
||||
class Recurring extends Extension {
|
||||
|
||||
/**
|
||||
* The product ID on EDD.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $item_id = 28530;
|
||||
|
||||
/**
|
||||
* The EDD settings tab where this extension should show.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_tab = 'gateways';
|
||||
|
||||
/**
|
||||
* The pass level required to access this extension.
|
||||
*/
|
||||
const PASS_LEVEL = \EDD\Admin\Pass_Manager::EXTENDED_PASS_ID;
|
||||
|
||||
/**
|
||||
* The settings section for this item.
|
||||
*
|
||||
* @since 2.11.5
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_section = 'recurring';
|
||||
|
||||
public function __construct() {
|
||||
add_filter( 'edd_settings_sections_gateways', array( $this, 'add_section' ) );
|
||||
add_action( 'edd_settings_tab_top_gateways_recurring', array( $this, 'settings_field' ) );
|
||||
add_action( 'edd_settings_tab_top_gateways_recurring', array( $this, 'hide_submit_button' ) );
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the custom configuration for Recurring.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
|
||||
return array(
|
||||
'style' => 'detailed-2col',
|
||||
'title' => 'Increase Revenue By Selling Subscriptions!',
|
||||
'description' => $this->get_custom_description(),
|
||||
'features' => array(
|
||||
'Flexible Recurring Payments',
|
||||
'Custom Reminder Emails',
|
||||
'Free Trial Support',
|
||||
'Signup Fees',
|
||||
'Recurring Revenue Reports',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a custom description for the Recurring extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return string
|
||||
*/
|
||||
private function get_custom_description() {
|
||||
$description = array(
|
||||
'Grow stable income by selling subscriptions and make renewals hassle free for your customers.',
|
||||
'When your customers are automatically billed, you reduce the risk of missed payments and retain more customers.',
|
||||
);
|
||||
|
||||
return $this->format_description( $description );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Recurring Payments section to the settings.
|
||||
*
|
||||
* @param array $sections
|
||||
* @return array
|
||||
*/
|
||||
public function add_section( $sections ) {
|
||||
if ( ! $this->can_show_product_section() ) {
|
||||
return $sections;
|
||||
}
|
||||
|
||||
$sections[ $this->settings_section ] = __( 'Recurring Payments', 'easy-digital-downloads' );
|
||||
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether EDD Recurring active or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool True if Recurring is active.
|
||||
*/
|
||||
protected function is_activated() {
|
||||
if ( $this->manager->is_plugin_active( $this->get_product_data() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return class_exists( 'EDD_Recurring' );
|
||||
}
|
||||
}
|
||||
|
||||
new Recurring();
|
@ -1,152 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Reviews
|
||||
*
|
||||
* Manages automatic activation for Reviews.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Reviews
|
||||
* @copyright Copyright (c) 2021, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 2.11.4
|
||||
*/
|
||||
namespace EDD\Admin\Settings;
|
||||
|
||||
use \EDD\Admin\Extensions\Extension;
|
||||
|
||||
class Reviews extends Extension {
|
||||
|
||||
/**
|
||||
* The product ID on EDD.
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
protected $item_id = 37976;
|
||||
|
||||
/**
|
||||
* The EDD settings tab where this extension should show.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_tab = 'marketing';
|
||||
|
||||
/**
|
||||
* The settings section for this item.
|
||||
*
|
||||
* @since 2.11.5
|
||||
* @var string
|
||||
*/
|
||||
protected $settings_section = 'reviews';
|
||||
|
||||
/**
|
||||
* The pass level required to access this extension.
|
||||
*/
|
||||
const PASS_LEVEL = \EDD\Admin\Pass_Manager::EXTENDED_PASS_ID;
|
||||
|
||||
public function __construct() {
|
||||
add_filter( 'edd_settings_sections_marketing', array( $this, 'add_section' ) );
|
||||
add_action( 'edd_settings_tab_top_marketing_reviews', array( $this, 'settings_field' ) );
|
||||
add_action( 'edd_settings_tab_top_marketing_reviews', array( $this, 'hide_submit_button' ) );
|
||||
add_action( 'add_meta_boxes', array( $this, 'maybe_do_metabox' ) );
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the custom configuration for Reviews.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param \EDD\Admin\Extensions\ProductData $product_data The product data object.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_configuration( \EDD\Admin\Extensions\ProductData $product_data ) {
|
||||
$configuration = array(
|
||||
'title' => 'Build Trust With Real Customer Reviews',
|
||||
);
|
||||
$settings_configuration = array(
|
||||
'style' => 'detailed-2col',
|
||||
'description' => $this->get_custom_description(),
|
||||
'features' => array(
|
||||
'Request Reviews',
|
||||
'Incentivize Reviewers',
|
||||
'Full Schema.org Support',
|
||||
'Embed Reviews Via Blocks',
|
||||
'Limit Reviews to Customers',
|
||||
'Vendor Reviews (with Frontend Submissions)',
|
||||
),
|
||||
);
|
||||
return $this->is_edd_settings_screen() ? array_merge( $configuration, $settings_configuration ) : $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a custom description for the Reviews extension card.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return string
|
||||
*/
|
||||
private function get_custom_description() {
|
||||
$description = array(
|
||||
'Increase sales on your site with social proof. 70% of online shoppers don\'t purchase before reading reviews.',
|
||||
'Easily collect, manage, and beautifully display reviews all from your WordPress dashboard.',
|
||||
);
|
||||
|
||||
return $this->format_description( $description );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Reviews section to the settings.
|
||||
*
|
||||
* @param array $sections
|
||||
* @return array
|
||||
*/
|
||||
public function add_section( $sections ) {
|
||||
if ( ! $this->can_show_product_section() ) {
|
||||
return $sections;
|
||||
}
|
||||
|
||||
$sections[ $this->settings_section ] = __( 'Reviews', 'easy-digital-downloads' );
|
||||
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* If Reviews is not active, registers a metabox on individual download edit screen.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return void
|
||||
*/
|
||||
public function maybe_do_metabox() {
|
||||
if ( ! $this->is_download_edit_screen() ) {
|
||||
return;
|
||||
}
|
||||
if ( $this->is_activated() ) {
|
||||
return;
|
||||
}
|
||||
add_meta_box(
|
||||
'edd-reviews-status',
|
||||
__( 'Product Reviews', 'easy-digital-downloads' ),
|
||||
array( $this, 'settings_field' ),
|
||||
'download',
|
||||
'side',
|
||||
'low'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether EDD Reviews active or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool True if Reviews is active.
|
||||
*/
|
||||
protected function is_activated() {
|
||||
if ( $this->manager->is_plugin_active( $this->get_product_data() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return function_exists( 'edd_reviews' );
|
||||
}
|
||||
}
|
||||
|
||||
new Reviews();
|
@ -1,232 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* WP Mail SMTP
|
||||
*
|
||||
* Manages automatic installation/activation for WP Mail SMTP.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage WP_SMTP
|
||||
* @copyright Copyright (c) 2021, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 2.11.4
|
||||
*/
|
||||
namespace EDD\Admin\Settings;
|
||||
|
||||
class WP_SMTP {
|
||||
|
||||
/**
|
||||
* Array of configuration data for WP Mail SMTP.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $config = array(
|
||||
'lite_plugin' => 'wp-mail-smtp/wp_mail_smtp.php',
|
||||
'lite_wporg_url' => 'https://wordpress.org/plugins/wp-mail-smtp/',
|
||||
'lite_download_url' => 'https://downloads.wordpress.org/plugin/wp-mail-smtp.zip',
|
||||
'pro_plugin' => 'wp-mail-smtp-pro/wp_mail_smtp.php',
|
||||
'smtp_settings' => 'admin.php?page=wp-mail-smtp',
|
||||
'smtp_wizard' => 'admin.php?page=wp-mail-smtp-setup-wizard',
|
||||
);
|
||||
|
||||
/**
|
||||
* The Extension Manager
|
||||
*
|
||||
* @var \EDD\Admin\Extensions\Extension_Manager
|
||||
*/
|
||||
private $manager;
|
||||
|
||||
public function __construct() {
|
||||
add_filter( 'edd_settings_emails', array( $this, 'register_setting' ) );
|
||||
add_action( 'edd_wpsmtp', array( $this, 'settings_field' ) );
|
||||
|
||||
$this->manager = new \EDD\Admin\Extensions\Extension_Manager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the setting to show the WP SMTP installer if it isn't active.
|
||||
*
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
public function register_setting( $settings ) {
|
||||
if ( $this->is_smtp_configured() ) {
|
||||
return $settings;
|
||||
}
|
||||
$settings['main']['wpsmtp'] = array(
|
||||
'id' => 'wpsmtp',
|
||||
'name' => __( 'Improve Email Deliverability', 'easy-digital-downloads' ),
|
||||
'desc' => '',
|
||||
'type' => 'hook',
|
||||
);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Output the settings field (installation helper).
|
||||
*
|
||||
* @param array $args
|
||||
* @return void
|
||||
*/
|
||||
public function settings_field( $args ) {
|
||||
$this->manager->enqueue();
|
||||
?>
|
||||
<div class="edd-extension-manager__body">
|
||||
<p class="edd-extension-manager__description">
|
||||
<?php esc_html_e( 'WP Mail SMTP allows you to easily set up WordPress to use a trusted provider to reliably send emails, including sales notifications.', 'easy-digital-downloads' ); ?>
|
||||
</p>
|
||||
|
||||
<div class="edd-extension-manager__group">
|
||||
<div class="edd-extension-manager__step">
|
||||
<?php $this->manager->button( $this->get_button_parameters() ); ?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if ( $this->is_smtp_activated() ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="edd-extension-manager__step" style="display:none;">
|
||||
<?php $this->manager->link( $this->get_link_parameters() ); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the button parameters.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_button_parameters() {
|
||||
$button = array();
|
||||
// If neither the lite nor pro plugin is installed, the button will prompt to install and activate the lite plugin.
|
||||
if ( ! $this->manager->is_plugin_installed( $this->config['lite_plugin'] ) && ! $this->manager->is_plugin_installed( $this->config['pro_plugin'] ) ) {
|
||||
$button['plugin'] = $this->config['lite_download_url'];
|
||||
$button['action'] = 'install';
|
||||
$button['button_text'] = __( 'Install & Activate WP Mail SMTP', 'easy-digital-downloads' );
|
||||
} elseif ( ! $this->is_smtp_activated() ) {
|
||||
// If one of the SMTP plugins is installed, but not activated, the button will prompt to activate it.
|
||||
$button['plugin'] = $this->config['lite_plugin'];
|
||||
$button['action'] = 'activate';
|
||||
$button['button_text'] = __( 'Activate WP Mail SMTP', 'easy-digital-downloads' );
|
||||
} elseif ( ! $this->is_smtp_configured() ) {
|
||||
// If the plugin is active, but not configured, the button will send them to the setup wizard.
|
||||
$button = $this->get_link_parameters();
|
||||
}
|
||||
|
||||
return $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of parameters for the link to configure WP Mail SMTP.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @return array
|
||||
*/
|
||||
private function get_link_parameters() {
|
||||
return $this->is_smtp_configured() ?
|
||||
array(
|
||||
'button_text' => __( 'Configure WP Mail SMTP', 'easy-digital-downloads' ),
|
||||
'href' => admin_url( $this->config['smtp_settings'] ),
|
||||
) :
|
||||
array(
|
||||
'button_text' => __( 'Run the WP Mail SMTP Setup Wizard', 'easy-digital-downloads' ),
|
||||
'href' => admin_url( $this->config['smtp_wizard'] ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether WP Mail SMTP plugin configured or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool True if some mailer is selected and configured properly.
|
||||
*/
|
||||
protected function is_smtp_configured() {
|
||||
|
||||
if ( ! $this->is_smtp_activated() || ! class_exists( '\\WPMailSMTP\\Options' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$phpmailer = $this->get_phpmailer();
|
||||
|
||||
$mailer = \WPMailSMTP\Options::init()->get( 'mail', 'mailer' );
|
||||
$is_mailer_complete = ! empty( $mailer ) && wp_mail_smtp()->get_providers()->get_mailer( $mailer, $phpmailer )->is_mailer_complete();
|
||||
|
||||
return 'mail' !== $mailer && $is_mailer_complete;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether WP Mail SMTP plugin active or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return bool True if SMTP plugin is active.
|
||||
*/
|
||||
protected function is_smtp_activated() {
|
||||
return function_exists( 'wp_mail_smtp' ) && ( is_plugin_active( $this->config['lite_plugin'] ) || is_plugin_active( $this->config['pro_plugin'] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get $phpmailer instance.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return \PHPMailer|\PHPMailer\PHPMailer\PHPMailer Instance of PHPMailer.
|
||||
*/
|
||||
protected function get_phpmailer() {
|
||||
|
||||
if ( version_compare( get_bloginfo( 'version' ), '5.5-alpha', '<' ) ) {
|
||||
$phpmailer = $this->get_phpmailer_v5();
|
||||
} else {
|
||||
$phpmailer = $this->get_phpmailer_v6();
|
||||
}
|
||||
|
||||
return $phpmailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get $phpmailer v5 instance.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return \PHPMailer Instance of PHPMailer.
|
||||
*/
|
||||
private function get_phpmailer_v5() {
|
||||
|
||||
global $phpmailer;
|
||||
|
||||
if ( ! ( $phpmailer instanceof \PHPMailer ) ) {
|
||||
require_once ABSPATH . WPINC . '/class-phpmailer.php';
|
||||
require_once ABSPATH . WPINC . '/class-smtp.php';
|
||||
$phpmailer = new \PHPMailer( true ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
}
|
||||
|
||||
return $phpmailer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get $phpmailer v6 instance.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return \PHPMailer\PHPMailer\PHPMailer Instance of PHPMailer.
|
||||
*/
|
||||
private function get_phpmailer_v6() {
|
||||
|
||||
global $phpmailer;
|
||||
|
||||
if ( ! ( $phpmailer instanceof \PHPMailer\PHPMailer\PHPMailer ) ) {
|
||||
require_once ABSPATH . WPINC . '/PHPMailer/PHPMailer.php';
|
||||
require_once ABSPATH . WPINC . '/PHPMailer/SMTP.php';
|
||||
require_once ABSPATH . WPINC . '/PHPMailer/Exception.php';
|
||||
$phpmailer = new \PHPMailer\PHPMailer\PHPMailer( true ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
}
|
||||
|
||||
return $phpmailer;
|
||||
}
|
||||
}
|
||||
|
||||
new WP_SMTP();
|
@ -513,33 +513,40 @@ class EDD_Batch_Payments_Import extends EDD_Batch_Import {
|
||||
* Look up Download by title and create one if none is found
|
||||
*
|
||||
* @since 2.6
|
||||
* @return int Download ID
|
||||
* @return int|false Download ID or false if the download could not be created.
|
||||
*/
|
||||
private function maybe_create_download( $title = '' ) {
|
||||
|
||||
if( ! is_string( $title ) ) {
|
||||
if ( ! is_string( $title ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$download = get_page_by_title( $title, OBJECT, 'download' );
|
||||
|
||||
if( $download ) {
|
||||
|
||||
$download_id = $download->ID;
|
||||
|
||||
} else {
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'download',
|
||||
'post_title' => $title,
|
||||
'post_author' => get_current_user_id()
|
||||
);
|
||||
|
||||
$download_id = wp_insert_post( $args );
|
||||
$download = new WP_Query(
|
||||
array(
|
||||
'post_type' => 'download',
|
||||
'title' => $title,
|
||||
'post_status' => 'all',
|
||||
'posts_per_page' => 1,
|
||||
'no_found_rows' => true,
|
||||
'ignore_sticky_posts' => true,
|
||||
'update_post_term_cache' => false,
|
||||
'update_post_meta_cache' => false,
|
||||
'orderby' => 'post_date ID',
|
||||
'order' => 'ASC',
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! empty( $download->post ) ) {
|
||||
return $download->post->ID;
|
||||
}
|
||||
|
||||
return $download_id;
|
||||
$args = array(
|
||||
'post_type' => 'download',
|
||||
'post_title' => $title,
|
||||
'post_author' => get_current_user_id(),
|
||||
);
|
||||
|
||||
return wp_insert_post( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Installers;
|
||||
|
||||
use EDD\Admin\Installers\PluginSilentUpgraderSkin;
|
||||
|
||||
/**
|
||||
* Skin for on-the-fly addon installations.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @since 1.5.6.1 Extend PluginSilentUpgraderSkin and clean up the class.
|
||||
*/
|
||||
class Install_Skin extends PluginSilentUpgraderSkin {
|
||||
|
||||
/**
|
||||
* Instead of outputting HTML for errors, json_encode the errors and send them
|
||||
* back to the Ajax script for processing.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param array $errors Array of errors with the install process.
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
|
||||
if ( ! empty( $errors ) ) {
|
||||
wp_send_json_error( $errors );
|
||||
}
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Installers;
|
||||
|
||||
/** \WP_Upgrader_Skin class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader-skin.php';
|
||||
|
||||
/**
|
||||
* Class PluginSilentUpgraderSkin.
|
||||
*
|
||||
* @internal Please do not use this class outside of core WPForms development. May be removed at any time.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
class PluginSilentUpgraderSkin extends \WP_Upgrader_Skin {
|
||||
|
||||
/**
|
||||
* Empty out the header of its HTML content and only check to see if it has
|
||||
* been performed or not.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
public function header() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty out the footer of its HTML contents.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
public function footer() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of outputting HTML for errors, just return them.
|
||||
* Ajax request will just ignore it.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param array $errors Array of errors with the install process.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function error( $errors ) {
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty out JavaScript output that calls function to decrement the update counts.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param string $type Type of update count to decrement.
|
||||
*/
|
||||
public function decrement_update_count( $type ) {
|
||||
}
|
||||
}
|
@ -1,608 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace EDD\Admin\Installers;
|
||||
|
||||
use WP_Error;
|
||||
use WP_Upgrader;
|
||||
use WP_Filesystem_Base;
|
||||
|
||||
/** \WP_Upgrader class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
|
||||
|
||||
/** \Plugin_Upgrader class */
|
||||
require_once ABSPATH . 'wp-admin/includes/class-plugin-upgrader.php';
|
||||
|
||||
/**
|
||||
* In WP 5.3 a PHP 5.6 splat operator (...$args) was added to \WP_Upgrader_Skin::feedback().
|
||||
* We need to remove all calls to *Skin::feedback() method, as we can't override it in own Skins
|
||||
* without breaking support for PHP 5.3-5.5.
|
||||
*
|
||||
* @internal Please do not use this class outside of core EDD development. May be removed at any time.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*/
|
||||
class PluginSilentUpgrader extends \Plugin_Upgrader {
|
||||
|
||||
/**
|
||||
* Run an upgrade/installation.
|
||||
*
|
||||
* Attempt to download the package (if it is not a local file), unpack it, and
|
||||
* install it in the destination folder.
|
||||
*
|
||||
* @since 1.5.6.1
|
||||
*
|
||||
* @param array $options {
|
||||
* Array or string of arguments for upgrading/installing a package.
|
||||
*
|
||||
* @type string $package The full path or URI of the package to install.
|
||||
* Default empty.
|
||||
* @type string $destination The full path to the destination folder.
|
||||
* Default empty.
|
||||
* @type bool $clear_destination Whether to delete any files already in the
|
||||
* destination folder. Default false.
|
||||
* @type bool $clear_working Whether to delete the files form the working
|
||||
* directory after copying to the destination.
|
||||
* Default false.
|
||||
* @type bool $abort_if_destination_exists Whether to abort the installation if the destination
|
||||
* folder already exists. When true, `$clear_destination`
|
||||
* should be false. Default true.
|
||||
* @type bool $is_multi Whether this run is one of multiple upgrade/installation
|
||||
* actions being performed in bulk. When true, the skin
|
||||
* WP_Upgrader::header() and WP_Upgrader::footer()
|
||||
* aren't called. Default false.
|
||||
* @type array $hook_extra Extra arguments to pass to the filter hooks called by
|
||||
* WP_Upgrader::run().
|
||||
* }
|
||||
* @return array|false|WP_error The result from self::install_package() on success, otherwise a WP_Error,
|
||||
* or false if unable to connect to the filesystem.
|
||||
*/
|
||||
public function run( $options ) {
|
||||
|
||||
$defaults = array(
|
||||
'package' => '', // Please always pass this.
|
||||
'destination' => '', // And this
|
||||
'clear_destination' => false,
|
||||
'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please
|
||||
'clear_working' => true,
|
||||
'is_multi' => false,
|
||||
'hook_extra' => array(), // Pass any extra $hook_extra args here, this will be passed to any hooked filters.
|
||||
);
|
||||
|
||||
$options = wp_parse_args( $options, $defaults );
|
||||
|
||||
/**
|
||||
* Filter the package options before running an update.
|
||||
*
|
||||
* See also {@see 'upgrader_process_complete'}.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param array $options {
|
||||
* Options used by the upgrader.
|
||||
*
|
||||
* @type string $package Package for update.
|
||||
* @type string $destination Update location.
|
||||
* @type bool $clear_destination Clear the destination resource.
|
||||
* @type bool $clear_working Clear the working resource.
|
||||
* @type bool $abort_if_destination_exists Abort if the Destination directory exists.
|
||||
* @type bool $is_multi Whether the upgrader is running multiple times.
|
||||
* @type array $hook_extra {
|
||||
* Extra hook arguments.
|
||||
*
|
||||
* @type string $action Type of action. Default 'update'.
|
||||
* @type string $type Type of update process. Accepts 'plugin', 'theme', or 'core'.
|
||||
* @type bool $bulk Whether the update process is a bulk update. Default true.
|
||||
* @type string $plugin Path to the plugin file relative to the plugins directory.
|
||||
* @type string $theme The stylesheet or template name of the theme.
|
||||
* @type string $language_update_type The language pack update type. Accepts 'plugin', 'theme',
|
||||
* or 'core'.
|
||||
* @type object $language_update The language pack update offer.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
$options = apply_filters( 'upgrader_package_options', $options );
|
||||
|
||||
if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times
|
||||
$this->skin->header();
|
||||
}
|
||||
|
||||
// Connect to the Filesystem first.
|
||||
$res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) );
|
||||
// Mainly for non-connected filesystem.
|
||||
if ( ! $res ) {
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->skin->before();
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
$this->skin->error( $res );
|
||||
$this->skin->after();
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Download the package (Note, This just returns the filename
|
||||
* of the file if the package is a local file)
|
||||
*/
|
||||
$download = $this->download_package( $options['package'], true );
|
||||
|
||||
// Allow for signature soft-fail.
|
||||
// WARNING: This may be removed in the future.
|
||||
if ( is_wp_error( $download ) && $download->get_error_data( 'softfail-filename' ) ) {
|
||||
|
||||
// Don't output the 'no signature could be found' failure message for now.
|
||||
if ( (string) $download->get_error_code() !== 'signature_verification_no_signature' || WP_DEBUG ) {
|
||||
// Outout the failure error as a normal feedback, and not as an error:
|
||||
//$this->skin->feedback( $download->get_error_message() );
|
||||
|
||||
// Report this failure back to WordPress.org for debugging purposes.
|
||||
wp_version_check(
|
||||
array(
|
||||
'signature_failure_code' => $download->get_error_code(),
|
||||
'signature_failure_data' => $download->get_error_data(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Pretend this error didn't happen.
|
||||
$download = $download->get_error_data( 'softfail-filename' );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $download ) ) {
|
||||
$this->skin->error( $download );
|
||||
$this->skin->after();
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return $download;
|
||||
}
|
||||
|
||||
$delete_package = ( (string) $download !== (string) $options['package'] ); // Do not delete a "local" file.
|
||||
|
||||
// Unzips the file into a temporary directory.
|
||||
$working_dir = $this->unpack_package( $download, $delete_package );
|
||||
if ( is_wp_error( $working_dir ) ) {
|
||||
$this->skin->error( $working_dir );
|
||||
$this->skin->after();
|
||||
if ( ! $options['is_multi'] ) {
|
||||
$this->skin->footer();
|
||||
}
|
||||
return $working_dir;
|
||||
}
|
||||
|
||||
// With the given options, this installs it to the destination directory.
|
||||
$result = $this->install_package(
|
||||
array(
|
||||
'source' => $working_dir,
|
||||
'destination' => $options['destination'],
|
||||
'clear_destination' => $options['clear_destination'],
|
||||
'abort_if_destination_exists' => $options['abort_if_destination_exists'],
|
||||
'clear_working' => $options['clear_working'],
|
||||
'hook_extra' => $options['hook_extra'],
|
||||
)
|
||||
);
|
||||
|
||||
$this->skin->set_result( $result );
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$this->skin->error( $result );
|
||||
//$this->skin->feedback( 'process_failed' );
|
||||
} else {
|
||||
// Installation succeeded.
|
||||
//$this->skin->feedback( 'process_success' );
|
||||
}
|
||||
|
||||
$this->skin->after();
|
||||
|
||||
if ( ! $options['is_multi'] ) {
|
||||
|
||||
/**
|
||||
* Fire when the upgrader process is complete.
|
||||
*
|
||||
* See also {@see 'upgrader_package_options'}.
|
||||
*
|
||||
* @since 3.6.0
|
||||
* @since 3.7.0 Added to WP_Upgrader::run().
|
||||
* @since 4.6.0 `$translations` was added as a possible argument to `$hook_extra`.
|
||||
*
|
||||
* @param WP_Upgrader $this WP_Upgrader instance. In other contexts, $this, might be a
|
||||
* Theme_Upgrader, Plugin_Upgrader, Core_Upgrade, or Language_Pack_Upgrader instance.
|
||||
* @param array $hook_extra {
|
||||
* Array of bulk item update data.
|
||||
*
|
||||
* @type string $action Type of action. Default 'update'.
|
||||
* @type string $type Type of update process. Accepts 'plugin', 'theme', 'translation', or 'core'.
|
||||
* @type bool $bulk Whether the update process is a bulk update. Default true.
|
||||
* @type array $plugins Array of the basename paths of the plugins' main files.
|
||||
* @type array $themes The theme slugs.
|
||||
* @type array $translations {
|
||||
* Array of translations update data.
|
||||
*
|
||||
* @type string $language The locale the translation is for.
|
||||
* @type string $type Type of translation. Accepts 'plugin', 'theme', or 'core'.
|
||||
* @type string $slug Text domain the translation is for. The slug of a theme/plugin or
|
||||
* 'default' for core translations.
|
||||
* @type string $version The version of a theme, plugin, or core.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
do_action( 'upgrader_process_complete', $this, $options['hook_extra'] );
|
||||
|
||||
$this->skin->footer();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle maintenance mode for the site.
|
||||
*
|
||||
* Create/delete the maintenance file to enable/disable maintenance mode.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem Subclass
|
||||
*
|
||||
* @param bool $enable True to enable maintenance mode, false to disable.
|
||||
*/
|
||||
public function maintenance_mode( $enable = false ) {
|
||||
global $wp_filesystem;
|
||||
$file = $wp_filesystem->abspath() . '.maintenance';
|
||||
if ( $enable ) {
|
||||
//$this->skin->feedback( 'maintenance_start' );
|
||||
// Create maintenance file to signal that we are upgrading
|
||||
$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
|
||||
$wp_filesystem->delete( $file );
|
||||
$wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
|
||||
} elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
|
||||
//$this->skin->feedback( 'maintenance_end' );
|
||||
$wp_filesystem->delete( $file );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a package.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 5.5.0 Added the `$hook_extra` parameter.
|
||||
*
|
||||
* @param string $package The URI of the package. If this is the full path to an
|
||||
* existing local file, it will be returned untouched.
|
||||
* @param bool $check_signatures Whether to validate file signatures. Default false.
|
||||
* @param array $hook_extra Extra arguments to pass to the filter hooks. Default empty array.
|
||||
* @return string|WP_Error The full path to the downloaded package file, or a WP_Error object.
|
||||
*/
|
||||
public function download_package( $package, $check_signatures = false, $hook_extra = array() ) {
|
||||
|
||||
/**
|
||||
* Filters whether to return the package.
|
||||
*
|
||||
* @since 3.7.0
|
||||
* @since 5.5.0 Added the `$hook_extra` parameter.
|
||||
*
|
||||
* @param bool $reply Whether to bail without returning the package.
|
||||
* Default false.
|
||||
* @param string $package The package file name.
|
||||
* @param WP_Upgrader $this The WP_Upgrader instance.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$reply = apply_filters( 'upgrader_pre_download', false, $package, $this, $hook_extra );
|
||||
if ( false !== $reply ) {
|
||||
return $reply;
|
||||
}
|
||||
|
||||
if ( ! preg_match( '!^(http|https|ftp)://!i', $package ) && file_exists( $package ) ) { // Local file or remote?
|
||||
return $package; // Must be a local file.
|
||||
}
|
||||
|
||||
if ( empty( $package ) ) {
|
||||
return new WP_Error( 'no_package', $this->strings['no_package'] );
|
||||
}
|
||||
|
||||
//$this->skin->feedback( 'downloading_package', $package );
|
||||
|
||||
$download_file = download_url( $package, 300, $check_signatures );
|
||||
|
||||
if ( is_wp_error( $download_file ) && ! $download_file->get_error_data( 'softfail-filename' ) ) {
|
||||
return new WP_Error( 'download_failed', $this->strings['download_failed'], $download_file->get_error_message() );
|
||||
}
|
||||
|
||||
return $download_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unpack a compressed package file.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
*
|
||||
* @param string $package Full path to the package file.
|
||||
* @param bool $delete_package Optional. Whether to delete the package file after attempting
|
||||
* to unpack it. Default true.
|
||||
* @return string|WP_Error The path to the unpacked contents, or a WP_Error on failure.
|
||||
*/
|
||||
public function unpack_package( $package, $delete_package = true ) {
|
||||
global $wp_filesystem;
|
||||
|
||||
//$this->skin->feedback( 'unpack_package' );
|
||||
|
||||
$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
|
||||
|
||||
//Clean up contents of upgrade directory beforehand.
|
||||
$upgrade_files = $wp_filesystem->dirlist( $upgrade_folder );
|
||||
if ( ! empty( $upgrade_files ) ) {
|
||||
foreach ( $upgrade_files as $file ) {
|
||||
$wp_filesystem->delete( $upgrade_folder . $file['name'], true );
|
||||
}
|
||||
}
|
||||
|
||||
// We need a working directory - Strip off any .tmp or .zip suffixes
|
||||
$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
|
||||
|
||||
// Clean up working directory
|
||||
if ( $wp_filesystem->is_dir( $working_dir ) ) {
|
||||
$wp_filesystem->delete( $working_dir, true );
|
||||
}
|
||||
|
||||
// Unzip package to working directory
|
||||
$result = unzip_file( $package, $working_dir );
|
||||
|
||||
// Once extracted, delete the package if required.
|
||||
if ( $delete_package ) {
|
||||
unlink( $package );
|
||||
}
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
$wp_filesystem->delete( $working_dir, true );
|
||||
if ( $result->get_error_code() === 'incompatible_archive' ) {
|
||||
return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
return $working_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a package.
|
||||
*
|
||||
* Copies the contents of a package form a source directory, and installs them in
|
||||
* a destination directory. Optionally removes the source. It can also optionally
|
||||
* clear out the destination folder if it already exists.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
|
||||
* @global array $wp_theme_directories
|
||||
*
|
||||
* @param array|string $args {
|
||||
* Optional. Array or string of arguments for installing a package. Default empty array.
|
||||
*
|
||||
* @type string $source Required path to the package source. Default empty.
|
||||
* @type string $destination Required path to a folder to install the package in.
|
||||
* Default empty.
|
||||
* @type bool $clear_destination Whether to delete any files already in the destination
|
||||
* folder. Default false.
|
||||
* @type bool $clear_working Whether to delete the files form the working directory
|
||||
* after copying to the destination. Default false.
|
||||
* @type bool $abort_if_destination_exists Whether to abort the installation if
|
||||
* the destination folder already exists. Default true.
|
||||
* @type array $hook_extra Extra arguments to pass to the filter hooks called by
|
||||
* WP_Upgrader::install_package(). Default empty array.
|
||||
* }
|
||||
*
|
||||
* @return array|WP_Error The result (also stored in `WP_Upgrader::$result`), or a WP_Error on failure.
|
||||
*/
|
||||
public function install_package( $args = array() ) {
|
||||
global $wp_filesystem, $wp_theme_directories;
|
||||
|
||||
$defaults = array(
|
||||
'source' => '', // Please always pass this
|
||||
'destination' => '', // and this
|
||||
'clear_destination' => false,
|
||||
'clear_working' => false,
|
||||
'abort_if_destination_exists' => true,
|
||||
'hook_extra' => array(),
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
// These were previously extract()'d.
|
||||
$source = $args['source'];
|
||||
$destination = $args['destination'];
|
||||
$clear_destination = $args['clear_destination'];
|
||||
|
||||
// @todo does this need to be replaced?
|
||||
// wpforms_set_time_limit( 300 );
|
||||
|
||||
if ( empty( $source ) || empty( $destination ) ) {
|
||||
return new WP_Error( 'bad_request', $this->strings['bad_request'] );
|
||||
}
|
||||
//$this->skin->feedback( 'installing_package' );
|
||||
|
||||
/**
|
||||
* Filter the install response before the installation has started.
|
||||
*
|
||||
* Returning a truthy value, or one that could be evaluated as a WP_Error
|
||||
* will effectively short-circuit the installation, returning that value
|
||||
* instead.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool|WP_Error $response Response.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] );
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Retain the Original source and destinations.
|
||||
$remote_source = $args['source'];
|
||||
$local_destination = $destination;
|
||||
|
||||
$source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) );
|
||||
$remote_destination = $wp_filesystem->find_folder( $local_destination );
|
||||
$count_source_files = count( $source_files );
|
||||
|
||||
// Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
|
||||
if ( $count_source_files === 1 && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { // Only one folder? Then we want its contents.
|
||||
$source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
|
||||
} elseif ( $count_source_files === 0 ) {
|
||||
return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
|
||||
} else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
|
||||
$source = trailingslashit( $args['source'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the source file location for the upgrade package.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @since 4.4.0 The $hook_extra parameter became available.
|
||||
*
|
||||
* @param string $source File source location.
|
||||
* @param string $remote_source Remote file source location.
|
||||
* @param WP_Upgrader $this WP_Upgrader instance.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] );
|
||||
|
||||
if ( is_wp_error( $source ) ) {
|
||||
return $source;
|
||||
}
|
||||
|
||||
// Has the source location changed? If so, we need a new source_files list.
|
||||
if ( $source !== $remote_source ) {
|
||||
$source_files = array_keys( $wp_filesystem->dirlist( $source ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* Protection against deleting files in any important base directories.
|
||||
* Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
|
||||
* destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
|
||||
* to copy the directory into the directory, whilst they pass the source
|
||||
* as the actual files to copy.
|
||||
*/
|
||||
$protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' );
|
||||
|
||||
if ( is_array( $wp_theme_directories ) ) {
|
||||
$protected_directories = array_merge( $protected_directories, $wp_theme_directories );
|
||||
}
|
||||
|
||||
if ( in_array( $destination, $protected_directories ) ) {
|
||||
$remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
|
||||
$destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
|
||||
}
|
||||
|
||||
if ( $clear_destination ) {
|
||||
// We're going to clear the destination if there's something there.
|
||||
$removed = $this->clear_destination( $remote_destination );
|
||||
|
||||
/**
|
||||
* Filter whether the upgrader cleared the destination.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param mixed $removed Whether the destination was cleared. true on success, WP_Error on failure
|
||||
* @param string $local_destination The local package destination.
|
||||
* @param string $remote_destination The remote package destination.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
*/
|
||||
$removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] );
|
||||
|
||||
if ( is_wp_error( $removed ) ) {
|
||||
return $removed;
|
||||
}
|
||||
} elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists( $remote_destination ) ) {
|
||||
// If we're not clearing the destination folder and something exists there already, Bail.
|
||||
// But first check to see if there are actually any files in the folder.
|
||||
$_files = $wp_filesystem->dirlist( $remote_destination );
|
||||
|
||||
if ( ! empty( $_files ) ) {
|
||||
$wp_filesystem->delete( $remote_source, true ); // Clear out the source files.
|
||||
|
||||
return new WP_Error( 'folder_exists', $this->strings['folder_exists'], $remote_destination );
|
||||
}
|
||||
}
|
||||
|
||||
// Create destination if needed.
|
||||
if ( ! $wp_filesystem->exists( $remote_destination ) ) {
|
||||
if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
|
||||
return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination );
|
||||
}
|
||||
}
|
||||
|
||||
// Copy new version of item into place.
|
||||
$result = copy_dir( $source, $remote_destination );
|
||||
|
||||
if ( is_wp_error( $result ) ) {
|
||||
if ( $args['clear_working'] ) {
|
||||
$wp_filesystem->delete( $remote_source, true );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Clear the Working folder?
|
||||
if ( $args['clear_working'] ) {
|
||||
$wp_filesystem->delete( $remote_source, true );
|
||||
}
|
||||
|
||||
$destination_name = basename( str_replace( $local_destination, '', $destination ) );
|
||||
|
||||
if ( $destination_name === '.' ) {
|
||||
$destination_name = '';
|
||||
}
|
||||
|
||||
$this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
|
||||
|
||||
/**
|
||||
* Filter the installation response after the installation has finished.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param bool $response Installation response.
|
||||
* @param array $hook_extra Extra arguments passed to hooked filters.
|
||||
* @param array $result Installation result data.
|
||||
*/
|
||||
$res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result );
|
||||
|
||||
if ( is_wp_error( $res ) ) {
|
||||
$this->result = $res;
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
// Bombard the calling function will all the info which we've just used.
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a plugin package.
|
||||
*
|
||||
* @since 1.6.3
|
||||
*
|
||||
* @param string $package The full local path or URI of the package.
|
||||
* @param array $args Optional. Other arguments for installing a plugin package. Default empty array.
|
||||
*
|
||||
* @return bool|\WP_Error True if the installation was successful, false or a WP_Error otherwise.
|
||||
*/
|
||||
public function install( $package, $args = array() ) {
|
||||
|
||||
$result = parent::install( $package, $args );
|
||||
if ( true === $result ) {
|
||||
do_action( 'edd_plugin_installed', $package );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
@ -356,9 +356,6 @@ function edd_ajax_generate_file_download_link() {
|
||||
die( '-3' );
|
||||
}
|
||||
|
||||
$payment_key = edd_get_payment_key( $payment_id );
|
||||
$email = edd_get_payment_user_email( $payment_id );
|
||||
|
||||
$limit = edd_get_file_download_limit( $download_id );
|
||||
if ( ! empty( $limit ) ) {
|
||||
// Increase the file download limit when generating new links
|
||||
@ -370,10 +367,10 @@ function edd_ajax_generate_file_download_link() {
|
||||
die( '-4' );
|
||||
}
|
||||
|
||||
$order = edd_get_order( $payment_id );
|
||||
$file_urls = '';
|
||||
|
||||
foreach( $files as $file_key => $file ) {
|
||||
$file_urls .= edd_get_download_file_url( $payment_key, $email, $file_key, $download_id, $price_id );
|
||||
foreach ( $files as $file_key => $file ) {
|
||||
$file_urls .= edd_get_download_file_url( $order, $order->email, $file_key, $download_id, $price_id );
|
||||
$file_urls .= "\n\n";
|
||||
}
|
||||
|
||||
@ -587,15 +584,18 @@ function edd_orders_list_table_process_bulk_actions() {
|
||||
_doing_it_wrong( __FUNCTION__, 'This method is not meant to be called directly.', 'EDD 3.0' );
|
||||
}
|
||||
|
||||
// Check the current user's capability.
|
||||
if ( ! current_user_can( 'edit_shop_payments' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$action = isset( $_REQUEST['action'] ) // WPCS: CSRF ok.
|
||||
? sanitize_text_field( $_REQUEST['action'] )
|
||||
: '';
|
||||
|
||||
// If this is a 'delete' action, the capability changes from edit to delete.
|
||||
$cap = 'delete' === $action ? 'delete_shop_payments' : 'edit_shop_payments';
|
||||
|
||||
// Check the current user's capability.
|
||||
if ( ! current_user_can( $cap ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail if we aren't processing bulk actions.
|
||||
if ( '-1' === $action ) {
|
||||
return;
|
||||
@ -625,6 +625,9 @@ function edd_orders_list_table_process_bulk_actions() {
|
||||
case 'restore':
|
||||
edd_restore_order( $id );
|
||||
break;
|
||||
case 'delete':
|
||||
edd_destroy_order( $id );
|
||||
break;
|
||||
case 'set-status-complete':
|
||||
edd_update_payment_status( $id, 'complete' );
|
||||
break;
|
||||
|
@ -368,7 +368,27 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
return;
|
||||
}
|
||||
}
|
||||
esc_html_e( 'No orders found.', 'easy-digital-downloads' );
|
||||
|
||||
$status = $this->get_status();
|
||||
|
||||
if ( ! empty( $status ) ) {
|
||||
$status_label = edd_get_status_label( $status );
|
||||
|
||||
switch ( $status ) {
|
||||
case 'trash':
|
||||
/* Translators: %s is for the status of 'Trash', telling the user no items were found in the trash. */
|
||||
$message = sprintf( __( 'No orders found in %s.', 'easy-digital-downloads' ), $status_label );
|
||||
break;
|
||||
default:
|
||||
/* Translators: %s is for the currently viewed order status filter */
|
||||
$message = sprintf( __( 'No %s orders found.', 'easy-digital-downloads' ), $status_label );
|
||||
break;
|
||||
}
|
||||
|
||||
echo esc_html( $message );
|
||||
} else {
|
||||
esc_html_e( 'No orders found.', 'easy-digital-downloads' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -509,7 +529,7 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
public function column_number( $order ) {
|
||||
$status = $this->get_status();
|
||||
|
||||
// View URL
|
||||
// View URL.
|
||||
$view_url = edd_get_admin_url( array(
|
||||
'page' => 'edd-payment-history',
|
||||
'view' => 'sale' === $order->type
|
||||
@ -518,13 +538,13 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
'id' => absint( $order->id ),
|
||||
) );
|
||||
|
||||
// Default row actions
|
||||
// Default row actions.
|
||||
$row_actions = array(
|
||||
'view' => '<a href="' . esc_url( $view_url ) . '">' . esc_html__( 'Edit', 'easy-digital-downloads' ) . '</a>',
|
||||
);
|
||||
|
||||
// View receipt
|
||||
if ( 'sale' === $order->type && edd_can_view_receipt( $order->payment_key ) ) {
|
||||
// View receipt.
|
||||
if ( 'sale' === $order->type && edd_can_view_receipt( $order ) ) {
|
||||
$row_actions['receipt'] = sprintf(
|
||||
'<a href="%s" target="_blank">%s</a>',
|
||||
edd_get_receipt_page_uri( $order->id ),
|
||||
@ -532,7 +552,7 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
);
|
||||
}
|
||||
|
||||
// Resend Receipt
|
||||
// Resend Receipt.
|
||||
if ( 'sale' === $this->type && 'complete' === $order->status && ! empty( $order->email ) ) {
|
||||
$row_actions['email_links'] = '<a href="' . esc_url( add_query_arg( array(
|
||||
'edd-action' => 'email_links',
|
||||
@ -540,7 +560,7 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
), $this->base_url ) ) . '">' . __( 'Resend Receipt', 'easy-digital-downloads' ) . '</a>';
|
||||
}
|
||||
|
||||
// Keep Delete at the end
|
||||
// Keep Delete at the end.
|
||||
if ( edd_is_order_trashable( $order->id ) ) {
|
||||
$trash_url = wp_nonce_url( add_query_arg( array(
|
||||
'edd-action' => 'trash_order',
|
||||
@ -677,6 +697,10 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
$action = array(
|
||||
'restore' => __( 'Restore', 'easy-digital-downloads' ),
|
||||
);
|
||||
|
||||
if ( current_user_can( 'delete_shop_payments' ) ) {
|
||||
$action['delete'] = __( 'Delete permanently', 'easy-digital-downloads' );
|
||||
}
|
||||
} else {
|
||||
$action['trash'] = __( 'Move to Trash', 'easy-digital-downloads' );
|
||||
}
|
||||
@ -1064,12 +1088,19 @@ class EDD_Payment_History_Table extends List_Table {
|
||||
*
|
||||
* @param string $which
|
||||
* @since 3.1.0.4
|
||||
* @since 3.1.1 Outputs the dialogs for deleting orders.
|
||||
*/
|
||||
protected function display_tablenav( $which ) {
|
||||
if ( 'top' === $which ) {
|
||||
if ( 'top' === $which ) :
|
||||
wp_nonce_field( 'bulk-' . $this->_args['plural'], '_wpnonce', false );
|
||||
}
|
||||
?>
|
||||
?>
|
||||
<div id="edd-bulk-delete-dialog" class="edd-dialog" title="<?php esc_html_e( 'Confirmation Required', 'easy-digital-downloads' ); ?>">
|
||||
<?php esc_html_e( 'You are about to permanently delete orders from your store. Once deleted, these orders are not recoverable. Are you sure you want to continue?', 'easy-digital-downloads' ); ?>
|
||||
</div>
|
||||
<div id="edd-single-delete-dialog" class="edd-dialog" title="<?php esc_html_e( 'Confirmation Required', 'easy-digital-downloads' ); ?>">
|
||||
<?php esc_html_e( 'You are about to permanently delete this order from your store. Once deleted, this order is not recoverable. Are you sure you want to continue?', 'easy-digital-downloads' ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="tablenav <?php echo esc_attr( $which ); ?>">
|
||||
|
||||
<?php if ( $this->has_items() ) : ?>
|
||||
|
@ -25,8 +25,7 @@ defined( 'ABSPATH' ) || exit;
|
||||
function edd_plugin_action_links( $links = array() ) {
|
||||
$edd_links = array();
|
||||
|
||||
$pass_manager = new EDD\Admin\Pass_Manager();
|
||||
if ( ! $pass_manager->has_pass() ) {
|
||||
if ( ! edd_is_pro() ) {
|
||||
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/lite-upgrade/',
|
||||
|
@ -1,172 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Promo Handler
|
||||
*
|
||||
* Handles logic for displaying and dismissing promotional notices.
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license GPL2+
|
||||
* @since 2.10.6
|
||||
*/
|
||||
|
||||
namespace EDD\Admin\Promos;
|
||||
|
||||
use EDD\Admin\Promos\Notices\Notice;
|
||||
use Sandhills\Utils\Persistent_Dismissible;
|
||||
|
||||
class PromoHandler {
|
||||
|
||||
/**
|
||||
* Registered notices.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private $notices = array(
|
||||
'\\EDD\\Admin\\Promos\\Notices\\License_Upgrade_Notice',
|
||||
'\\EDD\\Admin\\Promos\\Notices\\Five_Star_Review_Dashboard',
|
||||
'\\EDD\\Admin\\Promos\\Notices\\Five_Star_Review_Settings',
|
||||
);
|
||||
|
||||
/**
|
||||
* Notices constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_ajax_edd_dismiss_promo_notice', array( $this, 'dismiss_notice' ) );
|
||||
|
||||
$this->load_notices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads and displays all registered promotional notices.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*/
|
||||
private function load_notices() {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/promos/notices/abstract-notice.php';
|
||||
|
||||
foreach ( $this->notices as $notice_class_name ) {
|
||||
if ( ! class_exists( $notice_class_name ) ) {
|
||||
$file_name = strtolower( str_replace( '_', '-', basename( str_replace( '\\', '/', $notice_class_name ) ) ) );
|
||||
$file_path = EDD_PLUGIN_DIR . 'includes/admin/promos/notices/class-' . $file_name . '.php';
|
||||
|
||||
if ( file_exists( $file_path ) ) {
|
||||
require_once $file_path;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( $notice_class_name ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
add_action( $notice_class_name::DISPLAY_HOOK, function () use ( $notice_class_name ) {
|
||||
/** @var Notice $notice */
|
||||
$notice = new $notice_class_name();
|
||||
if ( $notice->should_display() ) {
|
||||
$notice->display();
|
||||
}
|
||||
}, $notice_class_name::DISPLAY_PRIORITY );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not a notice has been dismissed.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @param string $id ID of the notice to check.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_dismissed( $id ) {
|
||||
$is_dismissed = (bool) Persistent_Dismissible::get( array(
|
||||
'id' => 'edd-' . $id
|
||||
) );
|
||||
|
||||
return true === $is_dismissed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dismisses a notice.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @param string $id ID of the notice to dismiss.
|
||||
* @param int $dismissal_length Number of seconds to dismiss the notice for, or `0` for forever.
|
||||
*/
|
||||
public static function dismiss( $id, $dismissal_length = 0 ) {
|
||||
Persistent_Dismissible::set( array(
|
||||
'id' => 'edd-' . $id,
|
||||
'life' => $dismissal_length
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX callback for dismissing a notice.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*/
|
||||
public function dismiss_notice() {
|
||||
$notice_id = ! empty( $_POST['notice_id'] ) ? sanitize_text_field( $_POST['notice_id'] ) : false;
|
||||
if ( empty( $notice_id ) ) {
|
||||
wp_send_json_error( __( 'Missing notice ID.', 'easy-digital-downloads' ), 400 );
|
||||
}
|
||||
|
||||
if ( empty( $_POST['nonce'] ) || ! wp_verify_nonce( $_POST['nonce'], 'edd-dismiss-notice-' . sanitize_key( $_POST['notice_id'] ) ) ) {
|
||||
wp_send_json_error( __( 'You do not have permission to perform this action.', 'easy-digital-downloads' ), 403 );
|
||||
}
|
||||
|
||||
$notice_class_name = $this->get_notice_class_name( $notice_id );
|
||||
|
||||
// No matching notice class was found.
|
||||
if ( ! $notice_class_name ) {
|
||||
wp_send_json_error( __( 'You do not have permission to perform this action.', 'easy-digital-downloads' ), 403 );
|
||||
}
|
||||
|
||||
// Check whether the current user can dismiss the notice.
|
||||
if ( ! defined( $notice_class_name . '::CAPABILITY' ) || ! current_user_can( $notice_class_name::CAPABILITY ) ) {
|
||||
wp_send_json_error( __( 'You do not have permission to perform this action.', 'easy-digital-downloads' ), 403 );
|
||||
}
|
||||
|
||||
$dismissal_length = ! empty( $_POST['lifespan'] ) ? absint( $_POST['lifespan'] ) : 0;
|
||||
|
||||
self::dismiss( sanitize_key( $_POST['notice_id'] ), $dismissal_length );
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the notice class name for a given notice ID.
|
||||
*
|
||||
* @since 2.11.4
|
||||
* @param string $notice_id The notice ID to match.
|
||||
* @return bool|string The class name or false if no matching class was found.
|
||||
*/
|
||||
private function get_notice_class_name( $notice_id ) {
|
||||
$notice_class_name = false;
|
||||
// Look through the registered notice classes for the one being dismissed.
|
||||
foreach ( $this->notices as $notice_class_to_check ) {
|
||||
if ( ! class_exists( $notice_class_to_check ) ) {
|
||||
$file_name = strtolower( str_replace( '_', '-', basename( str_replace( '\\', '/', $notice_class_to_check ) ) ) );
|
||||
$file_path = EDD_PLUGIN_DIR . 'includes/admin/promos/notices/class-' . $file_name . '.php';
|
||||
|
||||
if ( file_exists( $file_path ) ) {
|
||||
require_once $file_path;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! class_exists( $notice_class_to_check ) ) {
|
||||
continue;
|
||||
}
|
||||
$notice = new $notice_class_to_check();
|
||||
if ( $notice->get_id() === $notice_id ) {
|
||||
$notice_class_name = $notice_class_to_check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $notice_class_name;
|
||||
}
|
||||
}
|
||||
|
||||
new PromoHandler();
|
@ -1,125 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Notice
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license GPL2+
|
||||
* @since 2.10.6
|
||||
*/
|
||||
|
||||
namespace EDD\Admin\Promos\Notices;
|
||||
|
||||
use EDD\Admin\Promos\PromoHandler;
|
||||
|
||||
abstract class Notice {
|
||||
|
||||
/**
|
||||
* Action hook for displaying the notice.
|
||||
*/
|
||||
const DISPLAY_HOOK = 'admin_notices';
|
||||
|
||||
/**
|
||||
* The priority for the display hook.
|
||||
*/
|
||||
const DISPLAY_PRIORITY = 10;
|
||||
|
||||
/**
|
||||
* Type of promotional notice.
|
||||
*/
|
||||
const TYPE = 'top-of-page';
|
||||
|
||||
/**
|
||||
* Whether or not the notice can be dismissed.
|
||||
*/
|
||||
const DISMISSIBLE = true;
|
||||
|
||||
/**
|
||||
* The capability required to view/dismiss the notice.
|
||||
*/
|
||||
const CAPABILITY = 'manage_options';
|
||||
|
||||
/**
|
||||
* Displays the notice content.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function _display();
|
||||
|
||||
/**
|
||||
* Generates a unique ID for this notice.
|
||||
* It's the class name (without the namespace) and with underscores converted to hyphens.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return strtolower( str_replace( '_', '-', basename( str_replace( '\\', '/', get_class( $this ) ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not the notice should be displayed.
|
||||
* Typically individual notices should not override this method, as it combines
|
||||
* a dismissal check and custom display logic (`_should_display()`). Custom logic
|
||||
* should go in `_should_display()`.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function should_display() {
|
||||
return current_user_can( static::CAPABILITY ) && ! PromoHandler::is_dismissed( $this->get_id() ) && $this->_should_display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Duration (in seconds) that the notice is dismissed for.
|
||||
* `0` means it's dismissed permanently.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function dismiss_duration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Individual notices can override this method to control display logic.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _should_display() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the notice.
|
||||
* Individual notices typically should not override this method, as it contains
|
||||
* all the notice wrapper logic. Instead, notices should override `_display()`
|
||||
*
|
||||
* @since 2.10.6
|
||||
* @return void
|
||||
*/
|
||||
public function display() {
|
||||
?>
|
||||
<div
|
||||
id="edd-admin-notice-<?php echo esc_attr( $this->get_id() ); ?>"
|
||||
class="edd-admin-notice-<?php echo esc_attr( sanitize_html_class( static::TYPE ) ); ?> edd-promo-notice"
|
||||
data-nonce="<?php echo esc_attr( wp_create_nonce( 'edd-dismiss-notice-' . $this->get_id() ) ); ?>"
|
||||
data-id="<?php echo esc_attr( $this->get_id() ); ?>"
|
||||
data-lifespan="<?php echo esc_attr( static::dismiss_duration() ); ?>"
|
||||
>
|
||||
<?php $this->_display(); ?>
|
||||
|
||||
<?php if ( static::DISMISSIBLE ) : ?>
|
||||
<button class="button-link edd-promo-notice-dismiss">
|
||||
×
|
||||
<span class="screen-reader-text"><?php esc_html_e( 'Dismiss notice', 'easy-digital-downloads' ); ?></span>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
}
|
@ -160,10 +160,14 @@ class Five_Star_Review_Dashboard extends Notice {
|
||||
if ( ! is_numeric( $activated ) || ( $activated + ( DAY_IN_SECONDS * 30 ) ) > time() ) {
|
||||
return false;
|
||||
}
|
||||
// @todo Change this to edd_count_orders in 3.0
|
||||
$payments = edd_count_payments();
|
||||
$orders = edd_count_orders(
|
||||
array(
|
||||
'type' => 'sale',
|
||||
'status__in' => edd_get_complete_order_statuses(),
|
||||
)
|
||||
);
|
||||
|
||||
return isset( $payments->publish ) && $payments->publish >= 15;
|
||||
return $orders >= 15;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,266 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* License Upgrade Notice
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license GPL2+
|
||||
* @since 2.10.6
|
||||
*/
|
||||
|
||||
namespace EDD\Admin\Promos\Notices;
|
||||
|
||||
use EDD\Admin\Pass_Manager;
|
||||
|
||||
class License_Upgrade_Notice extends Notice {
|
||||
|
||||
const DISPLAY_HOOK = 'in_admin_header';
|
||||
|
||||
/**
|
||||
* Number of EDD license keys that have been entered.
|
||||
* Not validated to make sure they're actually active; this is
|
||||
* just an indicator if any licenses exist at all.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $number_license_keys;
|
||||
|
||||
/**
|
||||
* @var Pass_Manager
|
||||
*/
|
||||
private $pass_manager;
|
||||
|
||||
/**
|
||||
* License_Upgrade_Notice constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
global $edd_licensed_products;
|
||||
|
||||
$this->number_license_keys = is_array( $edd_licensed_products ) ? count( $edd_licensed_products ) : 0;
|
||||
$this->pass_manager = new Pass_Manager();
|
||||
}
|
||||
|
||||
/**
|
||||
* This notice lasts 90 days.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public static function dismiss_duration() {
|
||||
return 3 * MONTH_IN_SECONDS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the current page is an EDD admin page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_edd_admin_page() {
|
||||
if ( defined( 'EDD_DOING_TESTS' ) && EDD_DOING_TESTS ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$screen = get_current_screen();
|
||||
|
||||
if ( ! $screen instanceof \WP_Screen || 'dashboard' === $screen->id || ! edd_is_admin_page( '', '', false ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected function _should_display() {
|
||||
|
||||
if ( ! $this->is_edd_admin_page() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Someone with no license keys entered always sees a notice.
|
||||
if ( 0 === $this->number_license_keys ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have no pass data yet, don't show the notice because we don't yet know what it should say.
|
||||
if ( ! $this->pass_manager->has_pass_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If someone has an extended pass or higher, and has an active AffiliateWP license, don't show.
|
||||
try {
|
||||
if (
|
||||
$this->pass_manager->has_pass() &&
|
||||
Pass_Manager::pass_compare( $this->pass_manager->highest_pass_id, Pass_Manager::EXTENDED_PASS_ID, '>=' ) &&
|
||||
$this->has_affiliate_wp_license() &&
|
||||
$this->has_mi_license()
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
} catch ( \Exception $e ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not AffiliateWP is installed and has a license key.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function has_affiliate_wp_license() {
|
||||
if ( ! function_exists( 'affiliate_wp' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (bool) affiliate_wp()->settings->get( 'license_key' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not MonsterInsights is installed and has a license key.
|
||||
*
|
||||
* @since 2.11.6
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function has_mi_license() {
|
||||
if ( ! class_exists( 'MonsterInsights' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$mi_license = \MonsterInsights::$instance->license->get_license_key();
|
||||
return ! empty( $mi_license );
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function _display() {
|
||||
|
||||
try {
|
||||
if ( 0 === $this->number_license_keys ) {
|
||||
$utm_parameters = $this->query_args( 'core' );
|
||||
$link_url = $this->build_url(
|
||||
'https://easydigitaldownloads.com/lite-upgrade/',
|
||||
$utm_parameters
|
||||
);
|
||||
|
||||
$help_url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/what-is-an-edd-pass/',
|
||||
array(
|
||||
'utm_medium' => 'top-promo',
|
||||
'utm_content' => 'what-is-a-pass',
|
||||
)
|
||||
);
|
||||
|
||||
// No license keys active at all.
|
||||
printf(
|
||||
/* Translators: %1$s opening anchor tag; %2$s closing anchor tag */
|
||||
__( 'You are using the free version of Easy Digital Downloads. %1$sPurchase a pass%2$s to get email marketing tools and recurring payments. %3$sAlready have a Pass?%4$s', 'easy-digital-downloads' ),
|
||||
'<a href="' . $link_url . '" target="_blank">',
|
||||
'</a>',
|
||||
'<a href="' . $help_url . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
} elseif ( ! $this->pass_manager->highest_pass_id ) {
|
||||
$utm_parameters = $this->query_args( 'extension-license' );
|
||||
$link_url = $this->build_url(
|
||||
'https://easydigitaldownloads.com/your-account/',
|
||||
$utm_parameters
|
||||
);
|
||||
|
||||
// Individual product license active, but no pass.
|
||||
printf(
|
||||
/* Translators: %1$s opening anchor tag; %2$s closing anchor tag */
|
||||
__( 'For access to additional Easy Digital Downloads extensions to grow your store, consider %1$spurchasing a pass%2$s.', 'easy-digital-downloads' ),
|
||||
'<a href="' . $link_url . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
} elseif ( Pass_Manager::pass_compare( $this->pass_manager->highest_pass_id, Pass_Manager::PERSONAL_PASS_ID, '=' ) ) {
|
||||
$utm_parameters = $this->query_args( 'personal-pass' );
|
||||
$link_url = $this->build_url(
|
||||
'https://easydigitaldownloads.com/your-account/',
|
||||
$utm_parameters
|
||||
);
|
||||
|
||||
// Personal pass active.
|
||||
printf(
|
||||
/* Translators: %1$s opening anchor tag; %2$s closing anchor tag */
|
||||
__( 'You are using Easy Digital Downloads with a Personal Pass. Consider %1$supgrading%2$s to get recurring payments and more.', 'easy-digital-downloads' ),
|
||||
'<a href="' . $link_url . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
} elseif ( Pass_Manager::pass_compare( $this->pass_manager->highest_pass_id, Pass_Manager::EXTENDED_PASS_ID, '>=' ) ) {
|
||||
if ( ! $this->has_affiliate_wp_license() ) {
|
||||
$link_url = edd_link_helper(
|
||||
'https://affiliatewp.com',
|
||||
array(
|
||||
'utm_medium' => 'top-promo',
|
||||
'utm_content' => 'affiliate-wp',
|
||||
)
|
||||
);
|
||||
|
||||
printf(
|
||||
/* Translators: %1$s opening anchor tag; %2$s closing anchor tag */
|
||||
__( 'Grow your business and make more money with affiliate marketing. %1$sGet AffiliateWP%2$s', 'easy-digital-downloads' ),
|
||||
'<a href="' . $link_url . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
} elseif( ! $this->has_mi_license() ) {
|
||||
printf(
|
||||
/* Translators: %1$s opening anchor tag; %2$s closing anchor tag */
|
||||
__( 'Gain access to powerful insights to grow your traffic and revenue. %1$sGet MonsterInsights%2$s', 'easy-digital-downloads' ),
|
||||
'<a href="' . esc_url( 'https://monsterinsights.com?utm_campaign=xsell&utm_source=eddplugin&utm_content=top-promo' ) . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch ( \Exception $e ) {
|
||||
// If we're in here, that means we have an invalid pass ID... what should we do? :thinking:.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the UTM parameters for the URLs.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @param string $upgrade_from License type upgraded from.
|
||||
* @param string $source Current page.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private function query_args( $upgrade_from, $source = '' ) {
|
||||
return array(
|
||||
'utm_medium' => 'top-promo',
|
||||
'utm_content' => 'upgrade-from-' . urlencode( $upgrade_from ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a link with UTM parameters
|
||||
*
|
||||
* @since 3.1
|
||||
*
|
||||
* @param string $url The Base URL.
|
||||
* @param array $utm_parameters The UTM tags for the URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function build_url( $url, $utm_parameters ) {
|
||||
return esc_url(
|
||||
edd_link_helper(
|
||||
$url,
|
||||
$utm_parameters
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
@ -28,6 +28,15 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
*/
|
||||
public $export_type = 'earnings_report';
|
||||
|
||||
/**
|
||||
* Refund amounts for partially refunded orders.
|
||||
* Stored separately from the main data as it's only required for the net columns.
|
||||
*
|
||||
* @since 3.1.0.5
|
||||
* @var array
|
||||
*/
|
||||
private $partial_refunds;
|
||||
|
||||
/**
|
||||
* Set the export headers.
|
||||
*
|
||||
@ -103,7 +112,7 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
unset( $statuses['pending'], $statuses['processing'], $statuses['preapproval'] );
|
||||
$supported_statuses = array_keys( $statuses );
|
||||
|
||||
return apply_filters( 'edd_export_earnings_supported_statuses', $supported_statuses );
|
||||
return array_unique( apply_filters( 'edd_export_earnings_supported_statuses', $supported_statuses ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,11 +197,9 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
}
|
||||
}
|
||||
|
||||
$supported_statuses = $this->get_supported_statuses();
|
||||
|
||||
$gross_count = 0;
|
||||
$gross_amount = 0;
|
||||
foreach ( $supported_statuses as $status ) {
|
||||
foreach ( edd_get_gross_order_statuses() as $status ) {
|
||||
$gross_count += absint( $data[ $status ]['count'] );
|
||||
$gross_amount += $data[ $status ]['amount'];
|
||||
}
|
||||
@ -212,7 +219,7 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
}
|
||||
|
||||
// Allows extensions with other 'completed' statuses to alter net earnings, like recurring.
|
||||
$completed_statuses = apply_filters( 'edd_export_earnings_completed_statuses', edd_get_complete_order_statuses() );
|
||||
$completed_statuses = array_unique( apply_filters( 'edd_export_earnings_completed_statuses', edd_get_net_order_statuses() ) );
|
||||
|
||||
$net_count = 0;
|
||||
$net_amount = 0;
|
||||
@ -223,6 +230,9 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
$net_count += absint( $data[ $status ]['count'] );
|
||||
$net_amount += floatval( $data[ $status ]['amount'] );
|
||||
}
|
||||
if ( ! empty( $this->partial_refunds ) ) {
|
||||
$net_amount += floatval( $this->partial_refunds['total'] );
|
||||
}
|
||||
$row_data .= $net_count . ',';
|
||||
$row_data .= '"' . edd_format_amount( $net_amount ) . '"';
|
||||
|
||||
@ -265,7 +275,8 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
$totals = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT SUM(total) AS total, COUNT(DISTINCT id) AS count, status
|
||||
FROM {$wpdb->edd_orders}
|
||||
WHERE date_created >= %s AND date_created <= %s
|
||||
WHERE type = 'sale'
|
||||
AND date_created >= %s AND date_created <= %s
|
||||
GROUP BY YEAR(date_created), MONTH(date_created), status
|
||||
ORDER by date_created ASC", $start_date, $end_date ), ARRAY_A );
|
||||
|
||||
@ -273,7 +284,7 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
foreach ( $totals as $row ) {
|
||||
$total_data[ $row['status'] ] = array(
|
||||
'count' => $row['count'],
|
||||
'amount' => floatval( $row['total'] )
|
||||
'amount' => floatval( $row['total'] ),
|
||||
);
|
||||
}
|
||||
|
||||
@ -290,7 +301,30 @@ class EDD_Batch_Earnings_Report_Export extends EDD_Batch_Export {
|
||||
'amount' => $total_data[ $status ]['amount'],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Get partial refund amounts to factor into net activity amounts.
|
||||
$partial_refunds = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT SUM(total) AS total, COUNT(DISTINCT id) AS count
|
||||
FROM {$wpdb->edd_orders}
|
||||
WHERE type = 'refund'
|
||||
AND parent IN (
|
||||
SELECT id
|
||||
FROM {$wpdb->edd_orders}
|
||||
WHERE status = 'partially_refunded'
|
||||
AND date_created >= %s
|
||||
AND date_created <= %s
|
||||
GROUP BY YEAR(date_created), MONTH(date_created)
|
||||
ORDER by date_created ASC
|
||||
);",
|
||||
$start_date,
|
||||
$end_date
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
if ( ! empty( $partial_refunds ) ) {
|
||||
$this->partial_refunds = reset( $partial_refunds );
|
||||
}
|
||||
|
||||
$data = apply_filters( 'edd_export_get_data', $data );
|
||||
|
@ -91,21 +91,21 @@ class EDD_Batch_Payments_Export extends EDD_Batch_Export {
|
||||
$data = array();
|
||||
|
||||
$args = array(
|
||||
'number' => 30,
|
||||
'offset' => ( $this->step * 30 ) - 30,
|
||||
'status' => $this->status,
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'date_created',
|
||||
'type' => 'sale',
|
||||
'status__not_in' => array( 'trash' ),
|
||||
'number' => 30,
|
||||
'offset' => ( $this->step * 30 ) - 30,
|
||||
'status' => $this->status,
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'date_created',
|
||||
'type' => 'sale',
|
||||
);
|
||||
|
||||
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
|
||||
$args['date_query'] = $this->get_date_query();
|
||||
}
|
||||
|
||||
if ( 'all' === $args['status'] ) {
|
||||
if ( in_array( $args['status'], array( 'any', 'all' ), true ) ) {
|
||||
unset( $args['status'] );
|
||||
$args['status__not_in'] = array( 'trash' );
|
||||
}
|
||||
|
||||
$orders = edd_get_orders( $args );
|
||||
@ -241,14 +241,15 @@ class EDD_Batch_Payments_Export extends EDD_Batch_Export {
|
||||
public function get_percentage_complete() {
|
||||
$args = array(
|
||||
'fields' => 'ids',
|
||||
'status' => $this->status,
|
||||
);
|
||||
|
||||
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
|
||||
$args['date_query'] = $this->get_date_query();
|
||||
}
|
||||
|
||||
if ( 'any' !== $this->status ) {
|
||||
$args['status'] = $this->status;
|
||||
if ( in_array( $args['status'], array( 'any', 'all' ), true ) ) {
|
||||
unset( $args['status'] );
|
||||
}
|
||||
|
||||
$total = edd_count_orders( $args );
|
||||
|
@ -35,13 +35,12 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
|
||||
* @return array $cols All the columns
|
||||
*/
|
||||
public function csv_cols() {
|
||||
$cols = array(
|
||||
'ID' => __( 'Log ID', 'easy-digital-downloads' ),
|
||||
return array(
|
||||
'ID' => __( 'Product ID', 'easy-digital-downloads' ),
|
||||
'user_id' => __( 'User', 'easy-digital-downloads' ),
|
||||
'customer_id' => __( 'Customer ID', 'easy-digital-downloads' ),
|
||||
'email' => __( 'Email', 'easy-digital-downloads' ),
|
||||
'first_name' => __( 'First Name', 'easy-digital-downloads' ),
|
||||
'last_name' => __( 'Last Name', 'easy-digital-downloads' ),
|
||||
'name' => __( 'Name', 'easy-digital-downloads' ),
|
||||
'download' => edd_get_label_singular(),
|
||||
'quantity' => __( 'Quantity', 'easy-digital-downloads' ),
|
||||
'amount' => __( 'Item Amount', 'easy-digital-downloads' ),
|
||||
@ -49,8 +48,6 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
|
||||
'price_id' => __( 'Price ID', 'easy-digital-downloads' ),
|
||||
'date' => __( 'Date', 'easy-digital-downloads' ),
|
||||
);
|
||||
|
||||
return $cols;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,29 +79,15 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
/** @var EDD\Orders\Order_Item $item */
|
||||
$order = edd_get_order( $item->order_id );
|
||||
$download = edd_get_download( $item->product_id );
|
||||
$user_info = $order->get_user_info();
|
||||
|
||||
$download_title = $item->product_name;
|
||||
|
||||
// Maybe append variable price name.
|
||||
if ( $download->has_variable_prices() ) {
|
||||
$price_option = edd_get_price_option_name( $item->product_id, $item->price_id, $order->id );
|
||||
|
||||
$download_title .= ! empty( $price_option )
|
||||
? ' - ' . $price_option
|
||||
: '';
|
||||
}
|
||||
$order = edd_get_order( $item->order_id );
|
||||
|
||||
$data[] = array(
|
||||
'ID' => $item->product_id,
|
||||
'user_id' => $order->user_id,
|
||||
'customer_id' => $order->customer_id,
|
||||
'email' => $order->email,
|
||||
'first_name' => isset( $user_info['first_name'] ) ? $user_info['first_name'] : '',
|
||||
'last_name' => isset( $user_info['last_name'] ) ? $user_info['last_name'] : '',
|
||||
'download' => $download_title,
|
||||
'name' => edd_get_customer_field( $order->customer_id, 'name' ),
|
||||
'download' => $item->product_name,
|
||||
'quantity' => $item->quantity,
|
||||
'amount' => $order->total,
|
||||
'payment_id' => $order->id,
|
||||
@ -129,9 +112,7 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
|
||||
* @return int
|
||||
*/
|
||||
public function get_percentage_complete() {
|
||||
$args = array(
|
||||
'fields' => 'ids',
|
||||
);
|
||||
$args = array();
|
||||
|
||||
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
|
||||
$args['date_query'] = $this->get_date_query();
|
||||
@ -141,7 +122,7 @@ class EDD_Batch_Sales_Export extends EDD_Batch_Export {
|
||||
$args['product_id'] = $this->download_id;
|
||||
}
|
||||
|
||||
$total = edd_count_order_items( $args );
|
||||
$total = edd_count_order_items( $args );
|
||||
$percentage = 100;
|
||||
|
||||
if ( $total > 0 ) {
|
||||
|
@ -90,20 +90,20 @@ class EDD_Batch_Taxed_Orders_Export extends EDD_Batch_Export {
|
||||
$data = array();
|
||||
|
||||
$args = array(
|
||||
'number' => 30,
|
||||
'offset' => ( $this->step * 30 ) - 30,
|
||||
'status' => $this->status,
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'date_created',
|
||||
'status__not_in' => array( 'trash' ),
|
||||
'number' => 30,
|
||||
'offset' => ( $this->step * 30 ) - 30,
|
||||
'status' => $this->status,
|
||||
'order' => 'ASC',
|
||||
'orderby' => 'date_created',
|
||||
);
|
||||
|
||||
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
|
||||
$args['date_created_query'] = $this->get_date_query();
|
||||
}
|
||||
|
||||
if ( 'any' === $args['status'] || 'all' === $args['status'] ) {
|
||||
if ( in_array( $args['status'], array( 'any', 'all' ), true ) ) {
|
||||
unset( $args['status'] );
|
||||
$args['status__not_in'] = array( 'trash' );
|
||||
}
|
||||
|
||||
add_filter( 'edd_orders_query_clauses', array( $this, 'query_clauses' ), 10, 2 );
|
||||
@ -236,14 +236,15 @@ class EDD_Batch_Taxed_Orders_Export extends EDD_Batch_Export {
|
||||
public function get_percentage_complete() {
|
||||
$args = array(
|
||||
'fields' => 'ids',
|
||||
'status' => $this->status,
|
||||
);
|
||||
|
||||
if ( ! empty( $this->start ) || ! empty( $this->end ) ) {
|
||||
$args['date_created_query'] = $this->get_date_query();
|
||||
}
|
||||
|
||||
if ( 'any' !== $this->status ) {
|
||||
$args['status'] = $this->status;
|
||||
if ( in_array( $args['status'], array( 'any', 'all' ), true ) ) {
|
||||
unset( $args['status'] );
|
||||
}
|
||||
|
||||
$total = edd_count_orders( $args );
|
||||
|
@ -35,7 +35,7 @@ function edd_overview_sales_earnings_chart() {
|
||||
}
|
||||
|
||||
$sql_clauses = array(
|
||||
'select' => 'date_created AS date',
|
||||
'select' => 'DATE_FORMAT(date_created, "%%Y-%%m") AS date',
|
||||
'where' => '',
|
||||
'groupby' => '',
|
||||
);
|
||||
@ -48,9 +48,11 @@ function edd_overview_sales_earnings_chart() {
|
||||
if ( $hour_by_hour ) {
|
||||
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'HOUR', 'date_created' );
|
||||
$sql_clauses['orderby'] = 'HOUR(date_created)';
|
||||
$sql_clauses['select'] = 'DATE_FORMAT(date_created, "%%Y-%%m-%%d %%H:00:00") AS date';
|
||||
} elseif ( $day_by_day ) {
|
||||
$sql_clauses['groupby'] = Reports\get_groupby_date_string( 'DATE', 'date_created' );
|
||||
$sql_clauses['orderby'] = 'DATE(date_created)';
|
||||
$sql_clauses['select'] = 'DATE_FORMAT(date_created, "%%Y-%%m-%%d") AS date';
|
||||
}
|
||||
|
||||
if ( ! empty( $currency ) && array_key_exists( strtoupper( $currency ), edd_get_currencies() ) ) {
|
||||
@ -117,10 +119,11 @@ function edd_overview_sales_earnings_chart() {
|
||||
|
||||
// Loop through each date there were sales/earnings, which we queried from the database.
|
||||
foreach ( $earnings_results as $earnings_result ) {
|
||||
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $earnings_result->date ) );
|
||||
$date_of_db_value = EDD()->utils->date( $earnings_result->date );
|
||||
|
||||
// Add any sales/earnings that happened during this hour.
|
||||
if ( $hour_by_hour ) {
|
||||
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
|
||||
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
||||
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
|
||||
$earnings[ $timestamp ][1] += $earnings_result->earnings;
|
||||
@ -142,10 +145,11 @@ function edd_overview_sales_earnings_chart() {
|
||||
|
||||
// Loop through each date there were sales/earnings, which we queried from the database.
|
||||
foreach ( $sales_results as $sales_result ) {
|
||||
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $sales_result->date ) );
|
||||
$date_of_db_value = EDD()->utils->date( $sales_result->date );
|
||||
|
||||
// Add any sales/earnings that happened during this hour.
|
||||
if ( $hour_by_hour ) {
|
||||
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
|
||||
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
||||
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
|
||||
$sales[ $timestamp ][1] += $sales_result->sales;
|
||||
@ -175,8 +179,6 @@ function edd_overview_sales_earnings_chart() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return array(
|
||||
'sales' => array_values( $sales ),
|
||||
'earnings' => array_values( $earnings ),
|
||||
@ -254,10 +256,11 @@ function edd_overview_refunds_chart() {
|
||||
|
||||
// Loop through each date there were refunds, which we queried from the database.
|
||||
foreach ( $results as $result ) {
|
||||
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $result->date ) );
|
||||
$date_of_db_value = EDD()->utils->date( $result->date );
|
||||
|
||||
// Add any refunds that happened during this hour.
|
||||
if ( $hour_by_hour ) {
|
||||
$date_of_db_value = edd_get_edd_timezone_equivalent_date_from_utc( $date_of_db_value );
|
||||
// If the date of this db value matches the date on this line graph/chart, set the y axis value for the chart to the number in the DB result.
|
||||
if ( $date_of_db_value->format( 'Y-m-d H' ) === $date_on_chart->format( 'Y-m-d H' ) ) {
|
||||
$number[ $timestamp ][1] += $result->number;
|
||||
|
@ -306,8 +306,9 @@ function edd_register_overview_report( $reports ) {
|
||||
'data_callback' => function () use ( $dates ) {
|
||||
$stats = new EDD\Stats();
|
||||
return $stats->get_customer_count( array(
|
||||
'range' => $dates['range'],
|
||||
'relative' => true,
|
||||
'range' => $dates['range'],
|
||||
'relative' => true,
|
||||
'purchase_count' => true,
|
||||
) );
|
||||
},
|
||||
'display_args' => array(
|
||||
@ -2569,8 +2570,9 @@ function edd_register_customer_report( $reports ) {
|
||||
'data_callback' => function () use ( $dates ) {
|
||||
$stats = new EDD\Stats();
|
||||
return $stats->get_customer_count( array(
|
||||
'range' => $dates['range'],
|
||||
'relative' => true,
|
||||
'range' => $dates['range'],
|
||||
'relative' => true,
|
||||
'purchase_count' => true,
|
||||
) );
|
||||
},
|
||||
'display_args' => array(
|
||||
@ -2663,11 +2665,13 @@ function edd_register_customer_report( $reports ) {
|
||||
|
||||
$results = $wpdb->get_results( $wpdb->prepare(
|
||||
"SELECT COUNT(c.id) AS total, {$sql_clauses['select']}
|
||||
FROM {$wpdb->edd_customers} c
|
||||
WHERE c.date_created >= %s AND c.date_created <= %s
|
||||
GROUP BY {$sql_clauses['groupby']}
|
||||
ORDER BY {$sql_clauses['orderby']} ASC",
|
||||
$dates['start']->copy()->format( 'mysql' ), $dates['end']->copy()->format( 'mysql' ) ) );
|
||||
FROM {$wpdb->edd_customers} c
|
||||
WHERE c.date_created >= %s AND c.date_created <= %s
|
||||
AND c.purchase_count > 0
|
||||
GROUP BY {$sql_clauses['groupby']}
|
||||
ORDER BY {$sql_clauses['orderby']} ASC",
|
||||
$dates['start']->copy()->format( 'mysql' ),
|
||||
$dates['end']->copy()->format( 'mysql' ) ) );
|
||||
|
||||
$customers = array();
|
||||
|
||||
@ -2785,470 +2789,31 @@ add_action( 'edd_reports_init', 'edd_register_export_report' );
|
||||
* @since 3.0
|
||||
*/
|
||||
function display_export_report() {
|
||||
global $wpdb;
|
||||
|
||||
wp_enqueue_script( 'edd-admin-tools-export' );
|
||||
?>
|
||||
<div id="edd-dashboard-widgets-wrap">
|
||||
<div class="metabox-holder">
|
||||
<div id="post-body">
|
||||
<div id="post-body-content" class="edd-reports-export edd-admin--has-grid">
|
||||
|
||||
<?php do_action( 'edd_reports_tab_export_content_top' ); ?>
|
||||
|
||||
<div class="postbox edd-export-earnings-report">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Earnings Report', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV giving a detailed look into earnings over time.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-earnings-report" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-to-and-from-container">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Earnings Start', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd_export_earnings_start_month" class="screen-reader-text"><?php esc_html_e( 'Select start month', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->month_dropdown( 'start_month', 0, 'edd_export_earnings', true ); ?>
|
||||
<label for="edd_export_earnings_start_year" class="screen-reader-text"><?php esc_html_e( 'Select start year', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->year_dropdown( 'start_year', 0, 5, 0, 'edd_export_earnings' ); ?>
|
||||
</fieldset>
|
||||
|
||||
<span class="edd-to-and-from--separator"><?php echo _x( '— to —', 'Date one to date two', 'easy-digital-downloads' ); ?></span>
|
||||
|
||||
<fieldset class="edd-to-and-from-container">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Earnings End', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd_export_earnings_end_month" class="screen-reader-text"><?php esc_html_e( 'Select end month', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->month_dropdown( 'end_month', 0, 'edd_export_earnings', true ); ?>
|
||||
<label for="edd_export_earnings_end_year" class="screen-reader-text"><?php esc_html_e( 'Select end year', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->year_dropdown( 'end_year', 0, 5, 0, 'edd_export_earnings' ); ?>
|
||||
</fieldset>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Earnings_Report_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-sales-earnings">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Sales and Earnings', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all sales or earnings on a day-by-day basis.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-sales-earnings" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Sales and Earnings Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-order-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-order-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'order-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-order-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-order-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'order-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_orders_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_orders_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_order_export_customer" class="screen-reader-text"><?php esc_html_e( 'Select Customer', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->customer_dropdown(
|
||||
array(
|
||||
'name' => 'customer_id',
|
||||
'id' => 'edd_order_export_customer',
|
||||
'chosen' => true,
|
||||
'none_selected' => '',
|
||||
'placeholder' => __( 'All Customers', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Sales_And_Earnings_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Export', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-orders">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Orders', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all orders.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-orders" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Order Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-orders-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-orders-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'orders-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-orders-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-orders-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'orders-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_orders_export_status" class="screen-reader-text"><?php esc_html_e( 'Select Status', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->select(
|
||||
array(
|
||||
'id' => 'edd_orders_export_status',
|
||||
'name' => 'status',
|
||||
'show_option_all' => __( 'All Statuses', 'easy-digital-downloads' ),
|
||||
'show_option_none' => false,
|
||||
'selected' => false,
|
||||
'options' => edd_get_payment_statuses(),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Payments_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-taxed-orders">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Taxed Orders', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all orders, taxed by Country and/or Region.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-taxed-orders" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Taxed Order Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-taxed-orders-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-orders-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'taxed-orders-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-taxed-orders-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-orders-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'taxed-orders-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_taxed_orders_export_status" class="screen-reader-text"><?php esc_html_e( 'Select Status', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->select(
|
||||
array(
|
||||
'id' => 'edd_taxed_orders_export_status',
|
||||
'name' => 'status',
|
||||
'show_option_all' => __( 'All Statuses', 'easy-digital-downloads' ),
|
||||
'show_option_none' => false,
|
||||
'selected' => false,
|
||||
'options' => edd_get_payment_statuses(),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_reports_filter_taxed_countries" class="screen-reader-text"><?php esc_html_e( 'Select Country', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->country_select(
|
||||
array(
|
||||
'name' => 'country',
|
||||
'id' => 'edd_reports_filter_taxed_countries',
|
||||
'selected' => false,
|
||||
'show_option_all' => false,
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_reports_filter_regions" class="screen-reader-text"><?php esc_html_e( 'Select Region', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->region_select(
|
||||
array(
|
||||
'id' => 'edd_reports_filter_regions',
|
||||
'placeholder' => __( 'All Regions', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Taxed_Orders_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-customers">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Customers', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php printf( esc_html__( 'Download a CSV of customers. Select a taxonomy to see all the customers who purchased %s in that taxonomy.', 'easy-digital-downloads' ), edd_get_label_plural( true ) ); ?></p>
|
||||
<form id="edd-export-customers" class="edd-export-form edd-import-export-form" method="post">
|
||||
<?php
|
||||
$taxonomies = edd_get_download_taxonomies();
|
||||
$taxonomies = array_map( 'sanitize_text_field', $taxonomies );
|
||||
|
||||
$placeholders = implode( ', ', array_fill( 0, count( $taxonomies ), '%s' ) );
|
||||
|
||||
$taxonomy__in = $wpdb->prepare( "tt.taxonomy IN ({$placeholders})", $taxonomies );
|
||||
|
||||
$sql = "SELECT t.*, tt.*, tr.object_id
|
||||
FROM {$wpdb->terms} AS t
|
||||
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
|
||||
INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id
|
||||
WHERE {$taxonomy__in}";
|
||||
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
$taxonomies = array();
|
||||
|
||||
if ( $results ) {
|
||||
foreach ( $results as $r ) {
|
||||
$t = get_taxonomy( $r->taxonomy );
|
||||
$taxonomies[ absint( $r->term_id ) ] = $t->labels->singular_name . ': ' . esc_html( $r->name );
|
||||
}
|
||||
}
|
||||
?>
|
||||
<label for="edd_export_taxonomy" class="screen-reader-text"><?php esc_html_e( 'Select Taxonomy', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->select(
|
||||
array(
|
||||
'name' => 'taxonomy',
|
||||
'id' => 'edd_export_taxonomy',
|
||||
'options' => $taxonomies,
|
||||
'selected' => false,
|
||||
'show_option_none' => false,
|
||||
'show_option_all' => __( 'All Taxonomies', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_customer_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download',
|
||||
'id' => 'edd_customer_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Customers_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-taxed-customers">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Taxed Customers', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all customers that were taxed.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-taxed-customers" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Taxed Customer Dates', 'easy-digital-downloads' ); ?></legend>
|
||||
<label for="edd-taxed-customers-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-customers-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'taxed-customers-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-taxed-customers-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-customers-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'taxed-customers-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<?php
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Taxed_Customers_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-downloads">
|
||||
<h2 class="hndle"><span><?php esc_html_e(
|
||||
/* translators: the singular post type label */
|
||||
sprintf( __( 'Export %s Products', 'easy-digital-downloads' ), edd_get_label_singular() ) ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e(
|
||||
/* translators: the plural post type label */
|
||||
sprintf( __( 'Download a CSV of product %1$s.', 'easy-digital-downloads' ), edd_get_label_plural( true ) ) ); ?></p>
|
||||
<form id="edd-export-downloads" class="edd-export-form edd-import-export-form" method="post">
|
||||
<label for="edd_download_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_download_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Downloads_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-api-requests">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export API Request Logs', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of API request logs.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-api-requests" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export API Request Log Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-api-requests-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-api-requests-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'api-requests-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-api-requests-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-api-requests-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'api-requests-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
</fieldset>
|
||||
<?php
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_API_Requests_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="postbox edd-export-download-history">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export File Download Logs', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of file download logs.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-download-history" class="edd-export-form edd-import-export-form" method="post">
|
||||
<label for="edd_file_download_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_file_download_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export File Download Log Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-file-download-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-file-download-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'file-download-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-file-download-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-file-download-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'file-download-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
</fieldset>
|
||||
<?php
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_File_Downloads_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php do_action( 'edd_reports_tab_export_content_bottom' ); ?>
|
||||
<?php
|
||||
do_action( 'edd_reports_tab_export_content_top' );
|
||||
$views = array(
|
||||
'earnings-report',
|
||||
'sales-earnings',
|
||||
'sales',
|
||||
'orders',
|
||||
'taxed-orders',
|
||||
'customers',
|
||||
'taxed-customers',
|
||||
'downloads',
|
||||
'api-requests',
|
||||
'download-history',
|
||||
);
|
||||
foreach ( $views as $view ) {
|
||||
include "views/export-{$view}.php";
|
||||
}
|
||||
do_action( 'edd_reports_tab_export_content_bottom' );
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -0,0 +1,38 @@
|
||||
<div class="postbox edd-export-api-requests">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export API Request Logs', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of API request logs.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-api-requests" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export API Request Log Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-api-requests-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-api-requests-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'api-requests-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-api-requests-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-api-requests-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'api-requests-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_API_Requests_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,63 @@
|
||||
<div class="postbox edd-export-customers">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Customers', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php printf( esc_html__( 'Download a CSV of customers. Select a taxonomy to see all the customers who purchased %s in that taxonomy.', 'easy-digital-downloads' ), edd_get_label_plural( true ) ); ?></p>
|
||||
<form id="edd-export-customers" class="edd-export-form edd-import-export-form" method="post">
|
||||
<?php
|
||||
global $wpdb;
|
||||
$taxonomies = edd_get_download_taxonomies();
|
||||
$taxonomies = array_map( 'sanitize_text_field', $taxonomies );
|
||||
|
||||
$placeholders = implode( ', ', array_fill( 0, count( $taxonomies ), '%s' ) );
|
||||
|
||||
$taxonomy__in = $wpdb->prepare( "tt.taxonomy IN ({$placeholders})", $taxonomies );
|
||||
|
||||
$sql = "SELECT t.*, tt.*, tr.object_id
|
||||
FROM {$wpdb->terms} AS t
|
||||
INNER JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id
|
||||
INNER JOIN {$wpdb->term_relationships} AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id
|
||||
WHERE {$taxonomy__in}";
|
||||
|
||||
$results = $wpdb->get_results( $sql );
|
||||
|
||||
$taxonomies = array();
|
||||
|
||||
if ( $results ) {
|
||||
foreach ( $results as $r ) {
|
||||
$t = get_taxonomy( $r->taxonomy );
|
||||
$taxonomies[ absint( $r->term_id ) ] = $t->labels->singular_name . ': ' . esc_html( $r->name );
|
||||
}
|
||||
}
|
||||
?>
|
||||
<label for="edd_export_taxonomy" class="screen-reader-text"><?php esc_html_e( 'Select Taxonomy', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->select(
|
||||
array(
|
||||
'name' => 'taxonomy',
|
||||
'id' => 'edd_export_taxonomy',
|
||||
'options' => $taxonomies,
|
||||
'selected' => false,
|
||||
'show_option_none' => false,
|
||||
'show_option_all' => __( 'All Taxonomies', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_customer_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download',
|
||||
'id' => 'edd_customer_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Customers_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,49 @@
|
||||
<div class="postbox edd-export-download-history">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export File Download Logs', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of file download logs.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-download-history" class="edd-export-form edd-import-export-form" method="post">
|
||||
<label for="edd_file_download_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_file_download_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export File Download Log Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-file-download-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-file-download-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'file-download-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-file-download-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-file-download-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'file-download-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_File_Downloads_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,26 @@
|
||||
<div class="postbox edd-export-downloads">
|
||||
<h2 class="hndle"><span><?php esc_html_e(
|
||||
/* translators: the singular post type label */
|
||||
sprintf( __( 'Export %s Products', 'easy-digital-downloads' ), edd_get_label_singular() ) ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e(
|
||||
/* translators: the plural post type label */
|
||||
sprintf( __( 'Download a CSV of product %1$s.', 'easy-digital-downloads' ), edd_get_label_plural( true ) ) ); ?></p>
|
||||
<form id="edd-export-downloads" class="edd-export-form edd-import-export-form" method="post">
|
||||
<label for="edd_download_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_download_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Downloads_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,32 @@
|
||||
<div class="postbox edd-export-earnings-report">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Earnings Report', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV giving a detailed look into earnings over time.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-earnings-report" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-to-and-from-container">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Earnings Start', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd_export_earnings_start_month" class="screen-reader-text"><?php esc_html_e( 'Select start month', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->month_dropdown( 'start_month', 0, 'edd_export_earnings', true ); ?>
|
||||
<label for="edd_export_earnings_start_year" class="screen-reader-text"><?php esc_html_e( 'Select start year', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->year_dropdown( 'start_year', 0, 5, 0, 'edd_export_earnings' ); ?>
|
||||
</fieldset>
|
||||
|
||||
<span class="edd-to-and-from--separator"><?php echo _x( '— to —', 'Date one to date two', 'easy-digital-downloads' ); ?></span>
|
||||
|
||||
<fieldset class="edd-to-and-from-container">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Earnings End', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd_export_earnings_end_month" class="screen-reader-text"><?php esc_html_e( 'Select end month', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->month_dropdown( 'end_month', 0, 'edd_export_earnings', true ); ?>
|
||||
<label for="edd_export_earnings_end_year" class="screen-reader-text"><?php esc_html_e( 'Select end year', 'easy-digital-downloads' ); ?></label>
|
||||
<?php echo EDD()->html->year_dropdown( 'end_year', 0, 5, 0, 'edd_export_earnings' ); ?>
|
||||
</fieldset>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Earnings_Report_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,52 @@
|
||||
<div class="postbox edd-export-orders">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Orders', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all orders.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-orders" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Order Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-orders-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-orders-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'orders-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-orders-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-orders-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'orders-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_orders_export_status" class="screen-reader-text"><?php esc_html_e( 'Select Status', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->select(
|
||||
array(
|
||||
'id' => 'edd_orders_export_status',
|
||||
'name' => 'status',
|
||||
'show_option_all' => __( 'All Statuses', 'easy-digital-downloads' ),
|
||||
'show_option_none' => false,
|
||||
'selected' => false,
|
||||
'options' => edd_get_payment_statuses(),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Payments_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,64 @@
|
||||
<div class="postbox edd-export-sales-earnings">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Sales and Earnings', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all sales or earnings on a day-by-day basis.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-sales-earnings" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Sales and Earnings Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-order-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-order-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'order-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-order-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-order-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'order-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_orders_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_orders_export_download',
|
||||
'chosen' => true,
|
||||
/* translators: the plural post type label */
|
||||
'placeholder' => sprintf( __( 'All %s', 'easy-digital-downloads' ), edd_get_label_plural() ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_order_export_customer" class="screen-reader-text"><?php esc_html_e( 'Select Customer', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->customer_dropdown(
|
||||
array(
|
||||
'name' => 'customer_id',
|
||||
'id' => 'edd_order_export_customer',
|
||||
'chosen' => true,
|
||||
'none_selected' => '',
|
||||
'placeholder' => __( 'All Customers', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Sales_And_Earnings_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Export', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,49 @@
|
||||
<div class="postbox edd-export-payment-history">
|
||||
<h2 class="hndle"><?php esc_html_e( 'Export Product Sales', 'easy-digital-downloads' ); ?></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV file containing a record of each sale of a product along with the customer information.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-sales" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Sales Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-sales-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-sales-export-start',
|
||||
'class' => 'edd-sales-export-start',
|
||||
'name' => 'sales-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-sales-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-sales-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'sales-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_sales_export_download" class="screen-reader-text"><?php esc_html_e( 'Select Download', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->product_dropdown(
|
||||
array(
|
||||
'name' => 'download_id',
|
||||
'id' => 'edd_sales_export_download',
|
||||
'chosen' => true,
|
||||
)
|
||||
);
|
||||
?>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Sales_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,37 @@
|
||||
<div class="postbox edd-export-taxed-customers">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Taxed Customers', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all customers that were taxed.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-taxed-customers" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Taxed Customer Dates', 'easy-digital-downloads' ); ?></legend>
|
||||
<label for="edd-taxed-customers-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-customers-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'taxed-customers-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-taxed-customers-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-customers-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'taxed-customers-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<?php wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' ); ?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Taxed_Customers_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -0,0 +1,72 @@
|
||||
<div class="postbox edd-export-taxed-orders">
|
||||
<h2 class="hndle"><span><?php esc_html_e( 'Export Taxed Orders', 'easy-digital-downloads' ); ?></span></h2>
|
||||
<div class="inside">
|
||||
<p><?php esc_html_e( 'Download a CSV of all orders, taxed by Country and/or Region.', 'easy-digital-downloads' ); ?></p>
|
||||
<form id="edd-export-taxed-orders" class="edd-export-form edd-import-export-form" method="post">
|
||||
<fieldset class="edd-from-to-wrapper">
|
||||
<legend class="screen-reader-text">
|
||||
<?php esc_html_e( 'Export Taxed Order Dates', 'easy-digital-downloads' ); ?>
|
||||
</legend>
|
||||
<label for="edd-taxed-orders-export-start" class="screen-reader-text"><?php esc_html_e( 'Set start date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-orders-export-start',
|
||||
'class' => 'edd-export-start',
|
||||
'name' => 'taxed-orders-export-start',
|
||||
'placeholder' => _x( 'From', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd-taxed-orders-export-end" class="screen-reader-text"><?php esc_html_e( 'Set end date', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->date_field(
|
||||
array(
|
||||
'id' => 'edd-taxed-orders-export-end',
|
||||
'class' => 'edd-export-end',
|
||||
'name' => 'taxed-orders-export-end',
|
||||
'placeholder' => _x( 'To', 'date filter', 'easy-digital-downloads' )
|
||||
)
|
||||
);
|
||||
?>
|
||||
</fieldset>
|
||||
<label for="edd_taxed_orders_export_status" class="screen-reader-text"><?php esc_html_e( 'Select Status', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->select(
|
||||
array(
|
||||
'id' => 'edd_taxed_orders_export_status',
|
||||
'name' => 'status',
|
||||
'show_option_all' => __( 'All Statuses', 'easy-digital-downloads' ),
|
||||
'show_option_none' => false,
|
||||
'selected' => false,
|
||||
'options' => edd_get_payment_statuses(),
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_reports_filter_taxed_countries" class="screen-reader-text"><?php esc_html_e( 'Select Country', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->country_select(
|
||||
array(
|
||||
'name' => 'country',
|
||||
'id' => 'edd_reports_filter_taxed_countries',
|
||||
'selected' => false,
|
||||
'show_option_all' => false,
|
||||
)
|
||||
);
|
||||
?>
|
||||
<label for="edd_reports_filter_regions" class="screen-reader-text"><?php esc_html_e( 'Select Region', 'easy-digital-downloads' ); ?></label>
|
||||
<?php
|
||||
echo EDD()->html->region_select(
|
||||
array(
|
||||
'id' => 'edd_reports_filter_regions',
|
||||
'placeholder' => __( 'All Regions', 'easy-digital-downloads' ),
|
||||
)
|
||||
);
|
||||
|
||||
wp_nonce_field( 'edd_ajax_export', 'edd_ajax_export' );
|
||||
?>
|
||||
<input type="hidden" name="edd-export-class" value="EDD_Batch_Taxed_Orders_Export"/>
|
||||
<button type="submit" class="button button-secondary"><?php esc_html_e( 'Generate CSV', 'easy-digital-downloads' ); ?></button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
@ -25,7 +25,7 @@ function edd_admin_header() {
|
||||
$current_page = ! empty( $_GET['page'] ) ? $_GET['page'] : '';
|
||||
$is_single_view = (bool) apply_filters( 'edd_admin_is_single_view', ! empty( $_GET['view'] ) );
|
||||
|
||||
$page_title = '';
|
||||
$page_title = __( 'Downloads', 'easy-digital-downloads' );
|
||||
switch( $current_page ) {
|
||||
case 'edd-settings':
|
||||
$page_title = __( 'Settings', 'easy-digital-downloads' );
|
||||
@ -45,18 +45,19 @@ function edd_admin_header() {
|
||||
case 'edd-tools':
|
||||
$page_title = __( 'Tools', 'easy-digital-downloads' );
|
||||
break;
|
||||
case 'edd-addons':
|
||||
$page_title = __( 'View Extensions', 'easy-digital-downloads' );
|
||||
if ( edd_is_pro() ) {
|
||||
$page_title = __( 'Manage Extensions', 'easy-digital-downloads' );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if ( ! empty( $_GET['page'] ) ) {
|
||||
$page_title = ucfirst( str_replace( array( 'edd-', 'fes-' ), '', $current_page ) );
|
||||
} else {
|
||||
if ( ! empty( $_GET['post_type'] ) ) {
|
||||
$post_type = get_post_type_object( $_GET['post_type'] );
|
||||
$page_title = $post_type->labels->name;
|
||||
} else {
|
||||
$page_title = __( 'Downloads', 'easy-digital-downloads' );
|
||||
}
|
||||
} elseif ( ! empty( $_GET['post_type'] ) ) {
|
||||
$post_type = get_post_type_object( $_GET['post_type'] );
|
||||
$page_title = $post_type->labels->name;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -223,7 +224,11 @@ function edd_options_page_secondary_nav( $active_tab = '', $section = '', $secti
|
||||
|
||||
// Add to links array
|
||||
$links[ $section_id ] = '<li class="' . esc_attr( $class ) . '"><a class="' . esc_attr( $class ) . '" href="' . esc_url( $tab_url ) . '">' . esc_html( $section_name ) . '</a><li>';
|
||||
} ?>
|
||||
}
|
||||
if ( count( $links ) < 2 ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="wp-clearfix">
|
||||
<ul class="subsubsub edd-settings-sub-nav">
|
||||
|
@ -541,26 +541,6 @@ function edd_get_registered_settings() {
|
||||
'type' => 'descriptive_text',
|
||||
),
|
||||
),
|
||||
'tracking' => array(
|
||||
'tracking_settings' => array(
|
||||
'id' => 'tracking_settings',
|
||||
'name' => '<h3>' . __( 'Tracking', 'easy-digital-downloads' ) . '</h3>',
|
||||
'desc' => '',
|
||||
'type' => 'header',
|
||||
),
|
||||
'allow_tracking' => array(
|
||||
'id' => 'allow_tracking',
|
||||
'name' => __( 'Usage Tracking', 'easy-digital-downloads' ),
|
||||
'check' => __( 'Allow', 'easy-digital-downloads' ),
|
||||
'desc' => sprintf(
|
||||
/* translators: %1$s Link to tracking information, do not translate. %2$s Link to EDD newsleter, do not translate. %3$s Link to EDD extensions, do not translate */
|
||||
__( 'Help us make Easy Digital Downloads better. <a href="%1$s" target="_blank">Here is what we track</a>.<br>If you opt-in, we will email you a discount code to <a href="%2$s" target="_blank">upgrade to a pass</a>.', 'easy-digital-downloads' ),
|
||||
edd_link_helper( 'https://easydigitaldownloads.com/docs/what-information-will-be-tracked-by-opting-into-usage-tracking/', array( 'utm_medium' => 'telemetry', 'utm_content' => 'option' ) ),
|
||||
edd_link_helper( 'https://easydigitaldownloads.com/lite-upgrade/', array( 'utm_medium' => 'telemetry', 'utm_content' => 'option' ) )
|
||||
),
|
||||
'type' => 'checkbox_description',
|
||||
)
|
||||
),
|
||||
) ),
|
||||
|
||||
// Payment Gateways Settings
|
||||
@ -924,7 +904,7 @@ function edd_get_registered_settings() {
|
||||
'tax_help' => array(
|
||||
'id' => 'tax_help',
|
||||
'name' => '',
|
||||
'desc' => sprintf( __( 'Visit the <a href="%s" target="_blank">Tax setup documentation</a> for further information. <p class="description">If you need VAT support, there are options listed on the documentation page.</p>', 'easy-digital-downloads' ), 'https://docs.easydigitaldownloads.com/article/238-tax-settings' ),
|
||||
'desc' => sprintf( __( 'Visit the <a href="%s" target="_blank">Tax setup documentation</a> for further information. <p class="description">If you need VAT support, there are options listed on the documentation page.</p>', 'easy-digital-downloads' ), 'https://easydigitaldownloads.com/docs/tax-settings/' ),
|
||||
'type' => 'descriptive_text',
|
||||
),
|
||||
'prices_include_tax' => array(
|
||||
@ -1329,6 +1309,10 @@ function edd_settings_sanitize( $input = array() ) {
|
||||
$tab = ! empty( $referrer['tab'] ) ? sanitize_key( $referrer['tab'] ) : 'general';
|
||||
$section = ! empty( $referrer['section'] ) ? sanitize_key( $referrer['section'] ) : 'main';
|
||||
|
||||
if ( ! empty( $_POST['edd_tab_override'] ) ) {
|
||||
$tab = sanitize_text_field( $_POST['edd_tab_override'] );
|
||||
}
|
||||
|
||||
// Maybe override the tab section
|
||||
if ( ! empty( $_POST['edd_section_override'] ) ) {
|
||||
$section = sanitize_text_field( $_POST['edd_section_override'] );
|
||||
@ -1530,17 +1514,9 @@ function edd_settings_sanitize_misc_accounting( $input ) {
|
||||
return $input;
|
||||
}
|
||||
|
||||
if ( ! empty( $input['enable_sequential'] ) && ! edd_get_option( 'enable_sequential' ) ) {
|
||||
|
||||
// Shows an admin notice about upgrading previous order numbers
|
||||
update_option( 'edd_upgrade_sequential', time() );
|
||||
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
add_filter( 'edd_settings_gateways-accounting_sanitize', 'edd_settings_sanitize_misc_accounting' );
|
||||
// add_filter( 'edd_settings_gateways-accounting_sanitize', 'edd_settings_sanitize_misc_accounting' );
|
||||
|
||||
/**
|
||||
* Taxes Settings Sanitization
|
||||
@ -1778,7 +1754,6 @@ function edd_get_registered_settings_sections() {
|
||||
'currency' => __( 'Currency', 'easy-digital-downloads' ),
|
||||
'pages' => __( 'Pages', 'easy-digital-downloads' ),
|
||||
'api' => __( 'API', 'easy-digital-downloads' ),
|
||||
'tracking' => __( 'Tracking', 'easy-digital-downloads' )
|
||||
) ),
|
||||
'gateways' => apply_filters( 'edd_settings_sections_gateways', array(
|
||||
'main' => __( 'General', 'easy-digital-downloads' ),
|
||||
@ -1837,9 +1812,9 @@ function edd_get_registered_settings_sections() {
|
||||
*/
|
||||
function edd_get_pages( $force = false ) {
|
||||
|
||||
$pages_options = array( '' => '' ); // Blank option
|
||||
$pages_options = array( '' => __( 'None', 'easy-digital-downloads' ) );
|
||||
|
||||
if ( ( ! isset( $_GET['page'] ) || 'edd-settings' != $_GET['page'] ) && ! $force ) {
|
||||
if ( ( ! isset( $_GET['page'] ) || 'edd-settings' !== $_GET['page'] ) && ! $force ) {
|
||||
return $pages_options;
|
||||
}
|
||||
|
||||
@ -2634,8 +2609,10 @@ function edd_upload_callback( $args ) {
|
||||
$class = edd_sanitize_html_class( $args['field_class'] );
|
||||
|
||||
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
||||
$html = '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']" class="' . $class . '" name="edd_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
|
||||
$html .= '<span> <input type="button" data-uploader-title="' . esc_html__( 'Attach File', 'easy-digital-downloads' ) . '" data-uploader-button-text="' . esc_html__( 'Attach', 'easy-digital-downloads' ) . '" class="edd_settings_upload_button button-secondary" value="' . __( 'Attach File', 'easy-digital-downloads' ) . '"/></span>';
|
||||
$html = '<div class="edd-upload-button-wrapper">';
|
||||
$html .= '<input type="text" class="' . sanitize_html_class( $size ) . '-text" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']" class="' . $class . '" name="edd_settings[' . esc_attr( $args['id'] ) . ']" value="' . esc_attr( stripslashes( $value ) ) . '"/>';
|
||||
$html .= '<button data-input="#edd_settings\\[' . edd_sanitize_key( $args['id'] ) . '\\]" data-uploader-title="' . esc_html__( 'Attach File', 'easy-digital-downloads' ) . '" data-uploader-button-text="' . esc_html__( 'Attach', 'easy-digital-downloads' ) . '" class="edd_settings_upload_button button button-secondary">' . __( 'Attach File', 'easy-digital-downloads' ) . '</button>';
|
||||
$html .= '</div>';
|
||||
$html .= '<p class="description"> ' . wp_kses_post( $args['desc'] ) . '</p>';
|
||||
|
||||
echo apply_filters( 'edd_after_setting_output', $html, $args );
|
||||
@ -2856,217 +2833,16 @@ function edd_descriptive_text_callback( $args ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the license field callback for Software Licensing
|
||||
* Registers the license field callback for Software Licensing.
|
||||
*
|
||||
* @since 1.5
|
||||
*
|
||||
* @param array $args Arguments passed by the setting
|
||||
*
|
||||
* @since 3.1.1 Updated to use the extension licenses class.
|
||||
* @param array $args Arguments passed by the setting.
|
||||
* @return void
|
||||
*/
|
||||
if ( ! function_exists( 'edd_license_key_callback' ) ) {
|
||||
function edd_license_key_callback( $args ) {
|
||||
$edd_option = edd_get_option( $args['id'] );
|
||||
|
||||
$messages = array();
|
||||
$license = get_option( $args['options']['is_valid_license_option'] );
|
||||
|
||||
if ( $edd_option ) {
|
||||
$value = $edd_option;
|
||||
} else {
|
||||
$value = isset( $args['std'] )
|
||||
? $args['std']
|
||||
: '';
|
||||
}
|
||||
|
||||
if ( ! empty( $license ) && is_object( $license ) ) {
|
||||
$now = current_time( 'timestamp' );
|
||||
$expiration = ! empty( $license->expires )
|
||||
? strtotime( $license->expires, $now )
|
||||
: false;
|
||||
|
||||
// activate_license 'invalid' on anything other than valid, so if there was an error capture it
|
||||
if ( false === $license->success ) {
|
||||
|
||||
switch ( $license->error ) {
|
||||
|
||||
case 'expired' :
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/checkout/?edd_license_key=' . esc_attr( $value ),
|
||||
array(
|
||||
'utm_medium' => 'license-notice',
|
||||
'utm_content' => 'expired',
|
||||
)
|
||||
);
|
||||
$class = 'expired';
|
||||
$messages[] = sprintf(
|
||||
__( 'Your license key expired on %s. Please <a href="%s" target="_blank">renew your license key</a>.', 'easy-digital-downloads' ),
|
||||
edd_date_i18n( $expiration ),
|
||||
$url
|
||||
);
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
|
||||
break;
|
||||
|
||||
case 'revoked' :
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/support/',
|
||||
array(
|
||||
'utm_medium' => 'license-notice',
|
||||
'utm_content' => 'revoked',
|
||||
)
|
||||
);
|
||||
$class = 'error';
|
||||
$messages[] = sprintf(
|
||||
__( 'Your license key has been disabled. Please <a href="%s" target="_blank">contact support</a> for more information.', 'easy-digital-downloads' ),
|
||||
$url
|
||||
);
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
|
||||
break;
|
||||
|
||||
case 'missing' :
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/your-account/',
|
||||
array(
|
||||
'utm_medium' => 'license-notice',
|
||||
'utm_content' => 'missing',
|
||||
)
|
||||
);
|
||||
$class = 'error';
|
||||
$messages[] = sprintf(
|
||||
__( 'Invalid license. Please <a href="%s" target="_blank">visit your account page</a> and verify it.', 'easy-digital-downloads' ),
|
||||
$url
|
||||
);
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
|
||||
break;
|
||||
|
||||
case 'invalid' :
|
||||
case 'site_inactive' :
|
||||
$url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/your-account/',
|
||||
array(
|
||||
'utm_medium' => 'license-notice',
|
||||
'utm_content' => 'inactive',
|
||||
)
|
||||
);
|
||||
$class = 'error';
|
||||
$messages[] = sprintf(
|
||||
__( 'Your %s is not active for this URL. Please <a href="%s" target="_blank">visit your account page</a> to manage your license keys.', 'easy-digital-downloads' ),
|
||||
esc_html( $args['name'] ),
|
||||
$url
|
||||
);
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
|
||||
break;
|
||||
|
||||
case 'item_name_mismatch' :
|
||||
$class = 'error';
|
||||
$messages[] = sprintf( __( 'This appears to be an invalid license key for %s.', 'easy-digital-downloads' ), $args['name'] );
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
|
||||
break;
|
||||
|
||||
case 'no_activations_left':
|
||||
$class = 'error';
|
||||
$messages[] = sprintf( __( 'Your license key has reached its activation limit. <a href="%s">View possible upgrades</a> now.', 'easy-digital-downloads' ), 'https://easydigitaldownloads.com/your-account/' );
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
|
||||
break;
|
||||
|
||||
case 'license_not_activable':
|
||||
$class = 'error';
|
||||
$messages[] = __( 'The key you entered belongs to a bundle, please use the product specific license key.', 'easy-digital-downloads' );
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
break;
|
||||
|
||||
default :
|
||||
$class = 'error';
|
||||
$error = ! empty( $license->error ) ? $license->error : __( 'unknown_error', 'easy-digital-downloads' );
|
||||
$messages[] = sprintf( __( 'There was an error with this license key: %s. Please <a href="%s">contact our support team</a>.', 'easy-digital-downloads' ), $error, 'https://easydigitaldownloads.com/support' );
|
||||
|
||||
$license_status = 'license-' . $class . '-notice';
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
switch ( $license->license ) {
|
||||
|
||||
case 'valid' :
|
||||
default:
|
||||
|
||||
$class = 'valid';
|
||||
|
||||
if ( 'lifetime' === $license->expires ) {
|
||||
$messages[] = __( 'License key never expires.', 'easy-digital-downloads' );
|
||||
|
||||
$license_status = 'license-lifetime-notice';
|
||||
|
||||
} elseif ( ( $expiration > $now ) && ( $expiration - $now < ( DAY_IN_SECONDS * 30 ) ) ) {
|
||||
$messages[] = sprintf(
|
||||
__( 'Your license key expires soon! It expires on %s.', 'easy-digital-downloads' ),
|
||||
date_i18n( get_option( 'date_format' ), strtotime( $license->expires, current_time( 'timestamp' ) ) )
|
||||
);
|
||||
|
||||
$license_status = 'license-expires-soon-notice';
|
||||
|
||||
} else {
|
||||
$messages[] = sprintf(
|
||||
__( 'Your license key expires on %s.', 'easy-digital-downloads' ),
|
||||
edd_date_i18n( $expiration )
|
||||
);
|
||||
|
||||
$license_status = 'license-expiration-date-notice';
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$class = 'empty';
|
||||
|
||||
$messages[] = sprintf(
|
||||
__( 'To receive updates, please enter your valid %s license key.', 'easy-digital-downloads' ),
|
||||
$args['name']
|
||||
);
|
||||
|
||||
$license_status = null;
|
||||
}
|
||||
|
||||
$class .= ' ' . edd_sanitize_html_class( $args['field_class'] );
|
||||
|
||||
$size = ( isset( $args['size'] ) && ! is_null( $args['size'] ) ) ? $args['size'] : 'regular';
|
||||
$html = '<input type="password" autocomplete="off" class="' . sanitize_html_class( $size ) . '-text" id="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']" name="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']" value="' . sanitize_key( $value ) . '"/>';
|
||||
|
||||
if ( ( is_object( $license ) && ! empty( $license->license ) && 'valid' == $license->license ) || 'valid' == $license ) {
|
||||
$html .= '<input type="submit" class="button-secondary" name="' . $args['id'] . '_deactivate" value="' . __( 'Deactivate License', 'easy-digital-downloads' ) . '"/>';
|
||||
}
|
||||
|
||||
$html .= '<label for="edd_settings[' . edd_sanitize_key( $args['id'] ) . ']"> ' . wp_kses_post( $args['desc'] ) . '</label>';
|
||||
|
||||
if ( ! empty( $messages ) ) {
|
||||
foreach ( $messages as $message ) {
|
||||
|
||||
$html .= '<div class="edd-license-data edd-license-' . esc_attr( $class ) . ' ' . esc_attr( $license_status ) . '">';
|
||||
$html .= '<p>' . wp_kses_post( $message ) . '</p>';
|
||||
$html .= '</div>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
wp_nonce_field( edd_sanitize_key( $args['id'] ) . '-nonce', edd_sanitize_key( $args['id'] ) . '-nonce' );
|
||||
|
||||
echo $html;
|
||||
$settings_field = new EDD\Licensing\Settings( $args );
|
||||
}
|
||||
}
|
||||
|
||||
@ -3173,3 +2949,21 @@ function edd_is_test_mode_forced() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for an incorrect setting for the privacy policy.
|
||||
* Required in updating from EDD 2.9.2 to 2.9.3.
|
||||
*/
|
||||
add_filter( 'edd_get_option_show_privacy_policy_on_checkout', function( $value ) {
|
||||
if ( ! empty( $value ) ) {
|
||||
return $value;
|
||||
}
|
||||
$fix_show_privacy_policy_setting = edd_get_option( 'show_agree_to_privacy_policy_on_checkout', false );
|
||||
if ( ! empty( $fix_show_privacy_policy_setting ) ) {
|
||||
edd_update_option( 'show_privacy_policy_on_checkout', $fix_show_privacy_policy_setting );
|
||||
edd_delete_option( 'show_agree_to_privacy_policy_on_checkout' );
|
||||
|
||||
return $fix_show_privacy_policy_setting;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}, 10, 3 );
|
||||
|
@ -484,7 +484,7 @@ function edd_tools_import_export_display() {
|
||||
<?php
|
||||
printf(
|
||||
__( 'Each column loaded from the CSV needs to be mapped to an order field. Select the column that should be mapped to each field below. Any columns not needed can be ignored. See <a href="%s" target="_blank">this guide</a> for assistance with importing payment records.', 'easy-digital-downloads' ),
|
||||
'https://docs.easydigitaldownloads.com/category/1337-importexport'
|
||||
'https://easydigitaldownloads.com/docs/importing-exporting-orders/'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
@ -799,7 +799,7 @@ function edd_tools_import_export_display() {
|
||||
<?php
|
||||
printf(
|
||||
__( 'Each column loaded from the CSV needs to be mapped to a Download product field. Select the column that should be mapped to each field below. Any columns not needed can be ignored. See <a href="%s" target="_blank">this guide</a> for assistance with importing Download products.', 'easy-digital-downloads' ),
|
||||
'https://docs.easydigitaldownloads.com/category/1337-importexport'
|
||||
'https://easydigitaldownloads.com/docs/importing-exporting-products/'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
@ -1278,6 +1278,7 @@ function edd_tools_sysinfo_display() {
|
||||
<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;" ) );
|
||||
?>
|
||||
@ -1414,7 +1415,11 @@ function edd_tools_sysinfo_get() {
|
||||
// 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" );
|
||||
@ -1713,6 +1718,7 @@ 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();
|
||||
|
||||
|
@ -28,90 +28,49 @@ class EDD_Tracking {
|
||||
*/
|
||||
private $data;
|
||||
|
||||
/**
|
||||
* The server URL to receive the telemetry data.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $telemetry_server = 'https://telemetry.easydigitaldownloads.com/v1/checkin/';
|
||||
|
||||
/**
|
||||
* Get things going
|
||||
*
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// WordPress core actions.
|
||||
add_action( 'init', array( $this, 'schedule_send' ) );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notice' ) );
|
||||
add_action( 'init', array( $this, 'schedule_send' ) );
|
||||
add_action( 'admin_notices', array( $this, 'admin_notice' ) );
|
||||
|
||||
// Sanitize setting.
|
||||
add_action( 'edd_settings_general_sanitize', array( $this, 'check_for_settings_optin' ) );
|
||||
add_filter( 'edd_settings_misc', array( $this, 'register_setting' ), 50 );
|
||||
|
||||
// Handle opting in and out.
|
||||
add_action( 'edd_opt_into_tracking', array( $this, 'check_for_optin' ) );
|
||||
add_action( 'edd_opt_into_tracking', array( $this, 'check_for_optin' ) );
|
||||
add_action( 'edd_opt_out_of_tracking', array( $this, 'check_for_optout' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has opted into tracking
|
||||
* Check if the user has opted into tracking.
|
||||
*
|
||||
* @access private
|
||||
* @return bool
|
||||
*/
|
||||
private function tracking_allowed() {
|
||||
protected function tracking_allowed() {
|
||||
return (bool) edd_get_option( 'allow_tracking', false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the data that is going to be tracked
|
||||
* Setup the data that is going to be tracked.
|
||||
*
|
||||
* @access private
|
||||
* @return void
|
||||
*/
|
||||
private function setup_data() {
|
||||
$data = new EDD\Telemetry\Data();
|
||||
|
||||
// Retrieve current theme info.
|
||||
$theme_data = wp_get_theme();
|
||||
$theme = $theme_data->Name . ' ' . $theme_data->Version;
|
||||
$checkout_page = edd_get_option( 'purchase_page', false );
|
||||
$date = ( false !== $checkout_page )
|
||||
? get_post_field( 'post_date', $checkout_page )
|
||||
: 'not set';
|
||||
$server = isset( $_SERVER['SERVER_SOFTWARE'] )
|
||||
? $_SERVER['SERVER_SOFTWARE']
|
||||
: '';
|
||||
|
||||
// Setup data.
|
||||
$data = array(
|
||||
'php_version' => phpversion(),
|
||||
'edd_version' => EDD_VERSION,
|
||||
'wp_version' => get_bloginfo( 'version' ),
|
||||
'server' => $server,
|
||||
'install_date' => $date,
|
||||
'multisite' => is_multisite(),
|
||||
'url' => home_url(),
|
||||
'theme' => $theme,
|
||||
'email' => get_bloginfo( 'admin_email' )
|
||||
);
|
||||
|
||||
// Retrieve current plugin information.
|
||||
if ( ! function_exists( 'get_plugins' ) ) {
|
||||
include ABSPATH . '/wp-admin/includes/plugin.php';
|
||||
}
|
||||
|
||||
// Get plugins
|
||||
$plugins = array_keys( get_plugins() );
|
||||
$active_plugins = get_option( 'active_plugins', array() );
|
||||
|
||||
// Remove active plugins from list so we can show active and inactive separately.
|
||||
foreach ( $plugins as $key => $plugin ) {
|
||||
if ( in_array( $plugin, $active_plugins, true ) ) {
|
||||
unset( $plugins[ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
$data['active_plugins'] = $active_plugins;
|
||||
$data['inactive_plugins'] = $plugins;
|
||||
$data['active_gateways'] = array_keys( edd_get_enabled_payment_gateways() );
|
||||
$data['products'] = wp_count_posts( 'download' )->publish;
|
||||
$data['download_label'] = edd_get_label_singular( true );
|
||||
$data['locale'] = get_locale();
|
||||
|
||||
$this->data = $data;
|
||||
$this->data = $data->get();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,36 +85,30 @@ class EDD_Tracking {
|
||||
*/
|
||||
public function send_checkin( $override = false, $ignore_last_checkin = false ) {
|
||||
|
||||
$home_url = trailingslashit( home_url() );
|
||||
|
||||
// Allows us to stop our own site from checking in, and a filter for our additional sites.
|
||||
if ( $home_url === 'https://easydigitaldownloads.com/' || apply_filters( 'edd_disable_tracking_checkin', false ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->tracking_allowed() && ! $override ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a maximum of once per week.
|
||||
$last_send = $this->get_last_send();
|
||||
if ( is_numeric( $last_send ) && $last_send > strtotime( '-1 week' ) && ! $ignore_last_checkin ) {
|
||||
if ( ! $this->can_send_data( $override, $ignore_last_checkin ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->setup_data();
|
||||
|
||||
wp_remote_post( 'https://easydigitaldownloads.com/?edd_action=checkin', array(
|
||||
'method' => 'POST',
|
||||
'timeout' => 8,
|
||||
'redirection' => 5,
|
||||
'httpversion' => '1.1',
|
||||
'blocking' => false,
|
||||
'body' => $this->data,
|
||||
'user-agent' => 'EDD/' . EDD_VERSION . '; ' . get_bloginfo( 'url' )
|
||||
) );
|
||||
if ( empty( $this->data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
update_option( 'edd_tracking_last_send', time() );
|
||||
wp_remote_post(
|
||||
$this->telemetry_server,
|
||||
array(
|
||||
'method' => 'POST',
|
||||
'timeout' => 8,
|
||||
'redirection' => 5,
|
||||
'httpversion' => '1.1',
|
||||
'blocking' => false,
|
||||
'body' => $this->data,
|
||||
'user-agent' => 'EDD/' . EDD_VERSION . '; ' . $this->data['id'],
|
||||
)
|
||||
);
|
||||
|
||||
update_option( 'edd_tracking_last_send', time(), false );
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -177,6 +130,27 @@ class EDD_Tracking {
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the tracking setting to the miscellaneous settings section.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
public function register_setting( $settings ) {
|
||||
$hidden = edd_get_option( 'allow_tracking', false ) ? '' : 'edd-hidden';
|
||||
|
||||
$settings['main']['allow_tracking'] = array(
|
||||
'id' => 'allow_tracking',
|
||||
'name' => __( 'Join the EDD Community', 'easy-digital-downloads' ),
|
||||
'check' => __( 'Yes, I want to help!', 'easy-digital-downloads' ) . ' <span class="allow_tracking edd-heart ' . $hidden . '"><img src="' . esc_url( EDD_PLUGIN_URL . 'assets/images/icons/icon-edd-heart.svg' ) . '" alt="" class="emoji" /></span>',
|
||||
'desc' => $this->get_telemetry_description(),
|
||||
'type' => 'checkbox_description',
|
||||
);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a new opt-in via the admin notice
|
||||
*
|
||||
@ -191,7 +165,7 @@ class EDD_Tracking {
|
||||
|
||||
$this->send_checkin( true );
|
||||
|
||||
update_option( 'edd_tracking_notice', '1' );
|
||||
update_option( 'edd_tracking_notice', 1, false );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,7 +179,7 @@ class EDD_Tracking {
|
||||
}
|
||||
|
||||
edd_delete_option( 'allow_tracking' );
|
||||
update_option( 'edd_tracking_notice', '1' );
|
||||
update_option( 'edd_tracking_notice', 1, false );
|
||||
edd_redirect( remove_query_arg( 'edd_action' ) );
|
||||
}
|
||||
|
||||
@ -266,34 +240,92 @@ class EDD_Tracking {
|
||||
|
||||
// No notices for local installs.
|
||||
if ( edd_is_dev_environment() ) {
|
||||
update_option( 'edd_tracking_notice', '1' );
|
||||
update_option( 'edd_tracking_notice', 1, false );
|
||||
return;
|
||||
}
|
||||
|
||||
// Notify the user.
|
||||
} elseif ( edd_is_admin_page() && ! edd_is_admin_page( 'index.php' ) && ! edd_is_insertable_admin_page() ) {
|
||||
$optin_url = add_query_arg( 'edd_action', 'opt_into_tracking' );
|
||||
$optout_url = add_query_arg( 'edd_action', 'opt_out_of_tracking' );
|
||||
|
||||
$base_url_slug = EDD\Admin\Pass_Manager::isPro() ? 'pricing' : 'lite-upgrade';
|
||||
$pass_url = edd_link_helper(
|
||||
'https://easydigitaldownloads.com/' . $base_url_slug,
|
||||
array(
|
||||
'utm_medium' => 'telemetry',
|
||||
'utm_content' => 'notice',
|
||||
)
|
||||
);
|
||||
if ( edd_is_admin_page() && ! edd_is_admin_page( 'index.php' ) && ! edd_is_insertable_admin_page() ) {
|
||||
|
||||
// Add the notice.
|
||||
EDD()->notices->add_notice( array(
|
||||
'id' => 'edd-allow-tracking',
|
||||
'class' => 'updated',
|
||||
'message' => array(
|
||||
'<strong>' . __( 'Help us improve Easy Digital Downloads!', 'easy-digital-downloads' ) . '</strong>',
|
||||
sprintf( __( 'Opt-in to sending the EDD team some information about your store, and immediately be emailed a discount, valid towards the <a href="%s" target="_blank">purchase of a pass</a>.', 'easy-digital-downloads' ), $pass_url ),
|
||||
__( 'No sensitive data is tracked.', 'easy-digital-downloads' ),
|
||||
'<a href="' . esc_url( $optin_url ) . '" class="button-secondary">' . __( 'Allow', 'easy-digital-downloads' ) . '</a> <a href="' . esc_url( $optout_url ) . '" class="button-secondary">' . __( 'Do not allow', 'easy-digital-downloads' ) . '</a>'
|
||||
),
|
||||
'is_dismissible' => false,
|
||||
) );
|
||||
EDD()->notices->add_notice(
|
||||
array(
|
||||
'id' => 'edd-allow-tracking',
|
||||
'class' => 'updated',
|
||||
'message' => $this->get_admin_notice_message(),
|
||||
'is_dismissible' => false,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the admin notice message.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @return array
|
||||
*/
|
||||
private function get_admin_notice_message() {
|
||||
|
||||
return array(
|
||||
'<strong>' . __( 'Join the EDD Community', 'easy-digital-downloads' ) . '</strong>',
|
||||
$this->get_telemetry_description(),
|
||||
sprintf(
|
||||
'<a href="%s" class="button button-primary">%s</a> <a href="%s" class="button button-secondary">%s</a>',
|
||||
esc_url( add_query_arg( 'edd_action', 'opt_into_tracking' ) ),
|
||||
__( 'Allow', 'easy-digital-downloads' ),
|
||||
esc_url( add_query_arg( 'edd_action', 'opt_out_of_tracking' ) ),
|
||||
__( 'Do not allow', 'easy-digital-downloads' )
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the telemetry description.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @return string
|
||||
*/
|
||||
public function get_telemetry_description() {
|
||||
|
||||
return __( 'Help us provide a better experience and faster fixes by sharing some anonymous data about how you use Easy Digital Downloads.', 'easy-digital-downloads' ) .
|
||||
' ' .
|
||||
sprintf(
|
||||
/* translators: %1$s Link to tracking information, do not translate. %2$s clsoing link tag, do not translate */
|
||||
__( '%1$sHere is what we track.%2$s', 'easy-digital-downloads' ),
|
||||
'<a href="' . edd_link_helper( 'https://easydigitaldownloads.com/docs/what-information-will-be-tracked-by-opting-into-usage-tracking/', array( 'utm_medium' => 'telemetry', 'utm_content' => 'option' ) ) . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether we can send the data.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @param bool $override If we should override the tracking setting.
|
||||
* @param bool $ignore_last_checkin If we should ignore when the last check in was.
|
||||
* @return bool
|
||||
*/
|
||||
public function can_send_data( $override, $ignore_last_checkin ) {
|
||||
|
||||
// Never send data from a dev site.
|
||||
if ( edd_is_dev_environment() || edd_is_test_mode() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( function_exists( 'wp_get_environment_type' ) && 'staging' === wp_get_environment_type() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->tracking_allowed() && ! $override ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a maximum of once per week.
|
||||
$last_send = $this->get_last_send();
|
||||
if ( ! $ignore_last_checkin && is_numeric( $last_send ) && $last_send > strtotime( '-1 week' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,6 @@ function edd_do_downgrade() {
|
||||
|
||||
return $did_downgrade;
|
||||
}
|
||||
add_action( 'admin_init', 'edd_do_downgrade' );
|
||||
|
||||
/**
|
||||
* Performs a database downgrade from EDD 3.0 to 2.11 if one is needed.
|
||||
|
@ -20,36 +20,19 @@ defined( 'ABSPATH' ) || exit;
|
||||
*/
|
||||
function edd_do_automatic_upgrades() {
|
||||
|
||||
$did_upgrade = false;
|
||||
$edd_version = edd_get_db_version();
|
||||
|
||||
if ( version_compare( $edd_version, EDD_VERSION, '<' ) ) {
|
||||
|
||||
// Let us know that an upgrade has happened
|
||||
$did_upgrade = true;
|
||||
if ( version_compare( $edd_version, EDD_VERSION, '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $did_upgrade ) {
|
||||
edd_update_db_version();
|
||||
|
||||
// Send a check in. Note: this only sends if data tracking has been enabled
|
||||
$tracking = new EDD_Tracking;
|
||||
$tracking->send_checkin( false, true );
|
||||
}
|
||||
|
||||
// 2.9.2 to 2.9.3
|
||||
$fix_show_privacy_policy_setting = edd_get_option( 'show_agree_to_privacy_policy_on_checkout', false );
|
||||
if ( ! empty( $fix_show_privacy_policy_setting ) ) {
|
||||
edd_update_option( 'show_privacy_policy_on_checkout', $fix_show_privacy_policy_setting );
|
||||
|
||||
edd_delete_option( 'show_agree_to_privacy_policy_on_checkout' );
|
||||
}
|
||||
|
||||
// 3.0: deactivate Manual Purchases addon
|
||||
if ( function_exists( 'edd_load_manual_purchases' ) ) {
|
||||
deactivate_plugins( 'edd-manual-purchases/edd-manual-purchases.php' );
|
||||
delete_option( 'edd_manual_purchases_license_active' );
|
||||
// Existing stores should set the upgraded version and the onboarding wizard as complete.
|
||||
if ( ! empty( $edd_version ) ) {
|
||||
update_option( 'edd_version_upgraded_from', $edd_version, false );
|
||||
if ( ! get_option( 'edd_onboarding_completed', false ) && ! get_option( 'edd_onboarding_started', false ) ) {
|
||||
update_option( 'edd_onboarding_completed', true, false );
|
||||
}
|
||||
}
|
||||
edd_update_db_version();
|
||||
}
|
||||
add_action( 'admin_init', 'edd_do_automatic_upgrades' );
|
||||
|
||||
@ -132,11 +115,8 @@ function edd_show_upgrade_notices() {
|
||||
// Include all 'Stepped' upgrade process notices in this else statement,
|
||||
// to avoid having a pending, and new upgrade suggested at the same time
|
||||
|
||||
if ( get_option( 'edd_upgrade_sequential' ) && edd_get_payments( array( 'fields' => 'ids' ) ) ) {
|
||||
printf(
|
||||
'<div class="notice notice-warning"><p>' . __( 'Easy Digital Downloads needs to upgrade past orders to make them sequential. <a href="%s">Start the order numbers upgrade</a>.', 'easy-digital-downloads' ) . '</p></div>',
|
||||
esc_url( admin_url( 'index.php?page=edd-upgrades&edd-upgrade=upgrade_sequential_payment_numbers' ) )
|
||||
);
|
||||
if ( get_option( 'edd_upgrade_sequential' ) ) {
|
||||
delete_option( 'edd_upgrade_sequential' );
|
||||
}
|
||||
|
||||
if ( version_compare( $edd_version, '2.1', '<' ) ) {
|
||||
@ -388,8 +368,6 @@ function edd_trigger_upgrades() {
|
||||
edd_v20_upgrades();
|
||||
}
|
||||
|
||||
edd_update_db_version();
|
||||
|
||||
// Let AJAX know that the upgrade is complete
|
||||
if ( edd_doing_ajax() ) {
|
||||
die( 'complete' );
|
||||
@ -660,6 +638,7 @@ function edd_v20_upgrades() {
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@ -725,7 +704,6 @@ function edd_v20_upgrade_sequential_payment_numbers() {
|
||||
edd_redirect( admin_url() );
|
||||
}
|
||||
}
|
||||
add_action( 'edd_upgrade_sequential_payment_numbers', 'edd_v20_upgrade_sequential_payment_numbers' );
|
||||
|
||||
/**
|
||||
* Upgrades for EDD v2.1 and the new customers database
|
||||
@ -817,7 +795,6 @@ function edd_v21_upgrade_customers_db() {
|
||||
|
||||
// No more customers found, finish up
|
||||
} else {
|
||||
edd_update_db_version();
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
|
||||
edd_redirect( admin_url() );
|
||||
@ -854,7 +831,6 @@ function edd_v226_upgrade_payments_price_logs_db() {
|
||||
$has_variable = $wpdb->get_col( $sql );
|
||||
if ( empty( $has_variable ) ) {
|
||||
// We had no variable priced products, so go ahead and just complete
|
||||
edd_update_db_version();
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
}
|
||||
@ -931,7 +907,6 @@ function edd_v226_upgrade_payments_price_logs_db() {
|
||||
|
||||
edd_redirect( $redirect );
|
||||
} else {
|
||||
edd_update_db_version();
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
}
|
||||
@ -968,7 +943,6 @@ function edd_v23_upgrade_payment_taxes() {
|
||||
|
||||
if ( empty( $has_payments ) ) {
|
||||
// We had no payments, just complete
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'upgrade_payment_taxes' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
@ -1007,7 +981,6 @@ function edd_v23_upgrade_payment_taxes() {
|
||||
|
||||
// No more payments found, finish up
|
||||
} else {
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'upgrade_payment_taxes' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
@ -1045,7 +1018,6 @@ function edd_v23_upgrade_customer_purchases() {
|
||||
|
||||
if ( empty( $has_payments ) ) {
|
||||
// We had no payments, just complete
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'upgrade_customer_payments_association' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
@ -1126,7 +1098,6 @@ function edd_v23_upgrade_customer_purchases() {
|
||||
|
||||
// No more customers found, finish up
|
||||
} else {
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'upgrade_customer_payments_association' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
|
||||
@ -1165,7 +1136,6 @@ function edd_upgrade_user_api_keys() {
|
||||
|
||||
// We had no key, just complete
|
||||
if ( empty( $has_key ) ) {
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'upgrade_user_api_keys' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
@ -1209,7 +1179,6 @@ function edd_upgrade_user_api_keys() {
|
||||
|
||||
// No more customers found, finish up
|
||||
} else {
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'upgrade_user_api_keys' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
@ -1271,7 +1240,6 @@ function edd_remove_refunded_sale_logs() {
|
||||
|
||||
// No more refunded payments found, finish up
|
||||
} else {
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'remove_refunded_sale_logs' );
|
||||
delete_option( 'edd_doing_upgrade' );
|
||||
edd_redirect( admin_url() );
|
||||
|
@ -434,6 +434,27 @@ class Data_Migrator {
|
||||
$payment_meta = maybe_unserialize( $meta['_edd_payment_meta'][0] );
|
||||
$user_info = isset( $payment_meta['user_info'] ) ? maybe_unserialize( $payment_meta['user_info'] ) : array();
|
||||
|
||||
// It is possible that for some reason the entire unserialized array is invalid, so before trying to use it, let's just verify we got an array back.
|
||||
if ( ! is_array( $payment_meta ) ) {
|
||||
// Dump this data to a file to ensure we keep it for later use.
|
||||
edd_debug_log( '==== Failed Migrating Legacy Payment ID: ' . $data->ID . ' ====', true );
|
||||
edd_debug_log( 'Reason: Payment Meta Unserialization failed.', true );
|
||||
edd_debug_log( '- Post Data', true );
|
||||
foreach ( get_object_vars( $data ) as $key => $value ) {
|
||||
edd_debug_log( '-- ' . $key . ': ' . $value, true );
|
||||
}
|
||||
|
||||
edd_debug_log( '- Post Meta', true );
|
||||
foreach ( $meta as $key => $value_array ) {
|
||||
edd_debug_log( '-- Meta Key: ' . $key, true );
|
||||
foreach ( $value_array as $value ) {
|
||||
edd_debug_log( '--- ' . $value, true );
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some old EDD data has the user info serialized, but starting with something other than a: so it can't be unserialized
|
||||
$user_info = self::fix_possible_serialization( $user_info );
|
||||
$user_info = maybe_unserialize( $user_info );
|
||||
|
@ -54,8 +54,14 @@ class Remove_Legacy_Data extends Base {
|
||||
if ( 1 === $this->step ) {
|
||||
// Drop customer `payment_ids` column. It's no longer needed.
|
||||
$customer_table = edd_get_component_interface( 'customer', 'table' );
|
||||
if ( $customer_table instanceof \EDD\Database\Tables\Customers && $customer_table->column_exists( 'payment_ids' ) ) {
|
||||
$this->get_db()->query( "ALTER TABLE {$this->get_db()->edd_customers} DROP `payment_ids`" );
|
||||
if ( $customer_table instanceof \EDD\Database\Tables\Customers ) {
|
||||
if ( $customer_table->column_exists( 'payment_ids' ) ) {
|
||||
$this->get_db()->query( "ALTER TABLE {$this->get_db()->edd_customers} DROP `payment_ids`" );
|
||||
}
|
||||
|
||||
if ( $customer_table->column_exists( 'notes' ) ) {
|
||||
$this->get_db()->query( "ALTER TABLE {$this->get_db()->edd_customers} DROP `notes`" );
|
||||
}
|
||||
}
|
||||
|
||||
// Delete unneeded meta.
|
||||
|
@ -344,12 +344,20 @@ function edd_ajax_update_cart_item_quantity() {
|
||||
|
||||
EDD()->cart->set_item_quantity( $download_id, $quantity, $options );
|
||||
|
||||
$subtotal = EDD()->cart->get_subtotal();
|
||||
$taxes = EDD()->cart->get_tax();
|
||||
$total = EDD()->cart->get_total();
|
||||
|
||||
$return = array(
|
||||
'download_id' => $download_id,
|
||||
'quantity' => EDD()->cart->get_item_quantity( $download_id, $options ),
|
||||
'subtotal' => html_entity_decode( edd_currency_filter( edd_format_amount( EDD()->cart->get_subtotal() ) ), ENT_COMPAT, 'UTF-8' ),
|
||||
'taxes' => html_entity_decode( edd_currency_filter( edd_format_amount( EDD()->cart->get_tax() ) ), ENT_COMPAT, 'UTF-8' ),
|
||||
'total' => html_entity_decode( edd_currency_filter( edd_format_amount( EDD()->cart->get_total() ) ), ENT_COMPAT, 'UTF-8' )
|
||||
'download_id' => $download_id,
|
||||
'quantity' => EDD()->cart->get_item_quantity( $download_id, $options ),
|
||||
'subtotal_raw' => $subtotal,
|
||||
'taxes_raw' => $taxes,
|
||||
'total_raw' => $total,
|
||||
'subtotal' => html_entity_decode( edd_currency_filter( edd_format_amount( $subtotal ) ), ENT_COMPAT, 'UTF-8' ),
|
||||
'taxes' => html_entity_decode( edd_currency_filter( edd_format_amount( $taxes ) ), ENT_COMPAT, 'UTF-8' ),
|
||||
'total' => html_entity_decode( edd_currency_filter( edd_format_amount( $total ) ), ENT_COMPAT, 'UTF-8' ),
|
||||
'discounts' => edd_get_cart_discounts_html(),
|
||||
);
|
||||
|
||||
// Allow for custom cart item quantity handling
|
||||
@ -588,174 +596,18 @@ add_action( 'wp_ajax_nopriv_edd_get_shop_states', 'edd_ajax_get_states_field' );
|
||||
*
|
||||
* @since 1.6
|
||||
* @since 3.0 Use `get_posts()` instead of multiple direct queries (yay caching)
|
||||
* @since 3.1.0.5 Uses EDD\Downloads\Search.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
function edd_ajax_download_search() {
|
||||
|
||||
// We store the last search in a transient for 30 seconds. This _might_
|
||||
// result in a race condition if 2 users are looking at the exact same time,
|
||||
// but we'll worry about that later if that situation ever happens.
|
||||
$args = get_transient( 'edd_download_search' );
|
||||
|
||||
// Parse args.
|
||||
$search = wp_parse_args(
|
||||
(array) $args,
|
||||
array(
|
||||
'text' => '',
|
||||
'results' => array(),
|
||||
)
|
||||
);
|
||||
|
||||
// Get the search string.
|
||||
$new_search = isset( $_GET['s'] )
|
||||
? sanitize_text_field( $_GET['s'] )
|
||||
: '';
|
||||
|
||||
// Limit to only alphanumeric characters, including unicode and spaces.
|
||||
$new_search = preg_replace( '/[^\pL^\pN\pZ]/', ' ', $new_search );
|
||||
|
||||
// Bail early if the search text has not changed.
|
||||
if ( $search['text'] === $new_search ) {
|
||||
echo wp_json_encode( $search['results'] );
|
||||
edd_die();
|
||||
}
|
||||
|
||||
// Set the local static search variable.
|
||||
$search['text'] = $new_search;
|
||||
|
||||
// Are we excluding the current ID?
|
||||
$excludes = isset( $_GET['current_id'] )
|
||||
? array_unique( array_map( 'absint', (array) $_GET['current_id'] ) )
|
||||
: array();
|
||||
|
||||
// Are we excluding bundles?
|
||||
$no_bundles = isset( $_GET['no_bundles'] )
|
||||
? filter_var( $_GET['no_bundles'], FILTER_VALIDATE_BOOLEAN )
|
||||
: false;
|
||||
|
||||
// Are we including variations?
|
||||
$variations = isset( $_GET['variations'] )
|
||||
? filter_var( $_GET['variations'], FILTER_VALIDATE_BOOLEAN )
|
||||
: false;
|
||||
|
||||
$variations_only = isset( $_GET['variations_only'] )
|
||||
? filter_var( $_GET['variations_only'], FILTER_VALIDATE_BOOLEAN )
|
||||
: false;
|
||||
|
||||
// Are we including all statuses, or only public ones?
|
||||
$status = ! current_user_can( 'edit_products' )
|
||||
? apply_filters( 'edd_product_dropdown_status_nopriv', array( 'publish' ) )
|
||||
: apply_filters( 'edd_product_dropdown_status', array( 'publish', 'draft', 'private', 'future' ) );
|
||||
|
||||
// Default query arguments.
|
||||
$args = array(
|
||||
'orderby' => 'title',
|
||||
'order' => 'ASC',
|
||||
'post_type' => 'download',
|
||||
'posts_per_page' => 50,
|
||||
'post_status' => implode( ',', $status ), // String.
|
||||
'post__not_in' => $excludes, // Array.
|
||||
'edd_search' => $new_search, // String.
|
||||
'suppress_filters' => false,
|
||||
);
|
||||
|
||||
// Maybe exclude bundles.
|
||||
if ( true === $no_bundles ) {
|
||||
$args['meta_query'] = array(
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => '_edd_product_type',
|
||||
'value' => 'bundle',
|
||||
'compare' => '!=',
|
||||
),
|
||||
array(
|
||||
'key' => '_edd_product_type',
|
||||
'value' => 'bundle',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
add_filter( 'posts_where', 'edd_ajax_filter_download_where', 10, 2 );
|
||||
// Get downloads.
|
||||
$items = get_posts( $args );
|
||||
remove_filter( 'posts_where', 'edd_ajax_filter_download_where', 10, 2 );
|
||||
|
||||
// Pluck title & ID.
|
||||
if ( ! empty( $items ) ) {
|
||||
$items = wp_list_pluck( $items, 'post_title', 'ID' );
|
||||
|
||||
// Loop through all items...
|
||||
foreach ( $items as $post_id => $title ) {
|
||||
$product_title = $title;
|
||||
|
||||
// Look for variable pricing.
|
||||
$prices = edd_get_variable_prices( $post_id );
|
||||
|
||||
if ( ! empty( $prices ) && ( false === $variations || ! $variations_only ) ) {
|
||||
$title .= ' (' . __( 'All Price Options', 'easy-digital-downloads' ) . ')';
|
||||
}
|
||||
|
||||
if ( empty( $prices ) || ! $variations_only ) {
|
||||
// Add item to results array.
|
||||
$search['results'][] = array(
|
||||
'id' => $post_id,
|
||||
'name' => $title,
|
||||
);
|
||||
}
|
||||
|
||||
// Maybe include variable pricing.
|
||||
if ( ! empty( $variations ) && ! empty( $prices ) ) {
|
||||
foreach ( $prices as $key => $value ) {
|
||||
$name = ! empty( $value['name'] ) ? $value['name'] : '';
|
||||
|
||||
if ( ! empty( $name ) ) {
|
||||
$search['results'][] = array(
|
||||
'id' => $post_id . '_' . $key,
|
||||
'name' => esc_html( $product_title . ': ' . $name ),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Empty the results array.
|
||||
$search['results'] = array();
|
||||
}
|
||||
|
||||
// Update the transient.
|
||||
set_transient( 'edd_download_search', $search, 30 );
|
||||
|
||||
// Output the results.
|
||||
echo wp_json_encode( $search['results'] );
|
||||
|
||||
// Done!
|
||||
edd_die();
|
||||
$search = new EDD\Downloads\Search();
|
||||
$search->ajax_search();
|
||||
}
|
||||
add_action( 'wp_ajax_edd_download_search', 'edd_ajax_download_search' );
|
||||
add_action( 'wp_ajax_nopriv_edd_download_search', 'edd_ajax_download_search' );
|
||||
|
||||
/**
|
||||
* Filters the WHERE SQL query for the edd_download_search.
|
||||
* This searches the download titles only, not the excerpt/content.
|
||||
*
|
||||
* @since 3.1.0.2
|
||||
* @param string $where
|
||||
* @param WP_Query $wp_query
|
||||
* @return string
|
||||
*/
|
||||
function edd_ajax_filter_download_where( $where, $wp_query ) {
|
||||
$search = $wp_query->get( 'edd_search' );
|
||||
if ( $search ) {
|
||||
global $wpdb;
|
||||
$search = $wpdb->esc_like( $search );
|
||||
$where .= " AND {$wpdb->posts}.post_title LIKE '%{$search}%'";
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search the customers database via AJAX
|
||||
*
|
||||
|
@ -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' => 'ab8b46a89c77db7555c2');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'd12364cb3d89217da0af');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'e15e50fe721f8724f3ff');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '44a7f6fcddb3d7a45761');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '5f9828f99e37e2672da7');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'f7eb0560b580188ab6f6');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '1f63b1343e4767c56590');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'fbe222c67791f3db7f56');
|
||||
|
File diff suppressed because one or more lines are too long
@ -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' => '65fac9798bc396ac4f3f');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-data', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '4dc61207e0bc9900907a');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '19e62e128bed7c7d9f98');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '8022d11843870776cb71');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '419c2b961828910baaff');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => 'ba06ffbd66b5912e943d');
|
||||
|
@ -1 +1 @@
|
||||
.wp-block-edd-orders.block-editor-block-list__block{padding:2rem!important}
|
||||
.wp-block-edd-order-history.block-editor-block-list__block{padding:2rem!important}.wp-block-edd-order-history .description{background-color:#efefef;margin-bottom:1em;padding:1em}
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '55245582154e0103f57f');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '5db7f26583a44b89219b');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'c67ec71759d631f00283');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '0661e954af1bb187dd97');
|
||||
|
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '481a55873a76d759425a');
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '1028b825bf11c1432c23');
|
||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,40 @@
|
||||
{
|
||||
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||
"apiVersion": 2,
|
||||
"name": "edd/user-downloads",
|
||||
"version": "2.0.0",
|
||||
"title": "EDD User Downloads",
|
||||
"category": "easy-digital-downloads",
|
||||
"icon": "admin-links",
|
||||
"description": "Allows a user to access the Easy Digital Downloads products they have purchased.",
|
||||
"keywords": [
|
||||
"easy digital downloads",
|
||||
"edd",
|
||||
"orders"
|
||||
],
|
||||
"supports": {
|
||||
"html": false
|
||||
},
|
||||
"textdomain": "easy-digital-downloads",
|
||||
"editorScript": "file:./index.js",
|
||||
"editorStyle": "file:./index.css",
|
||||
"style": "file:./style-index.css",
|
||||
"attributes": {
|
||||
"search": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"variations": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"nofiles": {
|
||||
"type": "string",
|
||||
"default": "No downloadable files found."
|
||||
},
|
||||
"hide_empty": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array('wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n', 'wp-server-side-render'), 'version' => '535d394ba6d83f8c0b16');
|
@ -0,0 +1 @@
|
||||
.wp-block-edd-user-downloads.block-editor-block-list__block{padding:2rem!important}.wp-block-edd-user-downloads .description{background-color:#efefef;margin-bottom:1em;padding:1em}.wp-block-edd-user-downloads .warning{border:1px solid #ddd;border-left:4px solid #f0b849;margin-bottom:1em;padding:1em}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
.screen-reader-text{clip:rect(1px,1px,1px,1px);word-wrap:normal!important;border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.edd-pro-search__control{display:flex;justify-content:flex-end;margin-bottom:2em}.edd-pro-search__control input{max-width:100%;width:300px}.edd-pro-search__hidden{display:none!important}.edd-blocks__row{align-items:center;display:grid;gap:1rem}.edd-blocks__row-label{font-weight:700}@media(min-width:480px){.edd-blocks__row{grid-template-columns:1fr 1fr}.edd-blocks__row>div:last-of-type:not(:first-of-type){text-align:right}.edd-blocks__row>div:only-child{grid-column:1/span 2}}div.edd-blocks__user-downloads{border:1px solid var(--edd-blocks-light-grey);padding:1rem}div.edd-blocks__user-downloads .edd-order-item__product .edd-order-item__files,div.edd-blocks__user-downloads .edd-order-items__header .edd-blocks__row-label{text-align:left}.edd-order-item__product,.edd-order-items__header{border-bottom:1px solid var(--edd-blocks-light-grey);gap:1em;padding:.5em 0}.edd-order-item__product:last-child,.edd-order-items__header:last-child{border-bottom:none;padding-bottom:0}.edd-order-items__header{padding-top:0}
|
@ -4,7 +4,7 @@
|
||||
* Description: Core blocks for Easy Digital Downloads.
|
||||
* Requires at least: 5.8
|
||||
* Requires PHP: 7.0
|
||||
* Version: 2.0.3
|
||||
* Version: 2.0.5.1
|
||||
* Author: Easy Digital Downloads
|
||||
* License: GPL-2.0-or-later
|
||||
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||
@ -66,6 +66,16 @@ function init_core_blocks() {
|
||||
require_once trailingslashit( EDD_BLOCKS_DIR . 'includes/admin' ) . $file . '.php';
|
||||
}
|
||||
}
|
||||
|
||||
if ( edd_is_pro() ) {
|
||||
$pro_files = array(
|
||||
'search',
|
||||
);
|
||||
|
||||
foreach ( $pro_files as $file ) {
|
||||
require_once trailingslashit( EDD_BLOCKS_DIR . 'pro' ) . $file . '.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -78,18 +88,19 @@ add_filter( 'edd_required_pages', __NAMESPACE__ . '\update_core_required_pages'
|
||||
*/
|
||||
function update_core_required_pages( $pages ) {
|
||||
|
||||
$pages['confirmation_page'] = array(
|
||||
$pages['confirmation_page'] = array(
|
||||
'post_title' => __( 'Confirmation', 'easy-digital-downloads' ),
|
||||
'post_content' => '<!-- wp:paragraph --><p>' . __( 'Thank you for your purchase!', 'easy-digital-downloads' ) . '</p><!-- /wp:paragraph --><!-- wp:edd/confirmation /-->',
|
||||
);
|
||||
$pages['success_page'] = array(
|
||||
$pages['success_page'] = array(
|
||||
'post_title' => __( 'Receipt', 'easy-digital-downloads' ),
|
||||
'post_content' => '<!-- wp:edd/receipt /-->',
|
||||
);
|
||||
$pages['purchase_history_page'] = array(
|
||||
$pages['purchase_history_page'] = array(
|
||||
'post_title' => __( 'Order History', 'easy-digital-downloads' ),
|
||||
'post_content' => '<!-- wp:edd/order-history /-->',
|
||||
);
|
||||
$pages['purchase_page']['post_content'] = '<!-- wp:edd/checkout /-->';
|
||||
|
||||
return $pages;
|
||||
}
|
||||
|
@ -18,9 +18,11 @@ 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' ),
|
||||
'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(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
@ -28,17 +28,29 @@ function pages( $settings ) {
|
||||
|
||||
$pages = edd_get_pages();
|
||||
|
||||
// Login page.
|
||||
$settings['pages']['login_page'] = array(
|
||||
'id' => 'login_page',
|
||||
'name' => __( 'Login Page', 'easy-digital-downloads' ),
|
||||
'desc' => __( 'This page must include the EDD Login block. Setting this allows the front end form to be used for resetting passwords.', 'easy-digital-downloads' ),
|
||||
'type' => 'select',
|
||||
'options' => $pages,
|
||||
'chosen' => true,
|
||||
'placeholder' => __( 'Select a page', 'easy-digital-downloads' ),
|
||||
$login_description = __( 'This page must include the EDD Login block. Setting this allows the front end form to be used for resetting passwords.', 'easy-digital-downloads' );
|
||||
$login_description .= '<br />';
|
||||
$login_description .= sprintf(
|
||||
/* translators: 1. opening code tag, do not translate; 2. closing code tag, do not translate. */
|
||||
__( 'Do not use this with the %1$s[edd_login]%2$s shortcode; it does not support resetting passwords.', 'easy-digital-downloads' ),
|
||||
'<code>',
|
||||
'</code>'
|
||||
);
|
||||
|
||||
// Login page.
|
||||
$login_page = array(
|
||||
array(
|
||||
'id' => 'login_page',
|
||||
'name' => __( 'Login Page', 'easy-digital-downloads' ),
|
||||
'desc' => $login_description,
|
||||
'type' => 'select',
|
||||
'options' => $pages,
|
||||
'chosen' => true,
|
||||
'placeholder' => __( 'Select a page', 'easy-digital-downloads' ),
|
||||
),
|
||||
);
|
||||
array_splice( $settings['pages'], -1, 0, $login_page );
|
||||
|
||||
if ( ! empty( $settings['pages']['purchase_page']['desc'] ) ) {
|
||||
$description = __( 'This is the checkout page where customers will complete their purchases.', 'easy-digital-downloads' );
|
||||
$description .= '<br />';
|
||||
@ -169,3 +181,19 @@ function button_colors( $args ) {
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
add_filter( 'edd_settings_misc', __NAMESPACE__ . '\disable_redownload' );
|
||||
/**
|
||||
* Update the text for the `disable_redownload` setting.
|
||||
*
|
||||
* @since 2.0.4
|
||||
* @param array $settings
|
||||
* @return array
|
||||
*/
|
||||
function disable_redownload( $settings ) {
|
||||
if ( ! empty( $settings['file_downloads']['disable_redownload']['desc'] ) ) {
|
||||
$settings['file_downloads']['disable_redownload']['desc'] = __( 'Do not allow users to redownload items from their order history.', 'easy-digital-downloads' );
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
@ -86,6 +86,7 @@ function do_personal_info_forms( $block_attributes ) {
|
||||
<?php
|
||||
$forms = get_personal_info_forms( $block_attributes, $customer_info_complete );
|
||||
if ( ! empty( $forms ) && count( $forms ) > 1 ) {
|
||||
wp_enqueue_script( 'edd-blocks-checkout-forms' );
|
||||
$i = 0;
|
||||
echo '<div class="edd-blocks__checkout-forms">';
|
||||
foreach ( $forms as $id => $form ) {
|
||||
@ -165,11 +166,7 @@ function add_user_script() {
|
||||
return;
|
||||
}
|
||||
|
||||
// For guest users, enqueue the script to toggle the login/registration forms.
|
||||
$forms = get_personal_info_forms( array( 'show_register_form' => edd_get_option( 'show_register_form' ) ) );
|
||||
if ( ! empty( $forms ) && count( $forms ) > 1 ) {
|
||||
wp_enqueue_script( 'edd-blocks-checkout-forms', EDD_BLOCKS_URL . 'assets/js/checkout-forms.js', array( 'edd-checkout-global' ), EDD_VERSION, true );
|
||||
}
|
||||
wp_register_script( 'edd-blocks-checkout-forms', EDD_BLOCKS_URL . 'assets/js/checkout-forms.js', array( 'edd-checkout-global' ), EDD_VERSION, true );
|
||||
}
|
||||
|
||||
add_action( 'wp_ajax_nopriv_edd_blocks_swap_personal_info', __NAMESPACE__ . '\swap_form' );
|
||||
|
@ -148,7 +148,7 @@ function buy_button( $block_attributes = array() ) {
|
||||
wp_enqueue_style( 'edd-styles' );
|
||||
}
|
||||
|
||||
$output = sprintf( '<div class="%s">', implode( ' ', $classes ) );
|
||||
$output = sprintf( '<div class="%s">', esc_attr( implode( ' ', $classes ) ) );
|
||||
$output .= edd_get_purchase_link(
|
||||
array(
|
||||
'class' => implode( ' ', get_purchase_link_classes( $block_attributes ) ),
|
||||
|
@ -51,10 +51,13 @@ function get_block_classes( $block_attributes, $classes = array() ) {
|
||||
$classes[] = "align{$block_attributes['align']}";
|
||||
}
|
||||
if ( ! empty( $block_attributes['className'] ) ) {
|
||||
$classes[] = $block_attributes['className'];
|
||||
$additional_classes = explode( ' ', $block_attributes['className'] );
|
||||
if ( $additional_classes ) {
|
||||
$classes = array_merge( $classes, $additional_classes );
|
||||
}
|
||||
}
|
||||
|
||||
return array_filter( array_unique( $classes ) );
|
||||
return array_filter( array_unique( array_map( 'sanitize_html_class', $classes ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -126,3 +129,18 @@ function is_block_editor( $current_user_can = '' ) {
|
||||
|
||||
return hash_equals( md5( $user->user_email ), $is_block_editor ) && current_user_can( $current_user_can );
|
||||
}
|
||||
|
||||
add_action( 'send_headers', __NAMESPACE__ . '\update_headers' );
|
||||
/**
|
||||
* Prevents clickjacking by sending the X-Frame-Options header
|
||||
* when a page has either the checkout or login block.
|
||||
*
|
||||
* @since 2.0.5.1
|
||||
* @return void
|
||||
*/
|
||||
function update_headers() {
|
||||
if ( ! has_block( 'edd/checkout' ) && ! has_block( 'edd/login' ) && ! has_block( 'edd/register' ) ) {
|
||||
return;
|
||||
}
|
||||
header( 'X-Frame-Options: SAMEORIGIN' );
|
||||
}
|
||||
|
@ -26,15 +26,18 @@ add_action( 'init', __NAMESPACE__ . '\register' );
|
||||
*/
|
||||
function register() {
|
||||
$blocks = array(
|
||||
'order-history' => array(
|
||||
'order-history' => array(
|
||||
'render_callback' => __NAMESPACE__ . '\orders',
|
||||
),
|
||||
'confirmation' => array(
|
||||
'confirmation' => array(
|
||||
'render_callback' => __NAMESPACE__ . '\confirmation',
|
||||
),
|
||||
'receipt' => array(
|
||||
'receipt' => array(
|
||||
'render_callback' => __NAMESPACE__ . '\receipt',
|
||||
),
|
||||
'user-downloads' => array(
|
||||
'render_callback' => __NAMESPACE__ . '\downloads',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $blocks as $block => $args ) {
|
||||
@ -56,25 +59,7 @@ function orders( $block_attributes = array() ) {
|
||||
|
||||
if ( edd_user_pending_verification() ) {
|
||||
ob_start();
|
||||
if ( ! empty( $_GET['edd-verify-request'] ) ) :
|
||||
?>
|
||||
<p class="edd-account-pending edd_success">
|
||||
<?php esc_html_e( 'An email with an activation link has been sent.', 'easy-digital-downloads' ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p class="edd-account-pending">
|
||||
<?php
|
||||
printf(
|
||||
wp_kses_post(
|
||||
/* translators: 1. Opening anchor tag. 2. Closing anchor tag. */
|
||||
__( 'Your account is pending verification. Please click the link in your email to activate your account. No email? %1$sSend a new activation code.%2$s', 'easy-digital-downloads' )
|
||||
),
|
||||
'<a href="' . esc_url( edd_get_user_verification_request_url() ) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
include EDD_BLOCKS_DIR . 'views/orders/pending.php';
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
@ -123,7 +108,7 @@ function confirmation( $block_attributes = array() ) {
|
||||
$session = Functions\get_purchase_session();
|
||||
if ( empty( $session['purchase_key'] ) ) {
|
||||
if ( Helpers\is_block_editor() ) {
|
||||
return '<p class="edd-alert edd-alert-info">' . esc_html( __( 'To view a sample confirmation screen, you need to have at least one order in your store.', 'easy-digital-downloads' ) ) . '</p>';
|
||||
return '<p class="edd-alert edd-alert-info">' . esc_html( __( 'To view a sample confirmation screen, you need to have at least one order in your store.', 'easy-digital-downloads' ) ) . '</p>';
|
||||
}
|
||||
|
||||
return '<p class="edd-alert edd-alert-error">' . esc_html( __( 'Your purchase session could not be retrieved.', 'easy-digital-downloads' ) ) . '</p>';
|
||||
@ -197,7 +182,7 @@ function receipt( $block_attributes = array() ) {
|
||||
edd_print_errors();
|
||||
|
||||
$order = edd_get_order_by( 'payment_key', $payment_key );
|
||||
$user_can_view = edd_can_view_receipt( $payment_key );
|
||||
$user_can_view = edd_can_view_receipt( $order );
|
||||
if ( ! $user_can_view ) {
|
||||
show_no_access_message( $order );
|
||||
|
||||
@ -313,3 +298,160 @@ function verify_guest_email( $data ) {
|
||||
}
|
||||
edd_set_error( 'edd-guest-error', __( 'Your email address could not be verified.', 'easy-digital-downloads' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the download history block.
|
||||
*
|
||||
* @since 2.0.5
|
||||
* @param array $block_attributes
|
||||
* @return string
|
||||
*/
|
||||
function downloads( $block_attributes = array() ) {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( edd_user_pending_verification() ) {
|
||||
ob_start();
|
||||
include EDD_BLOCKS_DIR . 'views/orders/pending.php';
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
$block_attributes = wp_parse_args(
|
||||
$block_attributes,
|
||||
array(
|
||||
'search' => false,
|
||||
'variations' => true,
|
||||
'nofiles' => __( 'No downloadable files found.', 'easy-digital-downloads' ),
|
||||
'hide_empty' => true,
|
||||
)
|
||||
);
|
||||
|
||||
$downloads = get_purchased_products( $block_attributes );
|
||||
if ( ! $downloads ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Set up classes.
|
||||
$classes = array(
|
||||
'wp-block-edd-user-downloads',
|
||||
'edd-blocks__user-downloads',
|
||||
);
|
||||
ob_start();
|
||||
?>
|
||||
<div class="<?php echo esc_attr( implode( ' ', array_filter( $classes ) ) ); ?>">
|
||||
<?php
|
||||
if ( $block_attributes['search'] && function_exists( '\\EDD\\Blocks\\Pro\\Search\\do_search' ) ) {
|
||||
\EDD\Blocks\Pro\Search\do_search();
|
||||
}
|
||||
?>
|
||||
<div class="edd-blocks__row edd-blocks__row-header edd-order-items__header">
|
||||
<div class="edd-blocks__row-label"><?php esc_html_e( 'Products', 'easy-digital-downloads' ); ?></div>
|
||||
<?php if ( ! edd_no_redownload() ) : ?>
|
||||
<div class="edd-blocks__row-label"><?php esc_html_e( 'Files', 'easy-digital-downloads' ); ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
ksort( $downloads );
|
||||
foreach ( $downloads as $name => $item ) {
|
||||
include EDD_BLOCKS_DIR . 'views/orders/downloads.php';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of products the user has purchased.
|
||||
*
|
||||
* @since 2.0.5
|
||||
* @param array The block attributes
|
||||
* @return false|array
|
||||
*/
|
||||
function get_purchased_products( $block_attributes ) {
|
||||
$args = array(
|
||||
'user_id' => get_current_user_id(),
|
||||
'fields' => 'ids',
|
||||
'status__in' => \edd_get_complete_order_statuses(),
|
||||
'number' => 9999,
|
||||
);
|
||||
if ( Helpers\is_block_editor() ) {
|
||||
$args['number'] = 50;
|
||||
unset( $args['user_id'] );
|
||||
}
|
||||
$order_ids = edd_get_orders( $args );
|
||||
if ( empty( $order_ids ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$items = edd_get_order_items(
|
||||
array(
|
||||
'order_id__in' => $order_ids,
|
||||
'number' => 99999,
|
||||
'status__in' => \edd_get_deliverable_order_item_statuses(),
|
||||
)
|
||||
);
|
||||
if ( empty( $items ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$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 ) ) {
|
||||
continue;
|
||||
}
|
||||
$bundled_products = edd_get_bundled_products( $item->product_id, $item->price_id );
|
||||
foreach ( $bundled_products as $bundle_item ) {
|
||||
$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 );
|
||||
$order_item_args = array(
|
||||
'order_id' => $item->order_id,
|
||||
'status' => $item->status,
|
||||
'product_id' => $product_id,
|
||||
'product_name' => $key,
|
||||
);
|
||||
if ( is_numeric( $price_id ) && edd_has_variable_prices( $product_id ) ) {
|
||||
if ( ! empty( $block_attributes['variations'] ) ) {
|
||||
$key = edd_get_download_name( $product_id, $price_id );
|
||||
$order_item_args['product_name'] = $key;
|
||||
} else {
|
||||
$download_files = edd_get_download_files( $product_id, $price_id );
|
||||
$conditions = wp_list_pluck( $download_files, 'condition' );
|
||||
if ( ! empty( $conditions ) && ! in_array( 'all', $conditions, true ) ) {
|
||||
$key = edd_get_download_name( $product_id, $price_id );
|
||||
$order_item_args['product_name'] = $key;
|
||||
}
|
||||
}
|
||||
$order_item_args['price_id'] = $price_id;
|
||||
}
|
||||
if ( array_key_exists( $key, $downloads ) ) {
|
||||
continue;
|
||||
}
|
||||
$downloads[ $key ] = new \EDD\Orders\Order_Item( $order_item_args );
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$key = $item->product_name;
|
||||
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 );
|
||||
$conditions = wp_list_pluck( $download_files, 'condition' );
|
||||
if ( empty( $conditions ) || in_array( 'all', $conditions, true ) ) {
|
||||
$key = edd_get_download_name( $item->product_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( array_key_exists( $key, $downloads ) ) {
|
||||
continue;
|
||||
}
|
||||
$downloads[ $key ] = $item;
|
||||
}
|
||||
|
||||
return ! empty( $downloads ) ? $downloads : false;
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ if ( function_exists( 'EDD_CFM' ) ) {
|
||||
echo EDD()->html->show_required();
|
||||
?>
|
||||
</label>
|
||||
<input class="edd-input required" type="email" name="edd_email" placeholder="<?php esc_html_e( 'Email address', 'easy-digital-downloads' ); ?>" id="edd-email" value="<?php echo esc_attr( $customer['email'] ); ?>" aria-describedby="edd-email-description" required/>
|
||||
<input class="edd-input required" type="email" name="edd_email" placeholder="<?php esc_html_e( 'Email address', 'easy-digital-downloads' ); ?>" id="edd-email" value="<?php echo esc_attr( $customer['email'] ); ?>" aria-describedby="edd-email-description" maxlength="100" required/>
|
||||
<p class="edd-description" id="edd-email-description"><?php esc_html_e( 'We will send the purchase receipt to this address.', 'easy-digital-downloads' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?php
|
||||
$price_id = $item->price_id;
|
||||
$download_files = edd_get_download_files( $item->product_id, $item->price_id );
|
||||
if ( $block_attributes['hide_empty'] && empty( $download_files ) ) {
|
||||
return;
|
||||
}
|
||||
$order = edd_get_order( $item->order_id );
|
||||
$classes = array(
|
||||
'edd-blocks__row',
|
||||
'edd-order-item__product',
|
||||
);
|
||||
if ( $block_attributes['search'] && edd_is_pro() ) {
|
||||
$classes[] = 'edd-pro-search__product';
|
||||
}
|
||||
?>
|
||||
<div class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>">
|
||||
<div class="edd-blocks__row-label"><?php echo esc_html( $name ); ?></div>
|
||||
|
||||
<?php if ( ! edd_no_redownload() ) : ?>
|
||||
<div class="edd-order-item__files">
|
||||
<?php
|
||||
if ( $download_files ) :
|
||||
foreach ( $download_files as $filekey => $file ) :
|
||||
$download_url = edd_get_download_file_url( $order, $order->email, $filekey, $item->product_id, $price_id );
|
||||
?>
|
||||
<div class="edd-order-item__file">
|
||||
<a href="<?php echo esc_url( $download_url ); ?>" class="edd-order-item__file-link">
|
||||
<?php echo esc_html( edd_get_file_name( $file ) ); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php
|
||||
endforeach;
|
||||
else :
|
||||
echo esc_html( $block_attributes['nofiles'] );
|
||||
endif; // End $download_files
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
@ -12,7 +12,7 @@
|
||||
?>
|
||||
</label>
|
||||
<div class="edd-blocks-form__control">
|
||||
<input name="edd_guest_email" id="edd_guest_email" class="edd-required edd-input" type="email" required/>
|
||||
<input name="edd_guest_email" id="edd_guest_email" class="edd-required edd-input" type="email" maxlength="100" required/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edd-blocks-form__group edd-blocks-form__group-submit">
|
||||
|
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
if ( ! empty( $_GET['edd-verify-request'] ) ) :
|
||||
?>
|
||||
<p class="edd-account-pending edd_success">
|
||||
<?php esc_html_e( 'An email with an activation link has been sent.', 'easy-digital-downloads' ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p class="edd-account-pending">
|
||||
<?php
|
||||
printf(
|
||||
wp_kses_post(
|
||||
/* translators: 1. Opening anchor tag. 2. Closing anchor tag. */
|
||||
__( 'Your account is pending verification. Please click the link in your email to activate your account. No email? %1$sSend a new activation code.%2$s', 'easy-digital-downloads' )
|
||||
),
|
||||
'<a href="' . esc_url( edd_get_user_verification_request_url() ) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
@ -10,7 +10,7 @@ $download_files = edd_get_download_files( $item->product_id, $item->price_id );
|
||||
foreach ( $download_files as $filekey => $file ) :
|
||||
?>
|
||||
<li class="edd_download_file">
|
||||
<a href="<?php echo esc_url( edd_get_download_file_url( $order->payment_key, $order->email, $filekey, $item->product_id, $item->price_id ) ); ?>" class="edd_download_file_link"><?php echo esc_html( edd_get_file_name( $file ) ); ?></a>
|
||||
<a href="<?php echo esc_url( edd_get_download_file_url( $order, $order->email, $filekey, $item->product_id, $item->price_id ) ); ?>" class="edd_download_file_link"><?php echo esc_html( edd_get_file_name( $file ) ); ?></a>
|
||||
</li>
|
||||
<?php
|
||||
/**
|
||||
@ -42,7 +42,7 @@ $download_files = edd_get_download_files( $item->product_id, $item->price_id );
|
||||
foreach ( $download_files as $filekey => $file ) :
|
||||
?>
|
||||
<li class="edd_download_file">
|
||||
<a href="<?php echo esc_url( edd_get_download_file_url( $order->payment_key, $order->email, $filekey, $bundle_item, $bundle_item_price_id ) ); ?>" class="edd_download_file_link"><?php echo esc_html( edd_get_file_name( $file ) ); ?></a>
|
||||
<a href="<?php echo esc_url( edd_get_download_file_url( $order, $order->email, $filekey, $bundle_item, $bundle_item_price_id ) ); ?>" class="edd_download_file_link"><?php echo esc_html( edd_get_file_name( $file ) ); ?></a>
|
||||
</li>
|
||||
<?php
|
||||
/**
|
||||
|
@ -166,6 +166,11 @@ final class Easy_Digital_Downloads {
|
||||
*/
|
||||
public $components = array();
|
||||
|
||||
/**
|
||||
* Pro Install
|
||||
*/
|
||||
private $pro = false;
|
||||
|
||||
/**
|
||||
* Main Easy_Digital_Downloads Instance.
|
||||
*
|
||||
@ -213,7 +218,6 @@ final class Easy_Digital_Downloads {
|
||||
self::$instance->email_summary_cron = new EDD_Email_Summary_Cron();
|
||||
self::$instance->payment_stats = new EDD_Payment_Stats();
|
||||
self::$instance->cart = new EDD_Cart();
|
||||
self::$instance->tracking = new EDD_Tracking();
|
||||
self::$instance->structured_data = new EDD\Structured_Data();
|
||||
self::$instance->notifications = new \EDD\Database\NotificationsDB();
|
||||
self::$instance->extensionRegistry = new \EDD\Extensions\ExtensionRegistry();
|
||||
@ -229,6 +233,19 @@ final class Easy_Digital_Downloads {
|
||||
|
||||
self::$instance->registerApiEndpoints();
|
||||
|
||||
// Check if the pro code is present.
|
||||
if ( class_exists( '\\EDD\\Pro\\Core' ) ) {
|
||||
self::$instance->pro = true;
|
||||
if ( edd_is_pro() ) {
|
||||
new EDD\Pro\Core();
|
||||
}
|
||||
}
|
||||
if ( ! edd_is_pro() && class_exists( '\\EDD\\Lite\\Core' ) ) {
|
||||
new EDD\Lite\Core();
|
||||
}
|
||||
|
||||
self::$instance->tracking = edd_is_pro() ? new EDD\Pro\Telemetry\Tracking() : new EDD_Tracking();
|
||||
|
||||
// Return the instance
|
||||
return self::$instance;
|
||||
}
|
||||
@ -285,6 +302,16 @@ final class Easy_Digital_Downloads {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the current install is a pro install.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @return bool
|
||||
*/
|
||||
public function is_pro() {
|
||||
return $this->pro;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the main loading class has been instantiated or not.
|
||||
*
|
||||
@ -310,7 +337,10 @@ final class Easy_Digital_Downloads {
|
||||
* @param string $file
|
||||
*/
|
||||
private static function setup_instance( $file = '' ) {
|
||||
self::$instance = new Easy_Digital_Downloads;
|
||||
if ( empty( $file ) && defined( EDD_PLUGIN_FILE ) ) {
|
||||
$file = EDD_PLUGIN_FILE;
|
||||
}
|
||||
self::$instance = new Easy_Digital_Downloads();
|
||||
self::$instance->file = $file;
|
||||
}
|
||||
|
||||
@ -325,27 +355,7 @@ final class Easy_Digital_Downloads {
|
||||
|
||||
// Plugin version.
|
||||
if ( ! defined( 'EDD_VERSION' ) ) {
|
||||
define( 'EDD_VERSION', '3.1.0.4' );
|
||||
}
|
||||
|
||||
// Plugin Root File.
|
||||
if ( ! defined( 'EDD_PLUGIN_FILE' ) ) {
|
||||
define( 'EDD_PLUGIN_FILE', $this->file );
|
||||
}
|
||||
|
||||
// Plugin Base Name.
|
||||
if ( ! defined( 'EDD_PLUGIN_BASE' ) ) {
|
||||
define( 'EDD_PLUGIN_BASE', plugin_basename( EDD_PLUGIN_FILE ) );
|
||||
}
|
||||
|
||||
// Plugin Folder Path.
|
||||
if ( ! defined( 'EDD_PLUGIN_DIR' ) ) {
|
||||
define( 'EDD_PLUGIN_DIR', plugin_dir_path( EDD_PLUGIN_FILE ) );
|
||||
}
|
||||
|
||||
// Plugin Folder URL.
|
||||
if ( ! defined( 'EDD_PLUGIN_URL' ) ) {
|
||||
define( 'EDD_PLUGIN_URL', plugin_dir_url( EDD_PLUGIN_FILE ) );
|
||||
define( 'EDD_VERSION', '3.1.1.2' );
|
||||
}
|
||||
|
||||
// Make sure CAL_GREGORIAN is defined.
|
||||
@ -524,8 +534,6 @@ final class Easy_Digital_Downloads {
|
||||
|
||||
// Old Database Components
|
||||
require_once EDD_PLUGIN_DIR . 'includes/class-edd-db.php';
|
||||
|
||||
require_once EDD_PLUGIN_DIR . 'includes/database/NotificationsDB.php';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -642,8 +650,6 @@ final class Easy_Digital_Downloads {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/cart/actions.php';
|
||||
|
||||
// Currency
|
||||
require_once EDD_PLUGIN_DIR . 'includes/currency/class-currency.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/currency/class-money-formatter.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/currency/functions.php';
|
||||
|
||||
// Gateways
|
||||
@ -678,11 +684,6 @@ final class Easy_Digital_Downloads {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/notes/functions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/notes/meta.php';
|
||||
|
||||
// Notifications
|
||||
require_once EDD_PLUGIN_DIR . 'includes/models/Notification.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/utils/EnvironmentChecker.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/utils/NotificationImporter.php';
|
||||
|
||||
// Orders
|
||||
require_once EDD_PLUGIN_DIR . 'includes/orders/classes/class-order.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/orders/classes/class-order-address.php';
|
||||
@ -768,7 +769,6 @@ final class Easy_Digital_Downloads {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/customers/customer-actions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/privacy-functions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/utils/class-tokenizer.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/class-pass-manager.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/user-functions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/query-filters.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/tax-functions.php';
|
||||
@ -791,7 +791,6 @@ final class Easy_Digital_Downloads {
|
||||
* @since 3.0
|
||||
*/
|
||||
private function include_admin() {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/add-ons.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/admin-footer.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/admin-actions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/class-edd-notices.php';
|
||||
@ -840,19 +839,10 @@ final class Easy_Digital_Downloads {
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/upgrades.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/upgrades/v3/upgrade-actions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/tools/tools-actions.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/class-extension-manager.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/abstract-extension.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/class-extension-product-data.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/product-education/class-wpsmtp.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/product-education/class-recurring.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/product-education/class-reviews.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/product-education/class-email-marketing.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/extensions/product-education/class-invoices.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/settings/settings-compatibility.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/admin-deprecated-functions.php';
|
||||
|
||||
require_once EDD_PLUGIN_DIR . 'includes/libraries/class-persistent-dismissible.php';
|
||||
require_once EDD_PLUGIN_DIR . 'includes/admin/promos/class-promo-handler.php';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,7 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
|
||||
public function __construct() {
|
||||
$this->api = new EDD_API();
|
||||
edd_do_automatic_upgrades();
|
||||
}
|
||||
|
||||
|
||||
@ -506,13 +507,15 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
$number = 1;
|
||||
$status = 'complete';
|
||||
$id = false;
|
||||
$price_id = false;
|
||||
$price_id = null;
|
||||
$tax = 0;
|
||||
$email = 'guest@edd.local';
|
||||
$fname = 'Pippin';
|
||||
$lname = 'Williamson';
|
||||
$date = false;
|
||||
$range = 30;
|
||||
$currency = edd_get_currency();
|
||||
$gateway = 'manual';
|
||||
|
||||
$generate_users = false;
|
||||
|
||||
@ -670,6 +673,18 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
);
|
||||
}
|
||||
|
||||
// Allow random currencies.
|
||||
if ( ! empty( $assoc_args['currency'] ) && 'random' === $assoc_args['currency'] ) {
|
||||
$currencies = array( 'USD', 'EUR', 'GBP' );
|
||||
$currency = $currencies[ array_rand( $currencies ) ];
|
||||
}
|
||||
|
||||
// Allow random gateways.
|
||||
if ( ! empty( $assoc_args['gateway'] ) && 'random' === $assoc_args['gateway'] ) {
|
||||
$gateways = array_keys( edd_get_payment_gateways() );
|
||||
$gateway = $gateways[ array_rand( $gateways ) ];
|
||||
}
|
||||
|
||||
// Build purchase data.
|
||||
$purchase_data = array(
|
||||
'price' => edd_sanitize_amount( $total ),
|
||||
@ -677,7 +692,7 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
'purchase_key' => strtolower( md5( uniqid() ) ),
|
||||
'user_email' => $email,
|
||||
'user_info' => $user_info,
|
||||
'currency' => edd_get_currency(),
|
||||
'currency' => $currency,
|
||||
'downloads' => $final_downloads,
|
||||
'cart_details' => $cart_details,
|
||||
'status' => 'pending',
|
||||
@ -700,7 +715,7 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
if ( ! empty( $timestring ) ) {
|
||||
$payment = new EDD_Payment( $order_id );
|
||||
$payment->completed_date = $timestring;
|
||||
$payment->gateway = 'manual';
|
||||
$payment->gateway = $gateway;
|
||||
$payment->save();
|
||||
}
|
||||
|
||||
@ -930,7 +945,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
WP_CLI::line( __( 'Old Records: ', 'easy-digital-downloads' ) . $old_count[0] );
|
||||
WP_CLI::line( __( 'New Records: ', 'easy-digital-downloads' ) . $new_count );
|
||||
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'migrate_discounts' );
|
||||
|
||||
} else {
|
||||
@ -1054,7 +1068,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
WP_CLI::line( __( 'New Records: ', 'easy-digital-downloads' ) . $new_count );
|
||||
}
|
||||
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'migrate_logs' );
|
||||
|
||||
}
|
||||
@ -1162,7 +1175,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
WP_CLI::line( __( 'New order notes: ', 'easy-digital-downloads' ) . $new_count );
|
||||
}
|
||||
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'migrate_order_notes' );
|
||||
}
|
||||
|
||||
@ -1264,7 +1276,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
WP_CLI::line( __( 'New customer notes: ', 'easy-digital-downloads' ) . $new_count );
|
||||
}
|
||||
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'migrate_customer_notes' );
|
||||
}
|
||||
}
|
||||
@ -1466,7 +1477,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
WP_CLI::line( __( 'Migration complete: Customer Email Addresses', 'easy-digital-downloads' ) );
|
||||
}
|
||||
|
||||
edd_update_db_version();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1530,7 +1540,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
WP_CLI::line( __( 'Old Records: ', 'easy-digital-downloads' ) . count( $tax_rates ) );
|
||||
WP_CLI::line( __( 'New Records: ', 'easy-digital-downloads' ) . $new_count );
|
||||
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'migrate_tax_rates' );
|
||||
}
|
||||
|
||||
@ -1767,7 +1776,6 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
$refund_count = edd_count_orders( array( 'type' => 'refund' ) );
|
||||
WP_CLI::line( __( 'Refund Records Created: ', 'easy-digital-downloads' ) . $refund_count );
|
||||
|
||||
edd_update_db_version();
|
||||
edd_set_upgrade_complete( 'migrate_orders' );
|
||||
|
||||
$progress->tick();
|
||||
@ -1943,10 +1951,20 @@ class EDD_CLI extends WP_CLI_Command {
|
||||
* @var \EDD\Database\Tables\Customers|false $customer_table
|
||||
*/
|
||||
$customer_table = edd_get_component_interface( 'customer', 'table' );
|
||||
if ( $customer_table instanceof \EDD\Database\Tables\Customers && $customer_table->column_exists( 'payment_ids' ) ) {
|
||||
if ( $customer_table instanceof \EDD\Database\Tables\Customers ) {
|
||||
WP_CLI::line( __( 'Updating customers database table.', 'easy-digital-downloads' ) );
|
||||
|
||||
$wpdb->query( "ALTER TABLE {$wpdb->edd_customers} DROP `payment_ids`" );
|
||||
if ( $customer_table->column_exists( 'payment_ids' ) ) {
|
||||
WP_CLI::line( __( 'Removing Payment IDs column.', 'easy-digital-downloads' ) );
|
||||
|
||||
$wpdb->query( "ALTER TABLE {$wpdb->edd_customers} DROP `payment_ids`" );
|
||||
}
|
||||
|
||||
if ( $customer_table->column_exists( 'notes' ) ) {
|
||||
WP_CLI::line( __( 'Removing notes column.', 'easy-digital-downloads' ) );
|
||||
|
||||
$wpdb->query( "ALTER TABLE {$wpdb->edd_customers} DROP `notes`" );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -11,6 +11,9 @@
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use EDD\Licensing\API;
|
||||
use EDD\Licensing\License;
|
||||
|
||||
if ( ! class_exists( 'EDD_License' ) ) :
|
||||
|
||||
/**
|
||||
@ -24,7 +27,31 @@ class EDD_License {
|
||||
private $item_shortname;
|
||||
private $version;
|
||||
private $author;
|
||||
private $api_url = 'https://easydigitaldownloads.com/edd-sl-api/';
|
||||
private $api_url;
|
||||
private $api_handler;
|
||||
|
||||
/**
|
||||
* The pass manager.
|
||||
*
|
||||
* @var \EDD\Admin\Pass_Manager
|
||||
*/
|
||||
private $pass_manager;
|
||||
|
||||
/**
|
||||
* The EDD license object.
|
||||
* This contains standard license data (from the API response) and the license key.
|
||||
*
|
||||
* @var \EDD\Licensing\License
|
||||
*/
|
||||
private $edd_license;
|
||||
|
||||
/**
|
||||
* Whether the license being checked is a pro license.
|
||||
*
|
||||
* @since 3.1.1
|
||||
* @var bool
|
||||
*/
|
||||
private $is_pro_license = false;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
@ -47,23 +74,18 @@ class EDD_License {
|
||||
|
||||
$this->item_shortname = 'edd_' . preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->item_name ) ) );
|
||||
$this->version = $_version;
|
||||
$this->license = trim( edd_get_option( $this->item_shortname . '_license_key', '' ) );
|
||||
$this->author = $_author;
|
||||
$this->api_url = is_null( $_api_url ) ? $this->api_url : $_api_url;
|
||||
|
||||
/**
|
||||
* Allows for backwards compatibility with old license options,
|
||||
* i.e. if the plugins had license key fields previously, the license
|
||||
* handler will automatically pick these up and use those in lieu of the
|
||||
* user having to reactive their license.
|
||||
*/
|
||||
if ( ! empty( $_optname ) ) {
|
||||
$opt = edd_get_option( $_optname, false );
|
||||
|
||||
if ( isset( $opt ) && empty( $this->license ) ) {
|
||||
$this->license = trim( $opt );
|
||||
$this->edd_license = new License( $this->item_name, $_optname );
|
||||
if ( empty( $this->edd_license->key ) ) {
|
||||
$this->edd_license = new License( 'pro' );
|
||||
if ( ! empty( $this->edd_license->key ) ) {
|
||||
$this->is_pro_license = true;
|
||||
}
|
||||
}
|
||||
$this->license = $this->edd_license->key;
|
||||
$this->author = $_author;
|
||||
$this->api_handler = new API();
|
||||
$this->api_url = is_null( $_api_url ) ? $this->api_handler->get_url() : $_api_url;
|
||||
$this->pass_manager = new \EDD\Admin\Pass_Manager();
|
||||
|
||||
// Setup hooks
|
||||
$this->includes();
|
||||
@ -85,7 +107,6 @@ class EDD_License {
|
||||
}
|
||||
$edd_licensed_products[] = $this->item_shortname;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,12 +135,6 @@ class EDD_License {
|
||||
// Display help text at the top of the Licenses tab
|
||||
add_action( 'edd_settings_tab_top', array( $this, 'license_help_text' ) );
|
||||
|
||||
// Activate license key on settings save
|
||||
add_action( 'admin_init', array( $this, 'activate_license' ) );
|
||||
|
||||
// Deactivate license key
|
||||
add_action( 'admin_init', array( $this, 'deactivate_license' ) );
|
||||
|
||||
// Check that license is valid once per week
|
||||
if ( edd_doing_cron() ) {
|
||||
add_action( 'edd_weekly_scheduled_events', array( $this, 'weekly_license_check' ) );
|
||||
@ -160,23 +175,27 @@ class EDD_License {
|
||||
}
|
||||
|
||||
$license = $this->license;
|
||||
// Fall back to the highest license key if one is not saved for this extension.
|
||||
// Fall back to the highest license key if one is not saved for this extension or there isn't a pro license.
|
||||
if ( empty( $license ) ) {
|
||||
$pass_manager = new \EDD\Admin\Pass_Manager();
|
||||
if ( $pass_manager->highest_license_key ) {
|
||||
$license = $pass_manager->highest_license_key;
|
||||
if ( $this->pass_manager->highest_license_key ) {
|
||||
$license = $this->pass_manager->highest_license_key;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't check for updates if there isn't a license key.
|
||||
if ( empty( $license ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'version' => $this->version,
|
||||
'license' => $license,
|
||||
'author' => $this->author,
|
||||
'beta' => function_exists( 'edd_extension_has_beta_support' ) && edd_extension_has_beta_support( $this->item_shortname ),
|
||||
'version' => $this->version,
|
||||
'license' => $license,
|
||||
'author' => $this->author,
|
||||
'beta' => function_exists( 'edd_extension_has_beta_support' ) && edd_extension_has_beta_support( $this->item_shortname ),
|
||||
);
|
||||
|
||||
if ( ! empty( $this->item_id ) ) {
|
||||
$args['item_id'] = $this->item_id;
|
||||
$args['item_id'] = $this->item_id;
|
||||
} else {
|
||||
$args['item_name'] = $this->item_name;
|
||||
}
|
||||
@ -199,11 +218,14 @@ class EDD_License {
|
||||
return array_merge( $settings, array(
|
||||
array(
|
||||
'id' => $this->item_shortname . '_license_key',
|
||||
'name' => sprintf( __( '%1$s', 'easy-digital-downloads' ), $this->item_name ),
|
||||
'name' => $this->item_name,
|
||||
'desc' => '',
|
||||
'type' => 'license_key',
|
||||
'options' => array( 'is_valid_license_option' => $this->item_shortname . '_license_active' ),
|
||||
'size' => 'regular'
|
||||
'options' => array(
|
||||
'is_valid_license_option' => $this->item_shortname . '_license_active',
|
||||
'item_id' => $this->item_id,
|
||||
),
|
||||
'size' => 'regular',
|
||||
)
|
||||
) );
|
||||
}
|
||||
@ -226,208 +248,42 @@ class EDD_License {
|
||||
return;
|
||||
}
|
||||
|
||||
echo '<p>' . sprintf(
|
||||
__( 'Enter your extension license keys here to receive updates for purchased extensions. If your license key has expired, please <a href="%s" target="_blank">renew your license</a>.', 'easy-digital-downloads' ),
|
||||
'https://docs.easydigitaldownloads.com/article/1000-license-renewal'
|
||||
) . '</p>';
|
||||
?>
|
||||
<div class="edd-licenses__description">
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
__( 'Enter your extension license keys here to receive updates for purchased extensions. If your license key has expired, please %srenew your license%s.', 'easy-digital-downloads' ),
|
||||
'<a href="https://easydigitaldownloads.com/docs/license-renewal/" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php if ( ! $this->pass_manager->highest_license_key ) : ?>
|
||||
<p>
|
||||
<?php
|
||||
$url = edd_get_admin_url(
|
||||
array(
|
||||
'page' => 'edd-settings',
|
||||
'tab' => 'general',
|
||||
)
|
||||
);
|
||||
printf(
|
||||
__( 'Have a pass? You\'re ready to set up EDD (Pro). %1$sActivate Your Pass%2$s' ),
|
||||
'<a href="' . esc_url( $url ) . '" class="button button-primary">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
$has_ran = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the supplied license key is for a pass, updates the `edd_pass_licenses` option with
|
||||
* the pass ID and the date it was checked.
|
||||
*
|
||||
* Note: It's intentional that the `edd_pass_licenses` option is always updated, even if
|
||||
* the provided license data is not for a pass. This is so we have a clearer idea
|
||||
* of when the checks started coming through. If the option doesn't exist in the DB
|
||||
* at all, then we haven't checked any licenses.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @param string $license
|
||||
* @param object $api_data
|
||||
*/
|
||||
private function maybe_set_pass_flag( $license, $api_data ) {
|
||||
$passes = get_option( 'edd_pass_licenses' );
|
||||
$passes = ! empty( $passes ) ? json_decode( $passes, true ) : array();
|
||||
|
||||
if ( ! empty( $api_data->pass_id ) && ! empty( $api_data->license ) && 'valid' === $api_data->license ) {
|
||||
$passes[ $license ] = array(
|
||||
'pass_id' => intval( $api_data->pass_id ),
|
||||
'time_checked' => time()
|
||||
);
|
||||
} else if ( array_key_exists( $license, $passes ) ) {
|
||||
unset( $passes[ $license ] );
|
||||
}
|
||||
|
||||
update_option( 'edd_pass_licenses', json_encode( $passes ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the pass flag for the supplied license. This happens when a license
|
||||
* is deactivated.
|
||||
*
|
||||
* @since 2.10.6
|
||||
*
|
||||
* @param string $license
|
||||
*/
|
||||
private function maybe_remove_pass_flag( $license ) {
|
||||
$passes = get_option( 'edd_pass_licenses' );
|
||||
$passes = ! empty( $passes ) ? json_decode( $passes, true ) : array();
|
||||
|
||||
if ( array_key_exists( $license, $passes ) ) {
|
||||
unset( $passes[ $license ] );
|
||||
}
|
||||
|
||||
update_option( 'edd_pass_licenses', json_encode( $passes ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the license key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function activate_license() {
|
||||
|
||||
if ( ! isset( $_POST['edd_settings'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_REQUEST[ $this->item_shortname . '_license_key-nonce'] ) || ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce'], $this->item_shortname . '_license_key-nonce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $_POST['edd_settings'][ $this->item_shortname . '_license_key'] ) ) {
|
||||
delete_option( $this->item_shortname . '_license_active' );
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( false !== strpos( $key, 'license_key_deactivate' ) ) {
|
||||
// Don't activate a key when deactivating a different key
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$details = get_option( $this->item_shortname . '_license_active' );
|
||||
|
||||
if ( is_object( $details ) && ! empty( $details->license ) && 'valid' === $details->license ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$license = sanitize_text_field( $_POST['edd_settings'][ $this->item_shortname . '_license_key'] );
|
||||
|
||||
if ( empty( $license ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Data to send to the API
|
||||
$api_params = array(
|
||||
'edd_action' => 'activate_license',
|
||||
'license' => $license,
|
||||
'item_name' => urlencode( $this->item_name ),
|
||||
'url' => home_url()
|
||||
);
|
||||
|
||||
if ( ! empty( $this->item_id ) ) {
|
||||
$api_params['item_id'] = $this->item_id;
|
||||
}
|
||||
|
||||
// Call the API
|
||||
$response = wp_remote_post(
|
||||
$this->api_url,
|
||||
array(
|
||||
'timeout' => 15,
|
||||
'sslverify' => false,
|
||||
'body' => $api_params
|
||||
)
|
||||
);
|
||||
|
||||
// Make sure there are no errors
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell WordPress to look for updates
|
||||
set_site_transient( 'update_plugins', null );
|
||||
|
||||
// Decode license data
|
||||
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
$this->maybe_set_pass_flag( $license, $license_data );
|
||||
|
||||
// Clear the option for licensed extensions to force regeneration.
|
||||
if ( ! empty( $api_data->license ) && 'valid' === $api_data->license ) {
|
||||
delete_option( 'edd_licensed_extensions' );
|
||||
}
|
||||
|
||||
update_option( $this->item_shortname . '_license_active', $license_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the license key
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function deactivate_license() {
|
||||
|
||||
if ( ! isset( $_POST['edd_settings'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST['edd_settings'][ $this->item_shortname . '_license_key'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce'], $this->item_shortname . '_license_key-nonce' ) ) {
|
||||
wp_die( __( 'Nonce verification failed', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run on deactivate button press
|
||||
if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate'] ) ) {
|
||||
|
||||
// Data to send to the API
|
||||
$api_params = array(
|
||||
'edd_action' => 'deactivate_license',
|
||||
'license' => $this->license,
|
||||
'item_name' => urlencode( $this->item_name ),
|
||||
'url' => home_url()
|
||||
);
|
||||
|
||||
if ( ! empty( $this->item_id ) ) {
|
||||
$api_params['item_id'] = $this->item_id;
|
||||
}
|
||||
|
||||
// Call the API
|
||||
$response = wp_remote_post(
|
||||
$this->api_url,
|
||||
array(
|
||||
'timeout' => 15,
|
||||
'sslverify' => false,
|
||||
'body' => $api_params
|
||||
)
|
||||
);
|
||||
|
||||
// Make sure there are no errors
|
||||
if ( is_wp_error( $response ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->maybe_remove_pass_flag( $this->license );
|
||||
|
||||
delete_option( $this->item_shortname . '_license_active' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if license key is valid once per week
|
||||
*
|
||||
@ -436,8 +292,14 @@ class EDD_License {
|
||||
*/
|
||||
public function weekly_license_check() {
|
||||
|
||||
// If a pro license is active, that license check is handled separately.
|
||||
if ( $this->is_pro_license ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't fire when saving settings.
|
||||
if ( ! empty( $_POST['edd_settings'] ) ) {
|
||||
return; // Don't fire when saving settings
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $this->license ) ) {
|
||||
@ -446,36 +308,22 @@ class EDD_License {
|
||||
|
||||
// data to send in our API request
|
||||
$api_params = array(
|
||||
'edd_action'=> 'check_license',
|
||||
'license' => $this->license,
|
||||
'item_name' => urlencode( $this->item_name ),
|
||||
'url' => home_url()
|
||||
'edd_action' => 'check_license',
|
||||
'license' => $this->license,
|
||||
'item_name' => urlencode( $this->item_name ),
|
||||
);
|
||||
|
||||
if ( ! empty( $this->item_id ) ) {
|
||||
$api_params['item_id'] = $this->item_id;
|
||||
}
|
||||
|
||||
// Call the API
|
||||
$response = wp_remote_post(
|
||||
$this->api_url,
|
||||
array(
|
||||
'timeout' => 15,
|
||||
'sslverify' => false,
|
||||
'body' => $api_params
|
||||
)
|
||||
);
|
||||
|
||||
// make sure the response came back okay
|
||||
if ( is_wp_error( $response ) ) {
|
||||
$license_data = $this->api_handler->make_request( $api_params );
|
||||
if ( ! $license_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$license_data = json_decode( wp_remote_retrieve_body( $response ) );
|
||||
|
||||
$this->maybe_set_pass_flag( $this->license, $license_data );
|
||||
|
||||
update_option( $this->item_shortname . '_license_active', $license_data );
|
||||
$this->pass_manager->maybe_set_pass_flag( $this->license, $license_data );
|
||||
$this->edd_license->save( $license_data );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -496,9 +344,9 @@ class EDD_License {
|
||||
|
||||
$messages = array();
|
||||
|
||||
$license = get_option( $this->item_shortname . '_license_active' );
|
||||
$license = $this->edd_license;
|
||||
|
||||
if ( is_object( $license ) && ( empty( $license->license ) || 'valid' !== $license->license ) && empty( $showed_invalid_message ) ) {
|
||||
if ( ( empty( $license->license ) || 'valid' !== $license->license ) && empty( $showed_invalid_message ) ) {
|
||||
if ( empty( $_GET['tab'] ) || 'licenses' !== $_GET['tab'] ) {
|
||||
|
||||
$messages[] = sprintf(
|
||||
@ -528,9 +376,9 @@ class EDD_License {
|
||||
public function plugin_row_license_missing( $plugin_data, $version_info ) {
|
||||
static $showed_imissing_key_message = array();
|
||||
|
||||
$license = get_option( $this->item_shortname . '_license_active' );
|
||||
$license = $this->edd_license;
|
||||
|
||||
if ( ( ! is_object( $license ) || empty( $license->license ) || 'valid' !== $license->license ) && empty( $showed_imissing_key_message[ $this->item_shortname ] ) ) {
|
||||
if ( ( empty( $license->license ) || 'valid' !== $license->license ) && empty( $showed_imissing_key_message[ $this->item_shortname ] ) ) {
|
||||
echo ' <strong><a href="' . esc_url( admin_url( 'edit.php?post_type=download&page=edd-settings&tab=licenses' ) ) . '">' . __( 'Enter valid license key for automatic updates.', 'easy-digital-downloads' ) . '</a></strong>';
|
||||
$showed_imissing_key_message[ $this->item_shortname ] = true;
|
||||
}
|
||||
@ -592,6 +440,134 @@ class EDD_License {
|
||||
delete_option( 'edd_stripe_payment_gateway_license_key_active' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Activate the license key.
|
||||
*
|
||||
* @deprecated 3.1.1
|
||||
* @return void
|
||||
*/
|
||||
public function activate_license() {
|
||||
|
||||
if ( ! isset( $_POST['edd_settings'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_REQUEST[ $this->item_shortname . '_license_key-nonce'] ) || ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce'], $this->item_shortname . '_license_key-nonce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( empty( $_POST['edd_settings'][ $this->item_shortname . '_license_key'] ) ) {
|
||||
delete_option( $this->item_shortname . '_license_active' );
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $_POST as $key => $value ) {
|
||||
if ( false !== strpos( $key, 'license_key_deactivate' ) ) {
|
||||
// Don't activate a key when deactivating a different key
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 'valid' === $this->edd_license->license ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$license = sanitize_text_field( $_POST['edd_settings'][ $this->item_shortname . '_license_key' ] );
|
||||
|
||||
if ( empty( $license ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Data to send to the API
|
||||
$api_params = array(
|
||||
'edd_action' => 'activate_license',
|
||||
'license' => $license,
|
||||
'item_name' => urlencode( $this->item_name ),
|
||||
'url' => home_url()
|
||||
);
|
||||
|
||||
if ( ! empty( $this->item_id ) ) {
|
||||
$api_params['item_id'] = $this->item_id;
|
||||
}
|
||||
|
||||
// Call the API
|
||||
$license_data = $this->api_handler->make_request( $api_params );
|
||||
|
||||
// Make sure there are no errors
|
||||
if ( ! $license_data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Tell WordPress to look for updates
|
||||
set_site_transient( 'update_plugins', null );
|
||||
|
||||
$this->pass_manager->maybe_set_pass_flag( $license, $license_data );
|
||||
|
||||
// Clear the option for licensed extensions to force regeneration.
|
||||
if ( ! empty( $license_data->license ) && 'valid' === $license_data->license ) {
|
||||
delete_option( 'edd_licensed_extensions' );
|
||||
}
|
||||
|
||||
$this->edd_license->save( $license_data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate the license key
|
||||
*
|
||||
* @deprecated 3.1.1
|
||||
* @return void
|
||||
*/
|
||||
public function deactivate_license() {
|
||||
|
||||
if ( ! isset( $_POST['edd_settings'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $_POST['edd_settings'][ $this->item_shortname . '_license_key'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! wp_verify_nonce( $_REQUEST[ $this->item_shortname . '_license_key-nonce'], $this->item_shortname . '_license_key-nonce' ) ) {
|
||||
wp_die( __( 'Nonce verification failed', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
|
||||
}
|
||||
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run on deactivate button press
|
||||
if ( isset( $_POST[ $this->item_shortname . '_license_key_deactivate'] ) ) {
|
||||
|
||||
// Data to send to the API
|
||||
$api_params = array(
|
||||
'edd_action' => 'deactivate_license',
|
||||
'license' => $this->license,
|
||||
'item_name' => urlencode( $this->item_name ),
|
||||
'url' => home_url()
|
||||
);
|
||||
|
||||
if ( ! empty( $this->item_id ) ) {
|
||||
$api_params['item_id'] = $this->item_id;
|
||||
}
|
||||
|
||||
// Call the API
|
||||
$response = $this->api_handler->make_request( $api_params );
|
||||
|
||||
// Make sure there are no errors
|
||||
if ( ! $response ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->pass_manager->maybe_remove_pass_flag( $this->license );
|
||||
|
||||
delete_option( $this->item_shortname . '_license_active' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endif; // end class_exists check
|
||||
|
@ -0,0 +1,507 @@
|
||||
<?php
|
||||
/**
|
||||
* Requirements
|
||||
*
|
||||
* The class to check the requirements and load the plugin if met.
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2022, Easy Digital Downloads, LLC
|
||||
* @license GPL2+
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
final class EDD_Requirements_Check {
|
||||
|
||||
/**
|
||||
* Plugin file
|
||||
*
|
||||
* @since 3.0
|
||||
* @var string
|
||||
*/
|
||||
private $file = '';
|
||||
|
||||
/**
|
||||
* Plugin basename
|
||||
*
|
||||
* @since 3.0
|
||||
* @var string
|
||||
*/
|
||||
private $base = '';
|
||||
|
||||
/**
|
||||
* Requirements array
|
||||
*
|
||||
* @todo Extend WP_Dependencies
|
||||
* @var array
|
||||
* @since 3.0
|
||||
*/
|
||||
private $requirements = array(
|
||||
|
||||
// PHP
|
||||
'php' => array(
|
||||
'minimum' => '7.1',
|
||||
'name' => 'PHP',
|
||||
'exists' => true,
|
||||
'current' => false,
|
||||
'checked' => false,
|
||||
'met' => false,
|
||||
),
|
||||
|
||||
// WordPress
|
||||
'wp' => array(
|
||||
'minimum' => '5.4',
|
||||
'name' => 'WordPress',
|
||||
'exists' => true,
|
||||
'current' => false,
|
||||
'checked' => false,
|
||||
'met' => false,
|
||||
),
|
||||
);
|
||||
|
||||
/**
|
||||
* Setup plugin requirements
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// Setup file & base
|
||||
$this->file = EDD_PLUGIN_FILE;
|
||||
$this->base = EDD_PLUGIN_BASE;
|
||||
|
||||
// Always load translations
|
||||
add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
|
||||
|
||||
// Load or quit
|
||||
$this->met()
|
||||
? $this->load()
|
||||
: $this->quit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Quit without loading
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
private function quit() {
|
||||
add_action( 'admin_head', array( $this, 'admin_head' ) );
|
||||
add_filter( "plugin_action_links_{$this->base}", array( $this, 'plugin_row_links' ) );
|
||||
add_action( "after_plugin_row_{$this->base}", array( $this, 'plugin_row_notice' ) );
|
||||
}
|
||||
|
||||
/** Specific Methods ******************************************************/
|
||||
|
||||
/**
|
||||
* Load normally
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
private function load() {
|
||||
|
||||
require_once dirname( $this->file ) . '/vendor/autoload.php';
|
||||
|
||||
// Maybe include the bundled bootstrapper
|
||||
if ( ! class_exists( 'Easy_Digital_Downloads' ) ) {
|
||||
require_once dirname( $this->file ) . '/includes/class-easy-digital-downloads.php';
|
||||
}
|
||||
|
||||
// Maybe hook-in the bootstrapper
|
||||
if ( class_exists( 'Easy_Digital_Downloads' ) ) {
|
||||
|
||||
// Bootstrap to plugins_loaded before priority 10 to make sure
|
||||
// add-ons are loaded after us.
|
||||
add_action( 'plugins_loaded', array( $this, 'bootstrap' ), 4 );
|
||||
|
||||
// Register the activation hook
|
||||
register_activation_hook( $this->file, array( $this, 'install' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install, usually on an activation hook.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function install() {
|
||||
|
||||
// Bootstrap to include all of the necessary files.
|
||||
$this->bootstrap();
|
||||
|
||||
// Network wide?
|
||||
$network_wide = ! empty( $_GET['networkwide'] )
|
||||
? (bool) $_GET['networkwide']
|
||||
: false;
|
||||
|
||||
// Call the installer directly during the activation hook.
|
||||
edd_install( $network_wide );
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap everything.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function bootstrap() {
|
||||
\Easy_Digital_Downloads::instance( $this->file );
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific URL for an external requirements page.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_url() {
|
||||
return 'https://easydigitaldownloads.com/recommended-wordpress-hosting/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific text to quickly explain what's wrong.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_text() {
|
||||
esc_html_e( 'This plugin is not fully active.', 'easy-digital-downloads' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific text to describe a single unmet requirement.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_description_text() {
|
||||
return esc_html__( 'Requires %1$s (%2$s), but (%3$s) is installed.', 'easy-digital-downloads' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific text to describe a single missing requirement.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_missing_text() {
|
||||
return esc_html__( 'Requires %1$s (%2$s), but it appears to be missing.', 'easy-digital-downloads' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific text used to link to an external requirements page.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_link() {
|
||||
return esc_html__( 'Requirements', 'easy-digital-downloads' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific aria label text to describe the requirements link.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_label() {
|
||||
return esc_html__( 'Easy Digital Download Requirements', 'easy-digital-downloads' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin specific text used in CSS to identify attribute IDs and classes.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
private function unmet_requirements_name() {
|
||||
return 'edd-requirements';
|
||||
}
|
||||
|
||||
/** Agnostic Methods ******************************************************/
|
||||
|
||||
/**
|
||||
* Plugin agnostic method to output the additional plugin row
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function plugin_row_notice() {
|
||||
// wp_is_auto_update_enabled_for_type was introduced in WordPress 5.5.
|
||||
$colspan = function_exists( 'wp_is_auto_update_enabled_for_type' ) && wp_is_auto_update_enabled_for_type( 'plugin' ) ? 2 : 1;
|
||||
?>
|
||||
<tr class="active <?php echo esc_attr( $this->unmet_requirements_name() ); ?>-row">
|
||||
<th class="check-column">
|
||||
<span class="dashicons dashicons-warning"></span>
|
||||
</th>
|
||||
<td class="column-primary">
|
||||
<?php $this->unmet_requirements_text(); ?>
|
||||
</td>
|
||||
<td class="column-description" colspan="<?php echo esc_attr( $colspan ); ?>">
|
||||
<?php $this->unmet_requirements_description(); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin agnostic method used to output all unmet requirement information
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
private function unmet_requirements_description() {
|
||||
foreach ( $this->requirements as $properties ) {
|
||||
if ( empty( $properties['met'] ) ) {
|
||||
$this->unmet_requirement_description( $properties );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin agnostic method to output specific unmet requirement information
|
||||
*
|
||||
* @since 3.0
|
||||
* @param array $requirement
|
||||
*/
|
||||
private function unmet_requirement_description( $requirement = array() ) {
|
||||
|
||||
// Requirement exists, but is out of date
|
||||
if ( ! empty( $requirement['exists'] ) ) {
|
||||
$text = sprintf(
|
||||
$this->unmet_requirements_description_text(),
|
||||
'<strong>' . esc_html( $requirement['name'] ) . '</strong>',
|
||||
'<strong>' . esc_html( $requirement['minimum'] ) . '</strong>',
|
||||
'<strong>' . esc_html( $requirement['current'] ) . '</strong>'
|
||||
);
|
||||
|
||||
// Requirement could not be found
|
||||
} else {
|
||||
$text = sprintf(
|
||||
$this->unmet_requirements_missing_text(),
|
||||
'<strong>' . esc_html( $requirement['name'] ) . '</strong>',
|
||||
'<strong>' . esc_html( $requirement['minimum'] ) . '</strong>'
|
||||
);
|
||||
}
|
||||
|
||||
// Output the description
|
||||
echo '<p>' . $text . '</p>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin agnostic method to output unmet requirements styling
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
public function admin_head() {
|
||||
|
||||
// Get the requirements row name
|
||||
$name = $this->unmet_requirements_name();
|
||||
?>
|
||||
|
||||
<style id="<?php echo esc_attr( $name ); ?>">
|
||||
.plugins tr[data-plugin="<?php echo esc_html( $this->base ); ?>"] th,
|
||||
.plugins tr[data-plugin="<?php echo esc_html( $this->base ); ?>"] td,
|
||||
.plugins .<?php echo esc_html( $name ); ?>-row th,
|
||||
.plugins .<?php echo esc_html( $name ); ?>-row td {
|
||||
background: #fff5f5;
|
||||
}
|
||||
.plugins tr[data-plugin="<?php echo esc_html( $this->base ); ?>"] th {
|
||||
box-shadow: none;
|
||||
}
|
||||
.plugins .<?php echo esc_html( $name ); ?>-row th span {
|
||||
margin-left: 6px;
|
||||
color: #dc3232;
|
||||
}
|
||||
.plugins tr[data-plugin="<?php echo esc_html( $this->base ); ?>"] th,
|
||||
.plugins .<?php echo esc_html( $name ); ?>-row th.check-column {
|
||||
border-left: 4px solid #dc3232 !important;
|
||||
}
|
||||
.plugins .<?php echo esc_html( $name ); ?>-row .column-description p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.plugins .<?php echo esc_html( $name ); ?>-row .column-description p:not(:last-of-type) {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin agnostic method to add the "Requirements" link to row actions
|
||||
*
|
||||
* @since 3.0
|
||||
* @param array $links
|
||||
* @return array
|
||||
*/
|
||||
public function plugin_row_links( $links = array() ) {
|
||||
|
||||
// Add the Requirements link
|
||||
$links['requirements'] =
|
||||
'<a href="' . esc_url( $this->unmet_requirements_url() ) . '" aria-label="' . esc_attr( $this->unmet_requirements_label() ) . '">'
|
||||
. esc_html( $this->unmet_requirements_link() )
|
||||
. '</a>';
|
||||
|
||||
// Return links with Requirements link
|
||||
return $links;
|
||||
}
|
||||
|
||||
/** Checkers **************************************************************/
|
||||
|
||||
/**
|
||||
* Plugin specific requirements checker
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
private function check() {
|
||||
|
||||
// Loop through requirements
|
||||
foreach ( $this->requirements as $dependency => $properties ) {
|
||||
|
||||
// Which dependency are we checking?
|
||||
switch ( $dependency ) {
|
||||
|
||||
// PHP
|
||||
case 'php':
|
||||
$version = phpversion();
|
||||
break;
|
||||
|
||||
// WP
|
||||
case 'wp':
|
||||
$version = get_bloginfo( 'version' );
|
||||
break;
|
||||
|
||||
// Unknown
|
||||
default:
|
||||
$version = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Merge to original array
|
||||
if ( ! empty( $version ) ) {
|
||||
$this->requirements[ $dependency ] = array_merge(
|
||||
$this->requirements[ $dependency ],
|
||||
array(
|
||||
'current' => $version,
|
||||
'checked' => true,
|
||||
'met' => version_compare( $version, $properties['minimum'], '>=' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Have all requirements been met?
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function met() {
|
||||
|
||||
// Run the check
|
||||
$this->check();
|
||||
|
||||
$to_meet = wp_list_pluck( $this->requirements, 'met' );
|
||||
|
||||
// Look for unmet dependencies, and exit if so
|
||||
foreach ( $to_meet as $met ) {
|
||||
if ( empty( $met ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Translations **********************************************************/
|
||||
|
||||
/**
|
||||
* Plugin specific text-domain loader.
|
||||
*
|
||||
* @since 1.4
|
||||
* @return void
|
||||
*/
|
||||
public function load_textdomain() {
|
||||
|
||||
/*
|
||||
* Due to the introduction of language packs through translate.wordpress.org,
|
||||
* loading our textdomain is complex.
|
||||
*
|
||||
* In v2.4.6, our textdomain changed from "edd" to "easy-digital-downloads".
|
||||
*
|
||||
* To support existing translation files from before the change, we must
|
||||
* look for translation files in several places and under several names.
|
||||
*
|
||||
* - wp-content/languages/plugins/easy-digital-downloads (introduced with language packs)
|
||||
* - wp-content/languages/edd/ (custom folder we have supported since 1.4)
|
||||
* - wp-content/plugins/easy-digital-downloads/languages/
|
||||
*
|
||||
* In wp-content/languages/edd/ we must look for:
|
||||
* - "easy-digital-downloads-{lang}_{country}.mo"
|
||||
*
|
||||
* In wp-content/languages/edd/ we must look for:
|
||||
* - "edd-{lang}_{country}.mo" as that was the old file naming convention
|
||||
*
|
||||
* In wp-content/languages/plugins/easy-digital-downloads/ we only need to look for:
|
||||
* - "easy-digital-downloads-{lang}_{country}.mo" as that is the new structure
|
||||
*
|
||||
* In wp-content/plugins/easy-digital-downloads/languages/, we must look for:
|
||||
* - both naming conventions. This is done by filtering "load_textdomain_mofile"
|
||||
*/
|
||||
add_filter( 'load_textdomain_mofile', array( $this, 'load_old_textdomain' ), 10, 2 );
|
||||
|
||||
// Set filter for plugin's languages directory.
|
||||
$edd_lang_dir = dirname( $this->base ) . '/languages/';
|
||||
$edd_lang_dir = apply_filters( 'edd_languages_directory', $edd_lang_dir );
|
||||
|
||||
unload_textdomain( 'easy-digital-downloads' );
|
||||
|
||||
/**
|
||||
* Defines the plugin language locale used in Easy Digital Downloads.
|
||||
*
|
||||
* @var $get_locale The locale to use.
|
||||
*/
|
||||
$locale = apply_filters( 'plugin_locale', get_user_locale(), 'easy-digital-downloads' );
|
||||
$mofile = sprintf( '%1$s-%2$s.mo', 'easy-digital-downloads', $locale );
|
||||
|
||||
// Look for wp-content/languages/edd/easy-digital-downloads-{lang}_{country}.mo
|
||||
$mofile_global1 = WP_LANG_DIR . "/edd/easy-digital-downloads-{$locale}.mo";
|
||||
|
||||
// Look for wp-content/languages/edd/edd-{lang}_{country}.mo
|
||||
$mofile_global2 = WP_LANG_DIR . "/edd/edd-{$locale}.mo";
|
||||
|
||||
// Look in wp-content/languages/plugins/easy-digital-downloads
|
||||
$mofile_global3 = WP_LANG_DIR . "/plugins/easy-digital-downloads/{$mofile}";
|
||||
|
||||
// Try to load from first global location
|
||||
if ( file_exists( $mofile_global1 ) ) {
|
||||
load_textdomain( 'easy-digital-downloads', $mofile_global1 );
|
||||
|
||||
// Try to load from next global location
|
||||
} elseif ( file_exists( $mofile_global2 ) ) {
|
||||
load_textdomain( 'easy-digital-downloads', $mofile_global2 );
|
||||
|
||||
// Try to load from next global location
|
||||
} elseif ( file_exists( $mofile_global3 ) ) {
|
||||
load_textdomain( 'easy-digital-downloads', $mofile_global3 );
|
||||
|
||||
// Load the default language files
|
||||
} else {
|
||||
load_plugin_textdomain( 'easy-digital-downloads', false, $edd_lang_dir );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a .mo file for the old textdomain if one exists.
|
||||
*
|
||||
* @see https://github.com/10up/grunt-wp-plugin/issues/21#issuecomment-62003284
|
||||
*/
|
||||
public function load_old_textdomain( $mofile, $textdomain ) {
|
||||
|
||||
// Fallback for old text domain
|
||||
if ( ( 'easy-digital-downloads' === $textdomain ) && ! file_exists( $mofile ) ) {
|
||||
$mofile = dirname( $mofile ) . DIRECTORY_SEPARATOR . str_replace( $textdomain, 'edd', basename( $mofile ) );
|
||||
}
|
||||
|
||||
// Return (possibly overridden) mofile
|
||||
return $mofile;
|
||||
}
|
||||
}
|
@ -2132,6 +2132,12 @@ class Stats {
|
||||
// Run pre-query checks and maybe generate SQL.
|
||||
$this->pre_query( $query );
|
||||
|
||||
$where = $this->query_vars['where_sql'];
|
||||
// Allow `purchase_count` to be set to `true` to query only customers with orders.
|
||||
if ( isset( $query['purchase_count'] ) && true === $query['purchase_count'] ) {
|
||||
$where .= " AND {$this->query_vars['table']}.purchase_count > 0";
|
||||
}
|
||||
|
||||
if ( true === $this->query_vars['relative'] ) {
|
||||
$relative_date_query_sql = $this->generate_relative_date_query_sql();
|
||||
|
||||
@ -2140,13 +2146,13 @@ class Stats {
|
||||
CROSS JOIN (
|
||||
SELECT IFNULL(COUNT(id), 0) AS relative
|
||||
FROM {$this->query_vars['table']}
|
||||
WHERE 1=1 {$this->query_vars['where_sql']} {$relative_date_query_sql}
|
||||
WHERE 1=1 {$where} {$relative_date_query_sql}
|
||||
) o
|
||||
WHERE 1=1 {$this->query_vars['where_sql']} {$this->query_vars['date_query_sql']}";
|
||||
WHERE 1=1 {$where} {$this->query_vars['date_query_sql']}";
|
||||
} else {
|
||||
$sql = "SELECT COUNT(id) AS total
|
||||
FROM {$this->query_vars['table']}
|
||||
WHERE 1=1 {$this->query_vars['date_query_sql']}";
|
||||
WHERE 1=1 {$where} {$this->query_vars['date_query_sql']}";
|
||||
}
|
||||
|
||||
$result = $this->get_db()->get_row( $sql );
|
||||
|
@ -234,6 +234,14 @@ function edd_setup_components() {
|
||||
'object' => '\\EDD\\Logs\\File_Download_Log',
|
||||
) );
|
||||
|
||||
edd_register_component( 'notification', array(
|
||||
'schema' => '\\EDD\\Database\\Schemas\\Notifications',
|
||||
'table' => '\\EDD\\Database\\Tables\\Notifications',
|
||||
'query' => '\\EDD\\Database\\Queries\\Notification',
|
||||
'object' => '\\EDD\\Notifications\\Notification',
|
||||
'meta' => false,
|
||||
) );
|
||||
|
||||
// Set the locally static setup var.
|
||||
$setup = true;
|
||||
|
||||
|
@ -1,236 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Currency
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license GPL2+
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
namespace EDD\Currency;
|
||||
|
||||
class Currency {
|
||||
|
||||
/**
|
||||
* @var string Currency code.
|
||||
*/
|
||||
public $code;
|
||||
|
||||
/**
|
||||
* @var string Symbol/text to display before amounts.
|
||||
*/
|
||||
public $prefix;
|
||||
|
||||
/**
|
||||
* @var string Symbol/text to display after amounts.
|
||||
*/
|
||||
public $suffix;
|
||||
|
||||
/**
|
||||
* @var string Symbol to use in the prefix/suffix.
|
||||
*/
|
||||
public $symbol;
|
||||
|
||||
/**
|
||||
* @var string Decimal separator.
|
||||
*/
|
||||
public $decimal_separator = '.';
|
||||
|
||||
/**
|
||||
* @var string Thousands separator.
|
||||
*/
|
||||
public $thousands_separator = ',';
|
||||
|
||||
/**
|
||||
* @var int Number of decimals.
|
||||
*/
|
||||
public $number_decimals = 2;
|
||||
|
||||
/**
|
||||
* Currency constructor.
|
||||
*
|
||||
* @param string $currency_code
|
||||
*/
|
||||
public function __construct( $currency_code ) {
|
||||
$this->code = strtoupper( $currency_code );
|
||||
|
||||
$this->setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new currency object.
|
||||
*
|
||||
* @param string $currency_code
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return Currency
|
||||
*/
|
||||
public static function from_code( $currency_code ) {
|
||||
return new self( $currency_code );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up properties.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
private function setup() {
|
||||
$this->symbol = $this->get_symbol();
|
||||
$this->decimal_separator = edd_get_option( 'decimal_separator', '.' );
|
||||
$this->thousands_separator = edd_get_option( 'thousands_separator', ',' );
|
||||
|
||||
/**
|
||||
* Filters the decimal separator.
|
||||
*
|
||||
* @param string $decimal_separator
|
||||
* @param string $code
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
$this->decimal_separator = apply_filters( 'edd_currency_decimal_separator', $this->decimal_separator, $this->code );
|
||||
|
||||
/**
|
||||
* Filters the thousands separator.
|
||||
*
|
||||
* @param string $thousands_separator
|
||||
* @param string $code
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
$this->thousands_separator = apply_filters( 'edd_currency_thousands_separator', $this->thousands_separator, $this->code );
|
||||
|
||||
$separator = $this->_has_space_around_symbol() ? ' ' : '';
|
||||
if ( 'before' === edd_get_option( 'currency_position', 'before' ) ) {
|
||||
$this->prefix = $this->symbol . $separator;
|
||||
} else {
|
||||
$this->suffix = $separator . $this->symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the currency prefix.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param string $code
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
$this->prefix = apply_filters( 'edd_currency_prefix', $this->prefix, $this->code );
|
||||
|
||||
/**
|
||||
* Filters the currency suffix.
|
||||
*
|
||||
* @param string $prefix
|
||||
* @param string $code
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
$this->suffix = apply_filters( 'edd_currency_suffix', $this->suffix, $this->code );
|
||||
|
||||
$this->number_decimals = $this->_is_zero_decimal() ? 0 : 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this currency has a space between the symbol and the amount.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _has_space_around_symbol() {
|
||||
return ! in_array( $this->code, array(
|
||||
'GBP',
|
||||
'BRL',
|
||||
'EUR',
|
||||
'USD',
|
||||
'AUD',
|
||||
'CAD',
|
||||
'HKD',
|
||||
'MXN',
|
||||
'SGD',
|
||||
'JPY'
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the symbol for this currency.
|
||||
* Depending on settings, this will be used as either the prefix or the suffix.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
public function get_symbol() {
|
||||
switch ( $this->code ) :
|
||||
case "GBP" :
|
||||
$symbol = '£';
|
||||
break;
|
||||
case "BRL" :
|
||||
$symbol = 'R$';
|
||||
break;
|
||||
case "EUR" :
|
||||
$symbol = '€';
|
||||
break;
|
||||
case "USD" :
|
||||
case "AUD" :
|
||||
case "NZD" :
|
||||
case "CAD" :
|
||||
case "HKD" :
|
||||
case "MXN" :
|
||||
case "SGD" :
|
||||
$symbol = '$';
|
||||
break;
|
||||
case "JPY" :
|
||||
$symbol = '¥';
|
||||
break;
|
||||
case "AOA" :
|
||||
$symbol = 'Kz';
|
||||
break;
|
||||
default :
|
||||
$symbol = $this->code;
|
||||
break;
|
||||
endswitch;
|
||||
|
||||
/**
|
||||
* Filters the currency symbol.
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param string $symbol Currency symbol.
|
||||
* @param string $code Currency code.
|
||||
*/
|
||||
return apply_filters( 'edd_currency_symbol', $symbol, $this->code );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not the currency is zero-decimal.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function _is_zero_decimal() {
|
||||
$currencies = array(
|
||||
'bif',
|
||||
'clp',
|
||||
'djf',
|
||||
'gnf',
|
||||
'huf',
|
||||
'jpy',
|
||||
'kmf',
|
||||
'krw',
|
||||
'mga',
|
||||
'pyg',
|
||||
'rwf',
|
||||
'ugx',
|
||||
'vnd',
|
||||
'vuv',
|
||||
'xaf',
|
||||
'xof',
|
||||
'xpf',
|
||||
);
|
||||
|
||||
return in_array( strtolower( $this->code ), $currencies, true );
|
||||
}
|
||||
|
||||
}
|
@ -1,232 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Money Formatter
|
||||
*
|
||||
* Formats an amount of money in various ways, according to the provided currency.
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Sandhills Development, LLC
|
||||
* @license GPL2+
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
namespace EDD\Currency;
|
||||
|
||||
class Money_Formatter {
|
||||
|
||||
/**
|
||||
* @var int|float Current working amount.
|
||||
*/
|
||||
public $amount;
|
||||
|
||||
/**
|
||||
* @var float Typed amount.
|
||||
*/
|
||||
public $typed_amount;
|
||||
|
||||
/**
|
||||
* @var int|float Original, unmodified amount passed in via constructor.
|
||||
*/
|
||||
private $original_amount;
|
||||
|
||||
/**
|
||||
* @var Currency
|
||||
*/
|
||||
private $currency;
|
||||
|
||||
/**
|
||||
* Money_Formatter constructor.
|
||||
*
|
||||
* @param $amount
|
||||
* @param Currency $currency
|
||||
*/
|
||||
public function __construct( $amount, Currency $currency ) {
|
||||
$this->original_amount = $amount;
|
||||
$this->amount = $amount;
|
||||
$this->typed_amount = $amount;
|
||||
$this->currency = $currency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-formats an amount.
|
||||
* This ensures the amount is put into a state where we can perform mathematical
|
||||
* operations on it --- that means using `.` as the decimal separator and no
|
||||
* thousands separator.
|
||||
*
|
||||
* @return float|int
|
||||
*/
|
||||
private function unformat() {
|
||||
$amount = $this->original_amount;
|
||||
|
||||
$sep_found = strpos( $amount, $this->currency->decimal_separator );
|
||||
if ( ',' === $this->currency->decimal_separator && false !== $sep_found ) {
|
||||
$whole = substr( $amount, 0, $sep_found );
|
||||
$part = substr( $amount, $sep_found + 1, ( strlen( $amount ) - 1 ) );
|
||||
$amount = $whole . '.' . $part;
|
||||
}
|
||||
|
||||
// Strip "," and " " from the amount (if set as the thousands separator).
|
||||
foreach ( array( ',', ' ' ) as $thousands_separator ) {
|
||||
if ( $thousands_separator === $this->currency->thousands_separator && false !== strpos( $amount, $this->currency->thousands_separator ) ) {
|
||||
$amount = str_replace( $thousands_separator, '', $amount );
|
||||
}
|
||||
}
|
||||
|
||||
return $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of decimals ot use for the formatted amount.
|
||||
*
|
||||
* Based on the currency code used when instantiating the class, determines how many
|
||||
* decimal points the value should have once formatted.
|
||||
*
|
||||
* @param bool $decimals If we should include decimals or not in the formatted amount.
|
||||
* @param float $amount The amount to format.
|
||||
*
|
||||
* @return int The number of decimals places to use when formatting the amount.
|
||||
*/
|
||||
private function get_decimals( $decimals, $amount ) {
|
||||
/**
|
||||
* Filter number of decimals to use for formatted amount
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param int $number Default 2. Number of decimals.
|
||||
* @param int|string $amount Amount being formatted.
|
||||
* @param string $currency_code Currency code being formatted.
|
||||
*/
|
||||
return apply_filters( 'edd_format_amount_decimals', $decimals ? $this->currency->number_decimals : 0, $amount, $this->currency->code );
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the amount for display.
|
||||
* Does not apply the currency code.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param bool $decimals If we should include decimal places or not when formatting.
|
||||
*
|
||||
* @return Money_Formatter
|
||||
*/
|
||||
public function format_for_display( $decimals = true ) {
|
||||
$amount = $this->unformat();
|
||||
|
||||
if ( empty( $amount ) ) {
|
||||
$amount = 0;
|
||||
}
|
||||
|
||||
$decimals = $this->get_decimals( $decimals, $amount );
|
||||
|
||||
// Format amount using decimals and separators (also rounds up or down).
|
||||
$formatted = number_format( (float) $amount, $decimals, $this->currency->decimal_separator, $this->currency->thousands_separator );
|
||||
|
||||
/**
|
||||
* Filter the formatted amount before returning
|
||||
*
|
||||
* @since unknown
|
||||
*
|
||||
* @param mixed $formatted Formatted amount.
|
||||
* @param mixed $amount Original amount.
|
||||
* @param int $decimals Default 2. Number of decimals.
|
||||
* @param string $decimal_separator Default '.'. Decimal separator.
|
||||
* @param string $thousands_separator Default ','. Thousands separator.
|
||||
* @param string $currency_code Currency used for formatting.
|
||||
*/
|
||||
$this->amount = apply_filters( 'edd_format_amount', $formatted, $amount, $decimals, $this->currency->decimal_separator, $this->currency->thousands_separator, $this->currency->code );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the amount for typed data returns.
|
||||
* Does not apply the currency code and returns a foat instead of a string.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param bool $decimals If we should include decimal places or not when formatting.
|
||||
*
|
||||
* @return Money_Formatter
|
||||
*/
|
||||
public function format_for_typed( $decimals = true ) {
|
||||
$amount = $this->unformat();
|
||||
|
||||
if ( empty( $amount ) ) {
|
||||
$amount = 0;
|
||||
}
|
||||
|
||||
$decimals = $this->get_decimals( $decimals, $amount );
|
||||
|
||||
/**
|
||||
* Since we want to return a float value here, intentionally only supply a decimal separator.
|
||||
*
|
||||
* The separators here are hard coded intentionally as we're looking to get truncated, raw format of float
|
||||
* which requires '.' for decimal separators and no thousands separator.
|
||||
*
|
||||
* This is also intentionally not filtered for the time being.
|
||||
*/
|
||||
$formatted = floatval( number_format( (float) $amount, $decimals, '.', '' ) );
|
||||
|
||||
// Set the amount to $this->amount.
|
||||
$this->typed_amount = $formatted;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the currency prefix/suffix to the amount.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return string
|
||||
*/
|
||||
public function apply_symbol() {
|
||||
$amount = $this->amount;
|
||||
$is_negative = is_numeric( $this->amount ) && $this->amount < 0;
|
||||
|
||||
// Remove "-" from start.
|
||||
if ( $is_negative ) {
|
||||
$amount = substr( $amount, 1 );
|
||||
}
|
||||
|
||||
$formatted = '';
|
||||
if ( ! empty( $this->currency->prefix ) ) {
|
||||
$formatted .= $this->currency->prefix;
|
||||
}
|
||||
|
||||
$formatted .= $amount;
|
||||
|
||||
if ( ! empty( $this->currency->suffix ) ) {
|
||||
$formatted .= $this->currency->suffix;
|
||||
}
|
||||
|
||||
if ( ! empty( $this->currency->prefix ) ) {
|
||||
/**
|
||||
* Filters the output with a prefix.
|
||||
*
|
||||
* @param string $formatted
|
||||
* @param string $currency_code
|
||||
* @param string $amount
|
||||
*/
|
||||
$formatted = apply_filters( 'edd_' . strtolower( $this->currency->code ) . '_currency_filter_before', $formatted, $this->currency->code, $amount );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->currency->suffix ) ) {
|
||||
/**
|
||||
* Filters the output with a suffix.
|
||||
*
|
||||
* @param string $formatted
|
||||
* @param string $currency_code
|
||||
* @param string $amount
|
||||
*/
|
||||
$formatted = apply_filters( 'edd_' . strtolower( $this->currency->code ) . '_currency_filter_after', $formatted, $this->currency->code, $amount );
|
||||
}
|
||||
|
||||
// Add the "-" sign back to the start of the string.
|
||||
if ( $is_negative ) {
|
||||
$formatted = '-' . $formatted;
|
||||
}
|
||||
|
||||
return $formatted;
|
||||
}
|
||||
|
||||
}
|
@ -1,258 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Notifications Database
|
||||
*
|
||||
* @package easy-digital-downloads
|
||||
* @copyright Copyright (c) 2021, Easy Digital Downloads
|
||||
* @license GPL2+
|
||||
* @since 2.11.4
|
||||
*/
|
||||
|
||||
namespace EDD\Database;
|
||||
|
||||
use EDD\Models\Notification;
|
||||
use EDD\Utils\EnvironmentChecker;
|
||||
use EDD\Utils\NotificationImporter;
|
||||
|
||||
class NotificationsDB extends \EDD_DB {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
global $wpdb;
|
||||
|
||||
$this->table_name = $wpdb->prefix . 'edd_notifications';
|
||||
$this->primary_key = 'id';
|
||||
$this->version = '1.0';
|
||||
|
||||
add_action( 'edd_daily_scheduled_events', array( $this, 'schedule_daily_notification_checks' ) );
|
||||
|
||||
$db_version = get_option( "{$this->table_name}_db_version" );
|
||||
if ( version_compare( $db_version, $this->version, '>=' ) ) {
|
||||
return;
|
||||
}
|
||||
$this->create_table();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a cron event to check for new notifications.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
public static function schedule_daily_notification_checks() {
|
||||
$importer = new NotificationImporter();
|
||||
$importer->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns and their formats.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_columns() {
|
||||
return array(
|
||||
'id' => '%d',
|
||||
'remote_id' => '%d',
|
||||
'title' => '%s',
|
||||
'content' => '%s',
|
||||
'buttons' => '%s',
|
||||
'type' => '%s',
|
||||
'conditions' => '%s',
|
||||
'start' => '%s',
|
||||
'end' => '%s',
|
||||
'dismissed' => '%d',
|
||||
'date_created' => '%s',
|
||||
'date_updated' => '%s',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let MySQL handle most of the defaults.
|
||||
* We just set the dates here to ensure they get saved in UTC.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_column_defaults() {
|
||||
return array(
|
||||
'date_created' => gmdate( 'Y-m-d H:i:s' ),
|
||||
'date_updated' => gmdate( 'Y-m-d H:i:s' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON-encodes any relevant columns.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function maybeJsonEncode( $data ) {
|
||||
$jsonColumns = array( 'buttons', 'conditions' );
|
||||
|
||||
foreach ( $jsonColumns as $column ) {
|
||||
if ( ! empty( $data[ $column ] ) && is_array( $data[ $column ] ) ) {
|
||||
$data[ $column ] = json_encode( $data[ $column ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new notification.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function insert( $data, $type = 'notification' ) {
|
||||
$result = parent::insert( $this->maybeJsonEncode( $data ), $type );
|
||||
|
||||
wp_cache_delete( 'edd_active_notification_count', 'edd_notifications' );
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates an existing notification.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param int $row_id
|
||||
* @param array $data
|
||||
* @param string $where
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function update( $row_id, $data = array(), $where = '' ) {
|
||||
return parent::update( $row_id, $this->maybeJsonEncode( $data ), $where );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all notifications that have not been dismissed and should be
|
||||
* displayed on this site.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param bool $conditionsOnly If set to true, then only the `conditions` column is retrieved
|
||||
* for each notification.
|
||||
*
|
||||
* @return Notification[]
|
||||
*/
|
||||
public function getActiveNotifications( $conditionsOnly = false ) {
|
||||
global $wpdb;
|
||||
|
||||
$environmentChecker = new EnvironmentChecker();
|
||||
$notifications = $wpdb->get_results( $this->getActiveQuery( $conditionsOnly ) );
|
||||
|
||||
$models = array();
|
||||
if ( is_array( $notifications ) ) {
|
||||
foreach ( $notifications as $notification ) {
|
||||
$model = new Notification( (array) $notification );
|
||||
|
||||
try {
|
||||
// Only add to the array if all conditions are met or if the notification has no conditions.
|
||||
if (
|
||||
! $model->conditions ||
|
||||
( is_array( $model->conditions ) && $environmentChecker->meetsConditions( $model->conditions ) )
|
||||
) {
|
||||
$models[] = $model;
|
||||
}
|
||||
} catch ( \Exception $e ) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset( $notifications );
|
||||
|
||||
return $models;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the query for selecting or counting active notifications.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @param bool $conditionsOnly
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getActiveQuery( $conditionsOnly = false ) {
|
||||
global $wpdb;
|
||||
|
||||
$select = $conditionsOnly ? 'conditions' : '*';
|
||||
|
||||
return $wpdb->prepare(
|
||||
"SELECT {$select} FROM {$this->table_name}
|
||||
WHERE dismissed = 0
|
||||
AND (start <= %s OR start IS NULL)
|
||||
AND (end >= %s OR end IS NULL)
|
||||
ORDER BY start DESC, id DESC",
|
||||
gmdate( 'Y-m-d H:i:s' ),
|
||||
gmdate( 'Y-m-d H:i:s' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts the number of active notifications.
|
||||
* Note: We can't actually do a real `COUNT(*)` on the database, because we want
|
||||
* to double-check the conditions are met before displaying. That's why we use
|
||||
* `getActiveNotifications()` which runs the conditions through the EnvironmentChecker.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function countActiveNotifications() {
|
||||
$numberActive = wp_cache_get( 'edd_active_notification_count', 'edd_notifications' );
|
||||
if ( false === $numberActive ) {
|
||||
$numberActive = count( $this->getActiveNotifications( true ) );
|
||||
|
||||
wp_cache_set( 'edd_active_notification_count', $numberActive, 'edd_notifications' );
|
||||
}
|
||||
|
||||
return $numberActive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the table.
|
||||
*
|
||||
* @since 2.11.4
|
||||
*/
|
||||
public function create_table() {
|
||||
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||
|
||||
global $wpdb;
|
||||
|
||||
dbDelta( "CREATE TABLE {$this->table_name} (
|
||||
id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
remote_id bigint(20) UNSIGNED DEFAULT NULL,
|
||||
title text NOT NULL,
|
||||
content longtext NOT NULL,
|
||||
buttons longtext DEFAULT NULL,
|
||||
type varchar(64) NOT NULL,
|
||||
conditions longtext DEFAULT NULL,
|
||||
start datetime DEFAULT NULL,
|
||||
end datetime DEFAULT NULL,
|
||||
dismissed tinyint(1) UNSIGNED NOT NULL DEFAULT 0,
|
||||
date_created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP(),
|
||||
date_updated datetime NOT NULL DEFAULT CURRENT_TIMESTAMP(),
|
||||
PRIMARY KEY (id),
|
||||
KEY dismissed_start_end (dismissed, start, end)
|
||||
) DEFAULT CHARACTER SET {$wpdb->charset} COLLATE {$wpdb->collate};" );
|
||||
|
||||
update_option( $this->table_name . '_db_version', $this->version );
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user