installed plugin Easy Digital Downloads version 3.1.0.3

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

View File

@ -0,0 +1,670 @@
<?php
/**
* Admin Payment Actions
*
* @package EDD
* @subpackage Admin/Payments
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.9
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Handle order item changes
*
* @since 3.0
*
* @param array $request
*
* @return boolean
*/
function edd_handle_order_item_change( $request = array() ) {
// Bail if missing necessary properties
if (
empty( $request['_wpnonce'] ) ||
empty( $request['id'] ) ||
empty( $request['order_item'] )
) {
return false;
}
// Bail if nonce check fails
if ( ! wp_verify_nonce( $request['_wpnonce'], 'edd_order_item_nonce' ) ) {
return false;
}
// Default data
$data = array();
// Maybe add status to data to update
if ( ! empty( $request['status'] ) && ( 'inherit' === $request['status'] ) || in_array( $request['status'], array_keys( edd_get_payment_statuses() ), true )) {
$data['status'] = sanitize_key( $request['status'] );
}
// Update order item
if ( ! empty( $data ) ) {
edd_update_order_item( $request['order_item'], $data );
edd_redirect( edd_get_admin_url( array(
'page' => 'edd-payment-history',
'view' => 'view-order-details',
'id' => absint( $request['id'] )
) ) );
}
}
add_action( 'edd_handle_order_item_change', 'edd_handle_order_item_change' );
/**
* Process the changes from the `View Order Details` page.
*
* @since 1.9
* @since 3.0 Refactored to use new core objects and query methods.
*
* @param array $data Order data.
*/
function edd_update_payment_details( $data = array() ) {
// Bail if an empty array is passed.
if ( empty( $data ) ) {
wp_die( esc_html__( 'You do not have permission to edit this payment record', 'easy-digital-downloads' ), esc_html__( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
// Bail if the user does not have the correct permissions.
if ( ! current_user_can( 'edit_shop_payments', $data['edd_payment_id'] ) ) {
wp_die( esc_html__( 'You do not have permission to edit this payment record', 'easy-digital-downloads' ), esc_html__( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
check_admin_referer( 'edd_update_payment_details_nonce' );
// Retrieve the order ID and set up the order.
$order_id = absint( $data['edd_payment_id'] );
$order = edd_get_order( $order_id );
$order_update_args = array();
$unlimited = isset( $data['edd-unlimited-downloads'] ) ? '1' : null;
$new_status = sanitize_key( $data['edd-payment-status'] );
$date_string = EDD()->utils->get_date_string(
sanitize_text_field( $data['edd-payment-date'] ),
sanitize_text_field( $data['edd-payment-time-hour'] ),
sanitize_text_field( $data['edd-payment-time-min'] )
);
// The date is entered in the WP timezone. We need to convert it to UTC prior to saving now.
$date = edd_get_utc_equivalent_date( EDD()->utils->date( $date_string, edd_get_timezone_id(), false ) );
$date = $date->format( 'Y-m-d H:i:s' );
$order_update_args['date_created'] = $date;
// Customer
$curr_customer_id = sanitize_text_field( $data['current-customer-id'] );
$new_customer_id = sanitize_text_field( $data['customer-id'] );
// Create a new customer.
if ( isset( $data['edd-new-customer'] ) && 1 === (int) $data['edd-new-customer'] ) {
$email = isset( $data['edd-new-customer-email'] )
? sanitize_text_field( $data['edd-new-customer-email'] )
: '';
// Sanitize first name
$first_name = isset( $data['edd-new-customer-first-name'] )
? sanitize_text_field( $data['edd-new-customer-first-name'] )
: '';
// Sanitize last name
$last_name = isset( $data['edd-new-customer-last-name'] )
? sanitize_text_field( $data['edd-new-customer-last-name'] )
: '';
// Combine
$name = $first_name . ' ' . $last_name;
if ( empty( $email ) || empty( $name ) ) {
wp_die( esc_html__( 'New Customers require a name and email address', 'easy-digital-downloads' ) );
}
$customer = new EDD_Customer( $email );
if ( empty( $customer->id ) ) {
$customer_data = array(
'name' => $name,
'email' => $email,
);
$user_id = email_exists( $email );
if ( false !== $user_id ) {
$customer_data['user_id'] = $user_id;
}
if ( ! $customer->create( $customer_data ) ) {
$customer = new EDD_Customer( $curr_customer_id );
edd_set_error( 'edd-payment-new-customer-fail', __( 'Error creating new customer', 'easy-digital-downloads' ) );
}
} else {
wp_die( sprintf( __( 'A customer with the email address %s already exists. Please go back and assign this payment to them.', 'easy-digital-downloads' ), $email ) );
}
$previous_customer = new EDD_Customer( $curr_customer_id );
} elseif ( $curr_customer_id !== $new_customer_id ) {
$customer = new EDD_Customer( $new_customer_id );
$previous_customer = new EDD_Customer( $curr_customer_id );
} else {
$customer = new EDD_Customer( $curr_customer_id );
}
// Remove the stats and payment from the previous customer and attach it to the new customer
if ( isset( $previous_customer ) ) {
$previous_customer->remove_payment( $order_id, false );
$customer->attach_payment( $order_id, false );
// If purchase was completed and not ever refunded, adjust stats of customers
if ( 'revoked' === $new_status || 'complete' === $new_status ) {
$previous_customer->recalculate_stats();
if ( ! empty( $customer ) ) {
$customer->recalculate_stats();
}
}
$order_update_args['customer_id'] = $customer->id;
}
$order_update_args['user_id'] = $customer->user_id;
$order_update_args['email'] = $customer->email;
// Address.
$address = $data['edd_order_address'];
$order_address_id = absint( $address['address_id'] );
$order_address_details = array(
'name' => $customer->name,
'address' => $address['address'],
'address2' => $address['address2'],
'city' => $address['city'],
'region' => $address['region'],
'postal_code' => $address['postal_code'],
'country' => $address['country'],
);
if ( empty( $order_address_id ) ) {
// Unset the address_id which is 0.
unset( $address['address_id'] );
// Add the $order_id to the arguments to create this order address.
$order_address_details['order_id'] = $order_id;
edd_add_order_address( $order_address_details );
} else {
edd_update_order_address( $order_address_id, $order_address_details );
}
// Unlimited downloads.
if ( 1 === (int) $unlimited ) {
edd_update_order_meta( $order_id, 'unlimited_downloads', $unlimited );
} else {
edd_delete_order_meta( $order_id, 'unlimited_downloads' );
}
// Don't set the status in the update call (for back compat)
unset( $order_update_args['status'] );
// Attempt to update the order
$updated = edd_update_order( $order_id, $order_update_args );
// Bail if an error occurred
if ( false === $updated ) {
wp_die( __( 'Error updating order.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 400 ) );
}
// Check if the status has changed, if so, we need to invoke the pertinent
// status processing method (for back compat)
if ( $new_status !== $order->status ) {
edd_update_order_status( $order_id, $new_status );
}
do_action( 'edd_updated_edited_purchase', $order_id );
edd_redirect( edd_get_admin_url( array(
'page' => 'edd-payment-history',
'view' => 'view-order-details',
'edd-message' => 'payment-updated',
'id' => absint( $order_id ),
) ) );
}
add_action( 'edd_update_payment_details', 'edd_update_payment_details' );
/**
* New in 3.0, permanently destroys an order, and all its data, and related data.
*
* @since 3.0
*
* @param array $data Arguments passed.
*/
function edd_trigger_destroy_order( $data ) {
if ( wp_verify_nonce( $data['_wpnonce'], 'edd_payment_nonce' ) ) {
$payment_id = absint( $data['purchase_id'] );
if ( ! current_user_can( 'delete_shop_payments', $payment_id ) ) {
wp_die( esc_html__( 'You do not have permission to edit this order.', 'easy-digital-downloads' ), esc_html__( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_destroy_order( $payment_id );
$redirect_link = add_query_arg(
array(
'page' => 'edd-payment-history',
'edd-message' => 'payment_deleted',
'status' => 'trash',
),
edd_get_admin_base_url()
);
edd_redirect( $redirect_link );
}
}
add_action( 'edd_delete_order', 'edd_trigger_destroy_order' );
/**
* Trigger the action of moving an order to the 'trash' status
*
* @since 3.0
*
* @param $data
* @return void
*/
function edd_trigger_trash_order( $data ) {
if ( wp_verify_nonce( $data['_wpnonce'], 'edd_payment_nonce' ) ) {
$payment_id = absint( $data['purchase_id'] );
if ( ! current_user_can( 'delete_shop_payments', $payment_id ) ) {
wp_die( __( 'You do not have permission to edit this payment record', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_trash_order( $payment_id );
$redirect = edd_get_admin_url( array(
'page' => 'edd-payment-history',
'edd-message' => 'order_trashed',
'order_type' => esc_attr( $data['order_type'] ),
) );
edd_redirect( $redirect );
}
}
add_action( 'edd_trash_order', 'edd_trigger_trash_order' );
/**
* Trigger the action of restoring an order from the 'trash' status
*
* @since 3.0
*
* @param $data
* @return void
*/
function edd_trigger_restore_order( $data ) {
if ( wp_verify_nonce( $data['_wpnonce'], 'edd_payment_nonce' ) ) {
$payment_id = absint( $data['purchase_id'] );
if ( ! current_user_can( 'delete_shop_payments', $payment_id ) ) {
wp_die( __( 'You do not have permission to edit this payment record', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
edd_restore_order( $payment_id );
$redirect = edd_get_admin_url( array(
'page' => 'edd-payment-history',
'edd-message' => 'order_restored',
'order_type' => esc_attr( $data['order_type'] ),
) );
edd_redirect( $redirect );
}
}
add_action( 'edd_restore_order', 'edd_trigger_restore_order' );
/**
* Retrieves a new download link for a purchased file
*
* @since 2.0
* @return string
*/
function edd_ajax_generate_file_download_link() {
$customer_view_role = apply_filters( 'edd_view_customers_role', 'view_shop_reports' );
if ( ! current_user_can( $customer_view_role ) ) {
die( '-1' );
}
$payment_id = absint( $_POST['payment_id'] );
$download_id = absint( $_POST['download_id'] );
$price_id = isset( $_POST['price_id'] ) && is_numeric( $_POST['price_id'] ) ? absint( $_POST['price_id'] ) : null;
if ( empty( $payment_id ) ) {
die( '-2' );
}
if ( empty( $download_id ) ) {
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
edd_set_file_download_limit_override( $download_id, $payment_id );
}
$files = edd_get_download_files( $download_id, $price_id );
if ( ! $files ) {
die( '-4' );
}
$file_urls = '';
foreach( $files as $file_key => $file ) {
$file_urls .= edd_get_download_file_url( $payment_key, $email, $file_key, $download_id, $price_id );
$file_urls .= "\n\n";
}
die( $file_urls );
}
add_action( 'wp_ajax_edd_get_file_download_link', 'edd_ajax_generate_file_download_link' );
/**
* Renders the refund form that is used to process a refund.
*
* @since 3.0
*
* @return void
*/
function edd_ajax_generate_refund_form() {
// Verify we have a logged user.
if ( ! is_user_logged_in() ) {
$return = array(
'success' => false,
'message' => __( 'You must be logged in to perform this action.', 'easy-digital-downloads' ),
);
wp_send_json( $return, 401 );
}
// Verify the logged in user has permission to edit shop payments.
if ( ! current_user_can( 'edit_shop_payments' ) ) {
$return = array(
'success' => false,
'message' => __( 'Your account does not have permission to perform this action.', 'easy-digital-downloads' ),
);
wp_send_json( $return, 401 );
}
$order_id = isset( $_POST['order_id'] ) && is_numeric( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : false;
if ( empty( $order_id ) ) {
$return = array(
'success' => false,
'message' => __( 'Invalid order ID', 'easy-digital-downloads' ),
);
wp_send_json( $return, 400 );
}
$order = edd_get_order( $order_id );
if ( empty( $order ) ) {
$return = array(
'success' => false,
'message' => __( 'Invalid order', 'easy-digital-downloads' ),
);
wp_send_json( $return, 404 );
}
if ( 'refunded' === $order->status ) {
$return = array(
'success' => false,
'message' => __( 'Order is already refunded', 'easy-digital-downloads' ),
);
wp_send_json( $return, 404 );
}
if ( 'refund' === $order->type ) {
$return = array(
'success' => false,
'message' => __( 'Cannot refund an order that is already refunded.', 'easy-digital-downloads' ),
);
wp_send_json( $return, 404 );
}
// Output buffer the form before we include it in the JSON response.
ob_start();
?>
<div id="edd-submit-refund-status" style="display: none;">
<span class="edd-submit-refund-message"></span>
<a class="edd-submit-refund-url" href=""><?php _e( 'View Refund', 'easy-digital-downloads' ); ?></a>
</div>
<form id="edd-submit-refund-form" method="POST">
<?php
// Load list table if not already loaded
if ( ! class_exists( '\\EDD\\Admin\\Refund_Items_Table' ) ) {
require_once 'class-refund-items-table.php';
}
$refund_items = new EDD\Admin\Refund_Items_Table();
$refund_items->prepare_items();
$refund_items->display();
?>
</form>
<?php
$html = trim( ob_get_clean() );
$return = array(
'success' => true,
'html' => $html,
);
wp_send_json( $return, 200 );
}
add_action( 'wp_ajax_edd_generate_refund_form', 'edd_ajax_generate_refund_form' );
/**
* Processes the results from the Submit Refund form
*
* @since 3.0
* @return void
*/
function edd_ajax_process_refund_form() {
// Verify we have a logged user.
if ( ! is_user_logged_in() ) {
wp_send_json_error( __( 'You must be logged in to perform this action.', 'easy-digital-downloads' ), 401 );
}
// Verify the logged in user has permission to edit shop payments.
if ( ! current_user_can( 'edit_shop_payments' ) ) {
wp_send_json_error( __( 'Your account does not have permission to perform this action.', 'easy-digital-downloads' ), 401 );
}
if ( empty( $_POST['data'] ) || empty( $_POST['order_id'] ) ) {
wp_send_json_error( __( 'Missing form data or order ID.', 'easy-digital-downloads' ), 400 );
}
// Get our data out of the serialized string.
parse_str( $_POST['data'], $form_data );
// Verify the nonce.
$nonce = ! empty( $form_data['edd_process_refund'] ) ? sanitize_text_field( $form_data['edd_process_refund'] ) : false;
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'edd_process_refund' ) ) {
wp_send_json_error( __( 'Nonce validation failed when submitting refund.', 'easy-digital-downloads' ), 401 );
}
// Collect selected order items.
$order_items = array();
if ( ! empty( $form_data['refund_order_item'] ) && is_array( $form_data['refund_order_item'] ) ) {
foreach( $form_data['refund_order_item'] as $order_item_id => $order_item ) {
// If there's no quantity or subtotal - bail.
if ( empty( $order_item['quantity'] ) || empty( $order_item['subtotal'] ) ) {
continue;
}
$order_items[] = array(
'order_item_id' => absint( $order_item_id ),
'quantity' => intval( $order_item['quantity'] ),
'subtotal' => edd_sanitize_amount( $order_item['subtotal'] ),
'tax' => ! empty( $order_item['tax'] ) ? edd_sanitize_amount( $order_item['tax'] ) : 0.00
);
}
}
// Collect selected adjustments.
$adjustments = array();
if ( ! empty( $form_data['refund_order_adjustment'] ) && is_array( $form_data['refund_order_adjustment'] ) ) {
foreach( $form_data['refund_order_adjustment'] as $adjustment_id => $adjustment ) {
// If there's no quantity or subtotal - bail.
if ( empty( $adjustment['quantity'] ) || empty( $adjustment['subtotal'] ) ) {
continue;
}
$adjustments[] = array(
'adjustment_id' => absint( $adjustment_id ),
'quantity' => intval( $adjustment['quantity'] ),
'subtotal' => floatval( edd_sanitize_amount( $adjustment['subtotal'] ) ),
'tax' => ! empty( $adjustment['tax'] ) ? floatval( edd_sanitize_amount( $adjustment['tax'] ) ) : 0.00
);
}
}
$order_id = absint( $_POST['order_id'] );
$refund_id = edd_refund_order( $order_id, $order_items, $adjustments );
if ( is_wp_error( $refund_id ) ) {
wp_send_json_error( $refund_id->get_error_message() );
} elseif ( ! empty( $refund_id ) ) {
$return = array(
'refund_id' => $refund_id,
'message' => sprintf( __( 'Refund successfully processed.', 'easy-digital-downloads' ) ),
'refund_url' => edd_get_admin_url(
array(
'page' => 'edd-payment-history',
'view' => 'view-refund-details',
'id' => urlencode( $refund_id ),
)
)
);
wp_send_json_success( $return, 200 );
} else {
wp_send_json_error( __( 'Unable to process refund.', 'easy-digital-downloads' ), 401 );
}
}
add_action( 'wp_ajax_edd_process_refund_form', 'edd_ajax_process_refund_form' );
/**
* Process Orders list table bulk actions. This is necessary because we need to
* redirect to ensure filters do not get applied when bulk actions are being
* processed. This processing cannot happen within the `EDD_Payment_History_Table`
* class as at that point, it is too late to do a redirect.
*
* @since 3.0
*/
function edd_orders_list_table_process_bulk_actions() {
// Bail if this method was called directly.
if ( 'load-download_page_edd-payment-history' !== current_action() ) {
_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'] )
: '';
// Bail if we aren't processing bulk actions.
if ( '-1' === $action ) {
return;
}
$ids = isset( $_GET['order'] ) // WPCS: CSRF ok.
? $_GET['order']
: false;
if ( ! is_array( $ids ) ) {
$ids = array( $ids );
}
if ( empty( $action ) ) {
return;
}
check_admin_referer( 'bulk-orders' );
$ids = wp_parse_id_list( $ids );
foreach ( $ids as $id ) {
switch ( $action ) {
case 'trash':
edd_trash_order( $id );
break;
case 'restore':
edd_restore_order( $id );
break;
case 'set-status-complete':
edd_update_payment_status( $id, 'complete' );
break;
case 'set-status-pending':
edd_update_payment_status( $id, 'pending' );
break;
case 'set-status-processing':
edd_update_payment_status( $id, 'processing' );
break;
case 'set-status-revoked':
edd_update_payment_status( $id, 'revoked' );
break;
case 'set-status-failed':
edd_update_payment_status( $id, 'failed' );
break;
case 'set-status-abandoned':
edd_update_payment_status( $id, 'abandoned' );
break;
case 'set-status-preapproval':
edd_update_payment_status( $id, 'preapproval' );
break;
case 'set-status-cancelled':
edd_update_payment_status( $id, 'cancelled' );
break;
case 'resend-receipt':
edd_email_purchase_receipt( $id, false );
break;
}
do_action( 'edd_payments_table_do_bulk_action', $id, $action );
}
wp_safe_redirect( wp_get_referer() );
}
add_action( 'load-download_page_edd-payment-history', 'edd_orders_list_table_process_bulk_actions' );

View File

@ -0,0 +1,158 @@
<?php
/**
* Add Order Page.
*
* @package EDD
* @subpackage Admin/Orders
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
use EDD\Database\Rows\Order as Order;
/**
* Output the Add Order page
*
* @since 3.0
*/
function edd_add_order_page_content() {
wp_enqueue_script( 'edd-admin-orders' );
// Enqueued for backwards compatibility. Empty file.
wp_enqueue_script( 'edd-admin-payments' );
// Create empty order object to pass to callback functions.
$order = new Order( array(
'id' => 0,
'parent' => 0,
'order_number' => 0,
'status' => 'complete',
'date_created' => date( 'Y-m-d H:i:s' ),
'date_modified' => date( 'Y-m-d H:i:s' ),
'date_refundable' => null,
'user_id' => 0,
'customer_id' => 0,
'email' => '',
'ip' => edd_get_ip(),
'gateway' => '',
'mode' => '',
'currency' => edd_get_currency(),
'payment_key' => '',
'subtotal' => 0,
'discount' => 0,
'tax' => 0,
'total' => 0,
) );
?>
<form id="edd-add-order-form" method="post">
<?php edd_order_details_publish( $order ); ?>
<div class="wrap edd-wrap edd-clearfix">
<h1><?php esc_html_e( 'New Order', 'easy-digital-downloads' ); ?></h1>
<hr class="wp-header-end">
<div class="notice notice-error inline" id="edd-add-order-customer-error" style="display: none;">
<p><strong><?php esc_html_e( 'Error', 'easy-digital-downloads' ); ?>:</strong> <?php esc_html_e( 'Please select an existing customer or create a new customer.', 'easy-digital-downloads' ); ?></p>
</div>
<div class="notice notice-error inline" id="edd-add-order-no-items-error" style="display: none">
<p><strong><?php esc_html_e( 'Error', 'easy-digital-downloads' ); ?>:</strong> <?php esc_html_e( 'Please add an item to this order.', 'easy-digital-downloads' ); ?></p>
</div>
<?php do_action( 'edd_add_order_before' ); ?>
<?php do_action( 'edd_add_order_form_top' ); ?>
<div id="poststuff">
<div id="edd-dashboard-widgets-wrap">
<div id="post-body" class="metabox-holder columns-2">
<div id="postbox-container-2" class="postbox-container">
<div id="normal-sortables">
<?php
// Before body.
do_action( 'edd_add_order_details_main_before' );
// Items.
edd_order_details_overview( $order );
// Details sections.
edd_order_details_sections( $order );
// After body.
do_action( 'edd_add_order_details_main_after' );
?>
</div>
</div>
<div id="postbox-container-1" class="postbox-container">
<div id="side-sortables">
<?php
// Before sidebar.
do_action( 'edd_add_order_details_sidebar_before' );
// Attributes.
edd_order_details_attributes( $order );
// Extras.
edd_order_details_extras( $order );
// After sidebar.
do_action( 'edd_add_order_details_sidebar_after' );
?>
</div>
</div>
</div>
</div>
</div>
<?php
do_action( 'edd_add_order_form_bottom' );
wp_nonce_field( 'edd_add_order_nonce', 'edd_add_order_nonce' );
?>
<input type="hidden" name="edd_action" value="add_order" />
<?php do_action( 'edd_add_order_after' ); ?>
</div><!-- /.wrap -->
</form>
<div
id="edd-admin-order-add-item-dialog"
title="<?php esc_attr_e( 'Add Download', 'easy-digital-downloads' ); ?>"
style="display: none;"
>
<div id="edd-admin-order-add-item-dialog-content"></div>
</div>
<div
id="edd-admin-order-add-discount-dialog"
title="<?php esc_attr_e( 'Add Discount', 'easy-digital-downloads' ); ?>"
style="display: none;"
>
<div id="edd-admin-order-add-discount-dialog-content"></div>
</div>
<div
id="edd-admin-order-add-adjustment-dialog"
title="<?php esc_attr_e( 'Add Adjustment', 'easy-digital-downloads' ); ?>"
style="display: none;"
>
<div id="edd-admin-order-add-adjustment-dialog-content"></div>
</div>
<?php
}

View File

@ -0,0 +1,50 @@
<?php
/**
* Order Sections Class.
*
* @package EDD
* @subpackage Admin
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
namespace EDD\Admin;
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Class for creating a vertically tabbed UI for reports.
*
* @since 3.0
*/
class Order_Sections extends Sections {
/**
* Output the contents
*
* @since 3.0
*/
public function display() {
$use_js = ! empty( $this->use_js )
? ' use-js'
: '';
$role = $this->use_js ? 'tablist' : 'menu';
?>
<div class="edd-sections-wrap edd-order-sections-wrapper">
<div class="edd-vertical-sections meta-box <?php echo $use_js; ?>">
<ul class="section-nav" role="<?php echo esc_attr( $role ); ?>">
<?php echo $this->get_all_section_links(); ?>
</ul>
<div class="section-wrap">
<?php echo $this->get_all_section_contents(); ?>
</div>
<br class="clear">
</div>
</div>
<?php
}
}

View File

@ -0,0 +1,755 @@
<?php
/**
* Refund Items Table Class.
*
* @package EDD
* @subpackage Admin/Orders
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
namespace EDD\Admin;
// Exit if accessed directly
use EDD\Orders\Order;
use EDD\Orders\Order_Adjustment;
use EDD\Orders\Order_Item;
defined( 'ABSPATH' ) || exit;
/**
* Order_Items_Table Class.
*
* Renders the Refund Items table on the Refund modal.
*
* @since 3.0
*/
class Refund_Items_Table extends List_Table {
/**
* Constructor.
*
* @since 3.0
* @see WP_List_Table::__construct()
*/
public function __construct() {
global $hook_suffix;
parent::__construct( array(
'singular' => 'refund-item',
'plural' => 'refund-items',
'ajax' => false,
) );
$this->get_counts();
}
/**
* Get the base URL for the order item list table.
*
* @since 3.0
*
* @return string Base URL.
*/
public function get_base_url() {}
/**
* Retrieve the view types.
*
* @since 3.0
*
* @return array $views All the views available.
*/
public function get_views() {
return array();
}
/**
* Retrieve the table columns.
*
* @since 3.0
*
* @return array $columns Array of all the list table columns.
*/
public function get_columns() {
$columns = array(
'cb' => '<input type="checkbox" />',
'name' => __( 'Product', 'easy-digital-downloads' ),
'amount' => __( 'Unit Price', 'easy-digital-downloads' ),
'quantity' => __( 'Quantity', 'easy-digital-downloads' ),
'subtotal' => __( 'Subtotal', 'easy-digital-downloads' ),
);
// Maybe add tax column.
$order = $this->get_order();
if ( $order && $order->get_tax_rate() ) {
$columns['tax'] = __( 'Tax', 'easy-digital-downloads' );
}
// Total at the end.
$columns['total'] = __( 'Total', 'easy-digital-downloads' );
// Return columns.
return $columns;
}
/**
* Retrieve the sortable columns.
*
* @since 3.0
*
* @return array Array of all the sortable columns.
*/
public function get_sortable_columns() { return array(); }
/**
* Gets the name of the primary column.
*
* @since 2.5
* @access protected
*
* @return string Name of the primary column.
*/
protected function get_primary_column_name() {
return 'name';
}
/**
* Generates a unique ID for an item, to be used as HTML IDs.
* We cannot simply use `$item->id` because it's possible that an order item and order adjustment
* could have the same ID.
*
* @param Order_Item|Order_Adjustment $item
*
* @since 3.0
* @return string
*/
private function get_item_unique_id( $item ) {
return $item instanceof Order_Item ? 'order-item-' . $item->id : 'order-adjustment-' . $item->id;
}
/**
* Returns a string that designates the type of object. This is used in HTML `name` attributes.
*
* @param Order_Item|Order_Adjustment $item
*
* @since 3.0
* @return string
*/
private function get_object_type( $item ) {
return $item instanceof Order_Item ? 'order_item' : 'order_adjustment';
}
/**
* Returns the item display name.
*
* @param Order_Item|Order_Adjustment $item
*
* @since 3.0
* @return string
*/
private function get_item_display_name( $item ) {
$name = '';
if ( $item instanceof Order_Item ) {
return $item->get_order_item_name();
}
if ( $item instanceof Order_Adjustment ) {
$name = __( 'Order Fee', 'easy-digital-downloads' );
if ( 'credit' === $item->type ) {
$name = __( 'Order Credit', 'easy-digital-downloads' );
}
if ( ! empty( $item->description ) ) {
$name .= ': ' . $item->description;
}
}
return $name;
}
/**
* This function renders most of the columns in the list table.
*
* @since 3.0
*
* @param Order_Item|Order_Adjustment $item Order item or adjustment object.
* @param string $column_name The name of the column.
*
* @return string Column name.
*/
public function column_default( $item, $column_name ) {
$object_type = $this->get_object_type( $item );
$item_id = $this->get_item_unique_id( $item );
switch ( $column_name ) {
case 'amount':
return $this->format_currency( $item, $column_name );
case 'total':
return $this->format_currency( $item, $column_name, 0 );
case 'quantity':
return $this->get_quantity_column( $item, $column_name, $item_id, $object_type );
case 'subtotal':
case 'tax':
return $this->get_adjustable_column( $item, $column_name, $item_id, $object_type );
default:
return property_exists( $item, $column_name )
? $item->{$column_name}
: '';
}
}
/**
* This private function formats a column value for currency.
*
* @since 3.0
*
* @param Order_Item|Order_Adjustment $item Item object.
* @param string $column_name ID of the column being displayed.
* @param false|float $amount_override Amount override, in case it's not in the order item.
*
* @return string Formatted amount.
*/
private function format_currency( $item, $column_name, $amount_override = false ) {
$symbol = $this->get_currency_symbol( $item->order_id );
$currency_pos = edd_get_option( 'currency_position', 'before' );
$formatted_amount = '';
if ( 'before' === $currency_pos ) {
$formatted_amount .= $symbol;
}
// Order Adjustments do not have an `amount` column. We can use `subtotal` instead.
if ( 'amount' === $column_name && $item instanceof Order_Adjustment ) {
$column_name = 'subtotal';
}
$amount = false !== $amount_override ? $amount_override : $item->{$column_name};
$formatted_amount .= '<span data-' . $column_name . '="' . edd_sanitize_amount( $amount ) . '">' . edd_format_amount( $amount, true, $this->get_order_currency_decimals( $item->order_id ) ) . '</span>';
if ( 'after' === $currency_pos ) {
$formatted_amount .= $symbol;
}
return $formatted_amount;
}
/**
* This private function returns the form input for refundable items,
* or amounts for items which have already been refunded.
*
* @param Order_Item $item The item object.
* @param string $column_name ID of the column being displayed.
* @param string $item_id Unique ID of the order item for the refund modal.
* @param string $object_type The item type.
* @return string
*/
private function get_adjustable_column( $item, $column_name, $item_id, $object_type ) {
if ( 'refunded' === $item->status ) {
return $this->format_currency( $item, $column_name, 0 );
}
$currency_pos = edd_get_option( 'currency_position', 'before' );
// Maximum amounts that can be refunded.
$refundable_amounts = $item->get_refundable_amounts();
$amount_remaining = array_key_exists( $column_name, $refundable_amounts ) ? $refundable_amounts[ $column_name ] : $item->{$column_name};
/*
* Original amount.
* For subtotals, we actually do subtotal minus discounts for simplicity so that the end user
* doesn't have to juggle that.
*/
$original_amount = $item->{$column_name};
if ( 'subtotal' === $column_name && ! empty( $item->discount ) ) {
$original_amount -= $item->discount;
}
ob_start();
?>
<div class="edd-form-group">
<label for="edd-order-item-<?php echo esc_attr( $item_id ); ?>-refund-<?php echo esc_attr( $column_name ); ?>" class="screen-reader-text">
<?php
if ( 'subtotal' === $column_name ) {
esc_html_e( 'Amount to refund, excluding tax', 'easy-digital-downloads' );
} else {
esc_html_e( 'Amount of tax to refund', 'easy-digital-downloads' );
}
?>
</label>
<div class="edd-form-group__control">
<?php
if ( 'before' === $currency_pos ) {
echo '<span class="edd-amount-control__currency is-before">';
echo esc_html( $this->get_currency_symbol( $item->order_id ) );
echo '</span>';
}
?>
<span class="edd-amount-control__input">
<input
type="text"
id="edd-order-item-<?php echo esc_attr( $item_id ); ?>-refund-<?php echo esc_attr( $column_name ); ?>"
class="edd-order-item-refund-<?php echo esc_attr( $column_name ); ?> edd-order-item-refund-input"
name="refund_<?php echo esc_attr( $object_type ); ?>[<?php echo esc_attr( $item->id ); ?>][<?php echo esc_attr( $column_name ); ?>]"
value="<?php echo esc_attr( edd_format_amount( $amount_remaining, true, $this->get_order_currency_decimals( $item->order_id ) ) ); ?>"
placeholder="<?php echo esc_attr( edd_format_amount( 0, true, $this->get_order_currency_decimals( $item->order_id ) ) ); ?>"
data-original="<?php echo esc_attr( $original_amount ); ?>"
data-max="<?php echo esc_attr( $amount_remaining ); ?>"
disabled
/>
</span>
<?php
if ( 'after' === $currency_pos ) {
echo '<span class="edd-amount-control__currency is-after">';
echo esc_html( $this->get_currency_symbol( $item->order_id ) );
echo '</span>';
}
?>
</div>
<small class="edd-order-item-refund-max-amount">
<?php
echo _x( 'Max:', 'Maximum input amount', 'easy-digital-downloads' ) . '&nbsp;';
echo $this->format_currency( $item, $column_name, $amount_remaining );
?>
</small>
</div>
<?php
return ob_get_clean();
}
/**
* Gets the quantity column content.
*
* @since 3.0
*
* @param Order_Item|Order_Adjustment $item Order item or adjustment object.
* @param string $column_name The name of the column.
* @param string $item_id Unique ID of the order item for the refund modal.
* @param string $object_type The item type.
* @return string
*/
private function get_quantity_column( $item, $column_name, $item_id, $object_type ) {
$refundable_amounts = $item->get_refundable_amounts();
$item_quantity = 'order_item' === $object_type ? $refundable_amounts['quantity'] : 1;
ob_start();
?>
<div class="edd-form-group">
<label for="edd_order_item_quantity_<?php echo esc_attr( $item_id ); ?>" class="screen-reader-text">
<?php esc_html_e( 'Quantity to refund', 'easy-digital-downloads' ); ?>
</label>
<div class="edd-form-group__control">
<?php if ( 'order_item' !== $object_type ) : ?>
<input type="hidden" data-original="<?php echo esc_attr( $item_quantity ); ?>" id="edd_order_item_quantity_<?php echo esc_attr( $item_id ); ?>" class="edd-order-item-refund-quantity edd-order-item-refund-input readonly" name="refund_<?php echo esc_attr( $object_type ); ?>[<?php echo esc_attr( $item->id ); ?>][quantity]" value="<?php echo esc_attr( $item_quantity ); ?>" disabled />
<?php else : ?>
<?php
$options = range( 1, $item_quantity );
array_unshift( $options, '' );
unset( $options[0] );
$args = array(
'options' => $options,
'name' => 'refund_' . esc_attr( $object_type ) . '[' . esc_attr( $item->id ) . '][quantity]',
'id' => 'edd-order-item-quantity-' . esc_attr( $item_id ),
'class' => 'edd-order-item-refund-quantity edd-order-item-refund-input',
'disabled' => true,
'show_option_all' => false,
'show_option_none' => false,
'chosen' => false,
'selected' => $item_quantity,
'data' => array(
'max' => intval( $item_quantity ),
'original' => intval( $item->quantity ),
),
);
?>
<?php echo EDD()->html->select( $args ); ?>
<?php endif; ?>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* Retrieves the number of decimals for a given order.
*
* @param int $order_id
*
* @since 3.0
* @return int|null
*/
private function get_order_currency_decimals( $order_id ) {
static $currency_decimals = null;
if ( is_null( $currency_decimals ) ) {
$order = edd_get_order( $order_id );
if ( $order ) {
$currency_decimals = edd_currency_decimal_filter( 2, $order->currency );
} else {
$currency_decimals = 2;
}
}
return $currency_decimals;
}
/**
* Retrieves the currency symbol for a given order item.
*
* @param int $order_id
*
* @since 3.0
* @return string|null
*/
private function get_currency_symbol( $order_id ) {
static $symbol = null;
if ( is_null( $symbol ) ) {
$order = edd_get_order( $order_id );
if ( $order ) {
$symbol = edd_currency_symbol( $order->currency );
}
}
return $symbol;
}
/**
* Render the checkbox column
*
* @since 3.0
*
* @param Order_Item|Order_Adjustment $item Order Item or Order Adjustment object.
*
* @return string
*/
public function column_cb( $item ) {
$object_type = $this->get_object_type( $item );
$refundable_amounts = $item->get_refundable_amounts();
$total_remaining = array_key_exists( 'total', $refundable_amounts ) ? floatval( $refundable_amounts['total'] ) : 0.00;
if ( 'refunded' !== $item->status && 0.00 != $total_remaining ) {
return sprintf(
'<input type="checkbox" name="%1$s[]" id="%1$s-%2$s" class="edd-order-item-refund-checkbox" value="%2$s" /><label for="%1$s-%2$s" class="screen-reader-text">%3$s</label>',
/*$1%s*/
'refund_' . esc_attr( $object_type ),
/*$2%s*/
esc_attr( $item->id ),
/* translators: product name */
esc_html( sprintf( __( 'Select %s', 'easy-digital-downloads' ), $this->get_item_display_name( $item ) ) )
);
}
return '';
}
/**
* Render the Name Column
*
* @since 3.0
*
* @param Order_Item|Order_Adjustment $item Order Item object.
*
* @return string Data shown in the Name column
*/
public function column_name( $item ) {
$checkbox_id = 'refund_' . $this->get_object_type( $item ) . '-' . $item->id;
$display_name = esc_html( $this->get_item_display_name( $item ) );
$status_label = ! empty( $item->status ) && 'complete' !== $item->status ? ' &mdash; ' . edd_get_status_label( $item->status ) : '';
if ( 'refunded' === $item->status ) {
return '<span class="row-title">' . $display_name . '</span>' . esc_html( $status_label );
}
return '<label for="' . esc_attr( $checkbox_id ) . '" class="row-title">' . $display_name . '</label>' . $status_label;
}
/**
* Message to be displayed when there are no items
*
* @since 3.0
*/
public function no_items() {
esc_html_e( 'No items found.', 'easy-digital-downloads' );
}
/**
* Retrieve the bulk actions
*
* @since 3.0
* @return array $actions Array of the bulk actions
*/
public function get_bulk_actions() { return array(); }
/**
* Process the bulk actions
*
* @since 3.0
*/
public function process_bulk_action() {}
/**
* Retrieve the order_item code counts
*
* @todo Fees aren't included in this count, but where does this actually get used anyway?
*
* @since 3.0
*/
public function get_counts() {
// Maybe retrieve counts.
if ( ! edd_is_add_order_page() ) {
// Check for an order ID
$order_id = ! empty( $_POST['order_id'] )
? absint( $_POST['order_id'] ) // WPCS: CSRF ok.
: 0;
// Get counts
$this->counts = edd_get_order_item_counts( array(
'order_id' => $order_id,
) );
}
}
/**
* Retrieve all order data to be shown on the refund table.
* This includes order items and order adjustments.
*
* @since 3.0
* @return Order[]|Order_Adjustment[] All order items and order adjustments associated with the current order.
*/
public function get_data() {
$order = $this->get_order();
if ( empty( $order ) ) {
return array();
}
// Get order items.
$order_items = edd_get_order_items( array(
'order_id' => $order->id,
'number' => 999,
) );
// Get order fees
$order_fees = $order->get_fees();
// Get order credits.
$credits = edd_get_order_adjustments( array(
'object_id' => $order->id,
'object_type' => 'order',
'type' => 'credit',
) );
return array_merge( $order_items, $order_fees, $credits );
}
/**
* Setup the final data for the table
*
* @since 3.0
*/
public function prepare_items() {
$this->_column_headers = array(
$this->get_columns(),
array(),
$this->get_sortable_columns(),
);
$this->items = $this->get_data();
}
/**
* Generates content for a single row of the table
*
* @since 3.0
*
* @param Order_Item|Order_Adjustment $item Order item object.
*/
public function single_row( $item ) {
$is_adjustment = $item instanceof Order_Adjustment;
$item_class = $is_adjustment ? $item->object_id : $item->order_id;
// Status.
$classes = array_map( 'sanitize_html_class', array(
'order-' . $item_class,
$item->status,
'refunditem',
) );
// Turn into a string.
$class = implode( ' ', $classes );
$item_id = $this->get_item_unique_id( $item );
$is_credit = $is_adjustment && 'credit' === $item->type;
?>
<tr id="order-item-<?php echo esc_attr( $item_id ); ?>" <?php echo esc_attr( $is_adjustment ? 'data-order-item-adjustment' : 'data-order-item' ); ?>="<?php echo esc_attr( $item->id ); ?>" <?php echo $is_credit ? 'data-credit="1"' : ''; ?> class="<?php echo esc_html( $class ); ?>">
<?php $this->single_row_columns( $item ); ?>
</tr>
<?php
}
/**
* Displays the table.
*
* @since 3.0
*/
public function display() {
$singular = $this->_args['singular'];
wp_nonce_field( 'edd_process_refund', 'edd_process_refund' );
$this->screen->render_screen_reader_content( 'heading_list' );
?>
<table class="wp-list-table <?php echo implode( ' ', $this->get_table_classes() ); ?>">
<thead>
<tr>
<?php $this->print_column_headers(); ?>
</tr>
</thead>
<tbody id="the-list"<?php
if ( $singular ) {
echo " data-wp-lists='list:$singular'";
} ?>>
<?php $this->display_rows_or_placeholder(); ?>
</tbody>
</table>
<div class="edd-submit-refund-actions">
<?php
/**
* Triggers after the table, but before the submit button.
*
* @param Order $order
*
* @since 3.0
*/
do_action( 'edd_after_submit_refund_table', $this->get_order() );
$this->display_tablenav( 'bottom' );
?>
</div>
<?php
}
/**
* Adds custom submit button below the refund items table.
*
* @param string $which
* @since 3.0
*/
protected function display_tablenav( $which ) {
if ( 'bottom' !== $which ) {
return;
}
?>
<div class="tablenav bottom">
<button id="edd-submit-refund-submit" class="button button-primary" disabled><?php esc_html_e( 'Submit Refund', 'easy-digital-downloads' ); ?></button>
</div>
<?php
}
/**
* Displays the rows.
*
* This is overridden in order to add columns for the totals.
*
* @since 3.0
*/
public function display_rows() {
static $currency_symbol = null;
$order_id = false;
$currency_position = edd_get_option( 'currency_position', 'before' );
foreach ( $this->items as $item ) {
if ( empty( $order_id ) ) {
$order_id = $item->order_id;
}
$this->single_row( $item );
}
$currency_symbol = $this->get_currency_symbol( $order_id );
// Now we need to add the columns for the totals.
?>
<tr id="edd-refund-submit-subtotal" class="edd-refund-submit-line-total">
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
<span class="row-title edd-refund-submit-line-total-name"><?php esc_html_e( 'Refund Subtotal:', 'easy-digital-downloads' ); ?></span>
<?php
$currency_symbol_output = sprintf( '<span>%s</span>', $currency_symbol );
$before = 'before' === $currency_position ? $currency_symbol_output : '';
$after = 'after' === $currency_position ? $currency_symbol_output : '';
$amount = edd_format_amount( 0.00, true, $this->get_order_currency_decimals( $order_id ) );
printf(
'<span class="edd-refund-submit-line-total-amount">%1$s<span id="edd-refund-submit-subtotal-amount">%2$s</span>%3$s</span>',
$before, // phpcs:ignore
esc_attr( $amount ),
$after // phpcs:ignore
);
?>
</td>
</tr>
<?php
$order = $this->get_order();
if ( $order && $order->get_tax_rate() ) :
?>
<tr id="edd-refund-submit-tax" class="edd-refund-submit-line-total">
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
<span class="row-title edd-refund-submit-line-total-name"><?php esc_html_e( 'Refund Tax Total:', 'easy-digital-downloads' ); ?></span>
<?php
printf(
'<span class="edd-refund-submit-line-total-amount">%1$s<span id="edd-refund-submit-tax-amount">%2$s</span>%3$s</span>',
$before, // phpcs:ignore
esc_attr( $amount ),
$after // phpcs:ignore
);
?>
</td>
</tr>
<?php endif; ?>
<tr id="edd-refund-submit-total" class="edd-refund-submit-line-total">
<td colspan="<?php echo esc_attr( $this->get_column_count() ); ?>">
<span class="row-title edd-refund-submit-line-total-name"><?php esc_html_e( 'Refund Total:', 'easy-digital-downloads' ); ?></span>
<?php
printf(
'<span class="edd-refund-submit-line-total-amount">%1$s<span id="edd-refund-submit-total-amount">%2$s</span>%3$s</span>',
$before, // phpcs:ignore
esc_attr( $amount ),
$after // phpcs:ignore
);
?>
</td>
</tr>
<?php
}
/**
* Gets the order object.
*
* @since 3.0
* @return Order|false
*/
private function get_order() {
$order_id = ! empty( $_POST['order_id'] )
? absint( $_POST['order_id'] ) // phpcs:ignore
: 0;
return ! empty( $order_id ) ? edd_get_order( $order_id ) : false;
}
}

View File

@ -0,0 +1,148 @@
<?php
/**
* Contextual Help
*
* @package EDD
* @subpackage Admin/Payments
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.4
*/
use EDD\Admin\Pass_Manager;
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Payments contextual help.
*
* @access private
* @since 1.4
* @return void
*/
function edd_payments_contextual_help() {
$screen = get_current_screen();
// Only show on main "Orders" screen.
if ( 'download_page_edd-payment-history' !== $screen->id ) {
return;
}
// Do not show on Add or View Order/Refund.
if ( isset( $_GET['view'] ) ) {
return;
}
$pass_manager = new Pass_Manager();
if ( $pass_manager->isFree() ) {
$docs_url = edd_link_helper(
'https://easydigitaldownloads.com/docs/',
array(
'utm_medium' => 'orders-contextual-help',
'utm_content' => 'documentation',
)
);
$upgrade_url = edd_link_helper(
'https://easydigitaldownloads.com/lite-upgrade/',
array(
'utm_medium' => 'orders-contextual-help',
'utm_content' => 'lite-upgrade',
)
);
$screen->set_help_sidebar(
'<p><strong>' . __( 'For more information:', 'easy-digital-downloads' ) . '</strong></p>' .
'<p>' . sprintf( __( 'Visit the <a href="%s">documentation</a> on the Easy Digital Downloads website.', 'easy-digital-downloads' ), $docs_url ) . '</p>' .
'<p>' . sprintf(
__( 'Need more from your Easy Digital Downloads store? <a href="%s">Upgrade Now</a>!', 'easy-digital-downloads' ),
$upgrade_url
) . '</p>'
);
}
$screen->add_help_tab( array(
'id' => 'edd-payments-overview',
'title' => __( 'Overview', 'easy-digital-downloads' ),
'content' =>
'<p>' . __( 'This screen provides access to all of the orders and refunds in your store.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Orders can be searched by email address, user name, or filtered by status, mode, date range, gateway, and more!', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'To maintain accurate reporting and accounting, we strongly advise against deleting any completed order data.', 'easy-digital-downloads' ) . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'edd-orders',
'title' => __( '&mdash; Orders', 'easy-digital-downloads' ),
'content' =>
'<p>' . __( 'Orders are placed by customers when they buy things from your store.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Every order contains a snapshot of your store at the time the order was placed, and is made up of many different pieces of information.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Things like products, discounts, taxes, fees, and customer email address, are all examples of information that is saved with each order.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Both full and partial refunds are supported.', 'easy-digital-downloads' ) . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'edd-refunds',
'title' => __( '&mdash; Refunds', 'easy-digital-downloads' ),
'content' =>
'<p>' . __( 'Refunds are created when a customer would like money back from a completed order.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Every refund refers back to the original order, and only contains the items and adjustments that were refunded.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Refunds could be entire orders, or single products.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'Once an item is refunded, it cannot be undone; it can only be repurchased.', 'easy-digital-downloads' ) . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'edd-payments-search',
'title' => __( 'Search', 'easy-digital-downloads' ),
'content' =>
'<p>' . __( 'The order history can be searched in several different ways.', 'easy-digital-downloads' ) . '</p>' .
'<p>' . __( 'You can enter:', 'easy-digital-downloads' ) . '</p>' .
'<ul>
<li>' . __( 'The order ID', 'easy-digital-downloads' ) . '</li>
<li>' . __( 'The 32-character order key', 'easy-digital-downloads' ) . '</li>
<li>' . __( 'The customer\'s email address', 'easy-digital-downloads' ) . '</li>
<li>' . sprintf(
__( 'The customer\'s name or ID prefixed by %s', 'easy-digital-downloads' ),
'<code>customer:</code>'
) . '</li>
<li>' . sprintf(
__( 'A user\'s ID prefixed by %s', 'easy-digital-downloads' ),
'<code>user:</code>'
) . '</li>
<li>' . sprintf(
__( 'The %s ID prefixed by %s', 'easy-digital-downloads' ),
edd_get_label_singular(),
'<code>#</code>'
) . '</li>
<li>' . sprintf(
__( 'The Discount Code prefixed by %s', 'easy-digital-downloads' ),
'<code>discount:</code>'
) . '</li>
<li>' . sprintf(
__( 'A transaction ID prefixed by %s', 'easy-digital-downloads' ),
'<code>txn:</code>'
) . '</li>
</ul>',
) );
$screen->add_help_tab( array(
'id' => 'edd-payments-details',
'title' => __( 'Details', 'easy-digital-downloads' ),
'content' =>
'<p>' . __( 'Each order can be further inspected by clicking the corresponding <em>View Order Details</em> link. This will provide more information including:', 'easy-digital-downloads' ) . '</p>' .
'<ul>
<li><strong>Purchased File</strong> - ' . __( 'The file associated with the purchase.', 'easy-digital-downloads' ) . '</li>
<li><strong>Purchase Date</strong> - ' . __( 'The exact date and time the order was completed.', 'easy-digital-downloads' ) . '</li>
<li><strong>Discount Used</strong> - ' . __( 'If a coupon or discount was used during the checkout process.', 'easy-digital-downloads' ) . '</li>
<li><strong>Name</strong> - ' . __( "The buyer's name.", 'easy-digital-downloads' ) . '</li>
<li><strong>Email</strong> - ' . __( "The buyer's email address.", 'easy-digital-downloads' ) . '</li>
<li><strong>Payment Notes</strong> - ' . __( 'Any customer-specific notes related to the order.', 'easy-digital-downloads' ) . '</li>
<li><strong>Payment Method</strong> - ' . __( 'The name of the order gateway used to complete the order.', 'easy-digital-downloads' ) . '</li>
<li><strong>Purchase Key</strong> - ' . __( 'A unique key used to identify the order.', 'easy-digital-downloads' ) . '</li>
</ul>'
) );
do_action( 'edd_payments_contextual_help', $screen );
}
add_action( 'load-download_page_edd-payment-history', 'edd_payments_contextual_help' );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,237 @@
<?php
/**
* Functions to render Orders page.
*
* @package EDD
* @subpackage Admin/Payments
* @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;
/** Navigation ****************************************************************/
/**
* Output the primary orders page navigation
*
* @since 3.0
* @param string $active_tab
*/
function edd_orders_page_primary_nav( $active_tab = '' ) {
ob_start();?>
<nav class="nav-tab-wrapper edd-nav-tab-wrapper" aria-label="<?php esc_attr_e( 'Secondary menu', 'easy-digital-downloads' ); ?>">
<?php
// Get the order pages
$tabs = edd_get_order_pages();
// Loop through order pages and create tabs
foreach ( $tabs as $tab_id => $tab_name ) {
// Remove
$tab_url = add_query_arg( array(
'settings-updated' => false,
'order_type' => sanitize_key( $tab_id )
) );
// Remove the section from the tabs so we always end up at the main section
$tab_url = remove_query_arg( array( 'section', 'status' ), $tab_url );
$active = $active_tab === $tab_id
? ' nav-tab-active'
: '';
// Link
echo '<a href="' . esc_url( $tab_url ) . '" class="nav-tab' . $active . '">'; // WPCS: XSS ok.
echo esc_html( $tab_name );
echo '</a>';
}
?>
</nav>
<?php
echo ob_get_clean(); // WPCS: XSS ok.
}
/**
* Retrieve the order pages.
*
* Used only by the primary tab navigation for orders.
*
* @since 3.0
*
* @return array
*/
function edd_get_order_pages() {
// Get types and setup return value
$types = edd_get_order_types();
$retval = array();
// Loop through and get type IDs and labels
foreach ( $types as $type_id => $type ) {
// Skip if hidden
if ( empty( $type['show_ui'] ) ) {
continue;
}
// Add to return array
$retval[ $type_id ] = ! empty( $type['labels']['plural'] )
? $type['labels']['plural']
: ucwords( $type_id );
}
// Filter & return
return (array) apply_filters( 'edd_get_order_pages', $retval );
}
/**
* Get the payment view
*
* @since 3.0
*
* @return string
*/
function edd_get_payment_view() {
return ! empty( $_GET['view'] ) // WPCS: CSRF ok.
? sanitize_key( $_GET['view'] ) // WPCS: CSRF ok.
: 'list';
}
/**
* Render one of the Order pages.
*
* @since 1.0
* @since 3.0 Nomenclature updated for consistency.
* Add a link to manually add orders.
* Changed to switch statement.
*/
function edd_payment_history_page() {
// What are we viewing?
switch ( edd_get_payment_view() ) {
// View Order
case 'view-order-details' :
require_once EDD_PLUGIN_DIR . 'includes/admin/payments/view-order-details.php';
break;
// Add Order
case 'add-order' :
require_once EDD_PLUGIN_DIR . 'includes/admin/payments/add-order.php';
edd_add_order_page_content();
break;
// View Refund
case 'view-refund-details' :
require_once EDD_PLUGIN_DIR . 'includes/admin/payments/view-refund.php';
edd_view_refund_page_content();
break;
// List Table
case 'list' :
default :
edd_order_list_table_content();
break;
}
}
/**
* Output the list table used to list out all orders.
*
* @since 3.0
*/
function edd_order_list_table_content() {
require_once EDD_PLUGIN_DIR . 'includes/admin/payments/class-payments-table.php';
$orders_table = new EDD_Payment_History_Table();
$orders_table->prepare_items();
$active_tab = sanitize_key( $orders_table->get_request_var( 'order_type', 'sale' ) );
$admin_url = edd_get_admin_url( array( 'page' => 'edd-payment-history' ) ); ?>
<div class="wrap">
<h1 class="wp-heading-inline"><?php esc_html_e( 'Orders', 'easy-digital-downloads' ); ?></h1>
<?php
if ( 'sale' === $active_tab ) {
$add_new_url = add_query_arg( array( 'view' => 'add-order' ), $admin_url );
printf(
'<a href="%s" class="page-title-action">%s</a>',
esc_url( $add_new_url ),
esc_html__( 'Add New', 'easy-digital-downloads' )
);
}
?>
<hr class="wp-header-end">
<?php edd_orders_page_primary_nav( $active_tab ); ?>
<?php do_action( 'edd_payments_page_top' ); ?>
<form id="edd-payments-filter" method="get" action="<?php echo esc_url( $admin_url ); ?>">
<input type="hidden" name="post_type" value="download" />
<input type="hidden" name="page" value="edd-payment-history" />
<input type="hidden" name="order_type" value="<?php echo esc_attr( $active_tab ); ?>" />
<?php
$orders_table->views();
$orders_table->advanced_filters();
$orders_table->display();
?>
</form>
<?php do_action( 'edd_payments_page_bottom' ); ?>
</div>
<?php
}
/**
* Orders admin titles.
*
* @since 1.6
* @since 3.0 Updated to use new nomenclature.
*
* @param string $admin_title
* @param string $title
*
* @return string Updated admin title.
*/
function edd_view_order_details_title( $admin_title, $title ) {
// Bail if we aren't on the Orders page.
if ( 'download_page_edd-payment-history' !== get_current_screen()->base ) {
return $admin_title;
}
// Get the view
$view = edd_get_payment_view();
// Which view?
switch ( $view ) {
// Edit/View
case 'view-order-details':
case 'edit-payment':
$title = __( 'Edit Order', 'easy-digital-downloads' ) . ' &mdash; ' . $admin_title;
break;
// Add
case 'add-order':
$title = __( 'Add New Order', 'easy-digital-downloads' ) . ' &mdash; ' . $admin_title;
break;
// List
case 'list' :
default:
$title = $admin_title;
break;
}
return $title;
}
add_filter( 'admin_title', 'edd_view_order_details_title', 10, 2 );

View File

@ -0,0 +1,368 @@
<?php
/**
* Refund Details Sections
*
* @package EDD
* @subpackage Admin/Orders
* @copyright Copyright (c) 2021, Sandhills Development, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
use EDD\Orders\Order;
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/** Header ******************************************************************/
/**
* Outputs Refund header region/notice of Refund vs. Order.
*
* @since 3.0
*
* @param Order $refund Current Refund.
*/
function edd_refund_details_notice( $refund ) {
$order_url = edd_get_admin_url(
array(
'id' => absint( $refund->parent ),
'page' => 'edd-payment-history',
'view' => 'view-order-details',
)
);
?>
<div class="edit-post-editor-regions__header">
<div class="edit-post-header notice-warning" style="border-left-width: 4px; border-left-style: solid;">
<div class="edit-post-header__settings">
<a href="<?php echo esc_url( $order_url ); ?>" class="button button-secondary" autofocus>
<?php esc_html_e( 'View Original Order', 'easy-digital-downloads' ); ?>
</a>
</div>
<div class="edit-post-header__toolbar">
<span alt="f223" class="edd-help-tip dashicons dashicons-editor-help" title="<?php _e( 'A refund is a read-only record to help balance your store&#39;s books.', 'easy-digital-downloads' ); ?>"></span>&nbsp;
<?php esc_html_e( 'You are viewing a refund record.', 'easy-digital-downloads' ); ?>
</div>
</div>
</div>
<?php
}
/** Main **********************************************************************/
/**
* Outputs the Refund Items box.
*
* @since 3.0
*
* @param Order $refund Current Refund.
*/
function edd_refund_details_items( $refund ) {
$_items = array();
$_adjustments = array();
$items = edd_get_order_items( array(
'order_id' => $refund->id,
'number' => 999,
) );
foreach ( $items as $item ) {
$item_adjustments = array();
$adjustments = edd_get_order_adjustments( array(
'object_id' => $item->id,
'number' => 999,
'object_type' => 'order_item',
'type' => array(
'discount',
'credit',
'fee',
),
) );
foreach ( $adjustments as $adjustment ) {
// @todo edd_get_order_adjustment_to_json()?
$adjustment_args = array(
'id' => esc_html( $adjustment->id ),
'objectId' => esc_html( $adjustment->object_id ),
'objectType' => esc_html( $adjustment->object_type ),
'typeId' => esc_html( $adjustment->type_id ),
'type' => esc_html( $adjustment->type ),
'description' => esc_html( $adjustment->description ),
'subtotal' => esc_html( $adjustment->subtotal ),
'tax' => esc_html( $adjustment->tax ),
'total' => esc_html( $adjustment->total ),
'dateCreated' => esc_html( $adjustment->date_created ),
'dateModified' => esc_html( $adjustment->date_modified ),
'uuid' => esc_html( $adjustment->uuid ),
);
$item_adjustments[] = $adjustment_args;
$_adjustments[] = $adjustment_args;
}
// @todo edd_get_order_item_to_json()?
$_items[] = array(
'id' => esc_html( $item->id ),
'orderId' => esc_html( $item->order_id ),
'productId' => esc_html( $item->product_id ),
'productName' => esc_html( $item->get_order_item_name() ),
'priceId' => esc_html( $item->price_id ),
'cartIndex' => esc_html( $item->cart_index ),
'type' => esc_html( $item->type ),
'status' => esc_html( $item->status ),
'quantity' => esc_html( $item->quantity ),
'amount' => esc_html( $item->amount ),
'subtotal' => esc_html( $item->subtotal ),
'discount' => esc_html( $item->discount ),
'tax' => esc_html( $item->tax ),
'total' => esc_html( $item->total ),
'dateCreated' => esc_html( $item->date_created ),
'dateModified' => esc_html( $item->date_modified ),
'uuid' => esc_html( $item->uuid ),
);
}
$adjustments = edd_get_order_adjustments( array(
'object_id' => $refund->id,
'number' => 999,
'object_type' => 'order',
'type' => array(
'discount',
'credit',
'fee',
),
) );
foreach ( $adjustments as $adjustment ) {
// @todo edd_get_order_adjustment_to_json()?
$_adjustments[] = array(
'id' => esc_html( $adjustment->id ),
'objectId' => esc_html( $adjustment->object_id ),
'objectType' => esc_html( $adjustment->object_type ),
'typeId' => esc_html( $adjustment->type_id ),
'type' => esc_html( $adjustment->type ),
'description' => esc_html( $adjustment->description ),
'subtotal' => esc_html( $adjustment->subtotal ),
'tax' => esc_html( $adjustment->tax ),
'total' => esc_html( $adjustment->total ),
'dateCreated' => esc_html( $adjustment->date_created ),
'dateModified' => esc_html( $adjustment->date_modified ),
'uuid' => esc_html( $adjustment->uuid ),
);
}
$has_tax = 'none';
$tax_rate = $refund->id ? $refund->get_tax_rate() : false;
$location = array(
'rate' => $tax_rate,
'country' => '',
'region' => '',
);
if ( $tax_rate ) {
$has_tax = $location;
$has_tax['rate'] = $tax_rate;
if ( $refund->tax_rate_id ) {
$tax_rate_object = $refund->get_tax_rate_object();
if ( $tax_rate_object ) {
$has_tax['country'] = $tax_rate_object->name;
$has_tax['region'] = $tax_rate_object->description;
}
}
}
wp_localize_script(
'edd-admin-orders',
'eddAdminOrderOverview',
array(
'items' => $_items,
'adjustments' => $_adjustments,
'refunds' => array(),
'isAdding' => false,
'isRefund' => true,
'hasQuantity' => true,
'hasTax' => $has_tax,
'order' => array(
'currency' => $refund->currency,
'currencySymbol' => html_entity_decode( edd_currency_symbol( $refund->currency ) ),
'subtotal' => $refund->subtotal,
'discount' => $refund->discount,
'tax' => $refund->tax,
'total' => $refund->total,
),
)
);
$templates = array(
'no-items',
'subtotal',
'tax',
'total',
'item',
'adjustment',
'adjustment-discount',
);
foreach ( $templates as $tmpl ) {
echo '<script type="text/html" id="tmpl-edd-admin-order-' . esc_attr( $tmpl ) . '">';
require_once EDD_PLUGIN_DIR . 'includes/admin/views/tmpl-order-' . $tmpl . '.php';
echo '</script>';
}
?>
<div id="edd-order-overview" class="postbox edd-edit-purchase-element edd-order-overview">
<table id="edd-order-overview-summary" class="widefat wp-list-table edd-order-overview-summary edd-order-overview-summary--refund">
<thead>
<tr>
<th class="column-name column-primary"><?php echo esc_html( edd_get_label_singular() ); ?></th>
<th class="column-amount"><?php esc_html_e( 'Unit Price', 'easy-digital-downloads' ); ?></th>
<th class="column-quantity"><?php esc_html_e( 'Quantity', 'easy-digital-downloads' ); ?></th>
<th class="column-subtotal column-right"><?php esc_html_e( 'Amount', 'easy-digital-downloads' ); ?></th>
</tr>
</thead>
</table>
</div>
<?php
}
/**
* Outputs Refund Notes box.
*
* @since 3.0
*
* @param Order $refund Current Refund.
*/
function edd_refund_details_notes( $refund ) {
?>
<div id="edd-order-items" class="postbox edd-edit-purchase-element">
<h2 class="hndle">
<?php esc_html_e( 'Refund Notes', 'easy-digital-downloads' ); ?>
</h2>
<div class="inside">
<?php edd_order_details_notes( $refund ); ?>
</div>
</div>
<?php
}
/**
* Outputs "Refund Details" box.
*
* @since 3.0
*
* @param Order $refund Current Refund.
*/
function edd_refund_details_attributes( $refund ) {
$refund_date = edd_get_edd_timezone_equivalent_date_from_utc( EDD()->utils->date( $refund->date_created, 'utc', true ) );
$trash_url = wp_nonce_url(
edd_get_admin_url( array(
'edd-action' => 'trash_order',
'purchase_id' => absint( $refund->id ),
'order_type' => 'refund',
'page' => 'edd-payment-history',
) ),
'edd_payment_nonce'
);
$order_url = edd_get_admin_url(
array(
'id' => absint( $refund->parent ),
'page' => 'edd-payment-history',
'view' => 'view-order-details',
)
);
$order = edd_get_order( $refund->parent );
?>
<div class="postbox">
<h2 class="hndle">
<?php esc_html_e( 'Refund Attributes', 'easy-digital-downloads' ); ?>
</h2>
<div class="edd-admin-box-inside">
<time datetime="<?php echo esc_attr( EDD()->utils->date( $refund->date_created, null, true )->toDateTimeString() ); ?>" style="line-height: normal">
<?php echo edd_date_i18n( $refund->date_created, 'M. d, Y' ) . '<br />' . edd_date_i18n( strtotime( $refund->date_created ), 'H:i' ); ?> <?php echo esc_html( edd_get_timezone_abbr() ); ?>
</time>
<br /><br />
<a href="<?php echo esc_url( $trash_url ); ?>" class="edd-delete-payment edd-delete">
<?php esc_html_e( 'Move to Trash', 'easy-digital-downloads' ); ?>
</a>
</div>
<div class="edd-admin-box-inside edd-admin-box-inside--row">
<div class="edd-form-group">
<span class="edd-form-group__label">
<?php esc_html_e( 'Original Order', 'easy-digital-downloads' ); ?>
</span>
<div class="edd-form-group__control">
<a href="<?php echo esc_url( $order_url ); ?>"><?php echo esc_html( $order->number ); ?></a>
</div>
</div>
</div>
</div>
<?php
}
/**
* Outputs related Refunds.
*
* @since 3.0
*
* @param Order $refund
*/
function edd_refund_details_related_refunds( $refund ) {
$refunds = array_filter(
edd_get_order_refunds( $refund->parent ),
function( $related_refund ) use ( $refund ) {
return $related_refund->id !== $refund->id;
}
);
if ( empty( $refunds ) ) {
return;
}
?>
<div class="postbox edd-order-data">
<h2 class="hndle">
<?php esc_html_e( 'Related Refunds', 'easy-digital-downloads' ); ?>
</h2>
<?php
foreach( $refunds as $refund ) :
$refund_url = edd_get_admin_url( array(
'page' => 'edd-payment-history',
'view' => 'view-refund-details',
'id' => absint( $refund->id ),
) );
?>
<div class="edd-admin-box-inside">
<div class="edd-form-group">
<a href="<?php echo esc_url( $refund_url ); ?>" class="edd-form-group__label">
<?php echo esc_html( $refund->number ); ?>
</a>
<div class="edd-form-group__control">
<time datetime="<?php echo esc_attr( EDD()->utils->date( $refund->date_created, null, true )->toDateTimeString() ); ?>" style="line-height: normal">
<?php echo edd_date_i18n( $refund->date_created, 'M. d, Y' ) . '<br />' . edd_date_i18n( strtotime( $refund->date_created ), 'H:i' ); ?> <?php echo esc_html( edd_get_timezone_abbr() ); ?>
</time>
</div>
</div>
<?php endforeach; ?>
</div>
<?php
}

View File

@ -0,0 +1,139 @@
<?php
/**
* View Order Details
*
* @package EDD
* @subpackage Admin/Payments
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 1.6
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* View Order Details Page
*
* @since 1.6
* @since 3.0 Updated to use the new EDD\Orders\Order object.
*/
if ( ! isset( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
wp_die( __( 'Order ID not supplied. Please try again', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ) );
}
$order_id = absint( $_GET['id'] );
$order = edd_get_order( $order_id );
// Check that the order exists in the database.
if ( empty( $order ) ) {
wp_die( __( 'The specified ID does not belong to an order. Please try again', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ) );
}
if ( 'refund' === $order->type ) {
$refund_link = edd_get_admin_url(
array(
'page' => 'edd-payment-history',
'view' => 'view-refund-details',
'id' => urlencode( $order->id ),
)
);
wp_die( sprintf( __( 'The specified ID is for a refund, not an order. Please <a href="%s">access the refund directly</a>.', 'easy-digital-downloads' ), esc_url( $refund_link ) ), __( 'Error', 'easy-digital-downloads' ) );
}
wp_enqueue_script( 'edd-admin-orders' );
// Enqueued for backwards compatibility. Empty file.
wp_enqueue_script( 'edd-admin-payments' );
?>
<form id="edd-edit-order-form" method="post">
<?php edd_order_details_publish( $order ); ?>
<div class="wrap edd-wrap edd-clearfix">
<h1><?php printf( esc_html__( 'Order: %s', 'easy-digital-downloads' ), esc_html( $order->number ) ); ?></h1>
<hr class="wp-header-end">
<div class="notice notice-error inline" id="edd-add-order-customer-error" style="display: none;">
<p><strong><?php esc_html_e( 'Error', 'easy-digital-downloads' ); ?>:</strong> <?php esc_html_e( 'Please select an existing customer or create a new customer.', 'easy-digital-downloads' ); ?></p>
</div>
<?php do_action( 'edd_view_order_details_before', $order->id ); ?>
<?php do_action( 'edd_view_order_details_form_top', $order->id ); ?>
<div id="poststuff">
<div id="edd-dashboard-widgets-wrap">
<div id="post-body" class="metabox-holder columns-2">
<div id="postbox-container-2" class="postbox-container">
<div id="normal-sortables">
<?php
// Before body
do_action( 'edd_view_order_details_main_before', $order->id );
// Overview
edd_order_details_overview( $order );
// Details sections
edd_order_details_sections( $order );
// Legacy hook from pre version 3 of Easy Digital Downloads.
do_action( 'edd_view_order_details_billing_after', $order->id );
// After body
do_action( 'edd_view_order_details_main_after', $order->id );
?>
</div>
</div>
<div id="postbox-container-1" class="postbox-container">
<div id="side-sortables">
<?php
// Before sidebar
do_action( 'edd_view_order_details_sidebar_before', $order->id );
// Attributes
edd_order_details_attributes( $order );
// Extras
edd_order_details_extras( $order );
// After sidebar
do_action( 'edd_view_order_details_sidebar_after', $order->id );
?>
</div>
</div>
</div>
</div>
</div>
<?php
do_action( 'edd_view_order_details_form_bottom', $order->id );
wp_nonce_field( 'edd_update_payment_details_nonce' ); ?>
<input type="hidden" name="edd_payment_id" value="<?php echo esc_attr( $order->id ); ?>"/>
<input type="hidden" name="edd_action" value="update_payment_details"/>
<?php do_action( 'edd_view_order_details_after', $order->id ); ?>
</div><!-- /.wrap -->
</form>
<div id="edd-refund-order-dialog" title="<?php esc_html_e( 'Submit Refund', 'easy-digital-downloads' ); ?>"></div>
<div
id="edd-admin-order-copy-download-link-dialog"
title="<?php printf( esc_html__( 'Copy %s Links', 'easy-digital-downloads' ), esc_html( edd_get_label_singular() ) ); ?>"
style="display: none;"
>
<div id="edd-admin-order-copy-download-link-dialog-content"></div>
</div>

View File

@ -0,0 +1,128 @@
<?php
/**
* View Refund page.
*
* @package EDD
* @subpackage Admin/Payments
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
* @since 3.0
*/
// Exit if accessed directly
defined( 'ABSPATH' ) || exit;
/**
* Outputs the View Refund page.
*
* @since 3.0
*/
function edd_view_refund_page_content() {
// @todo Avoid killing page ouput.
if ( ! isset( $_GET['id'] ) || ! is_numeric( $_GET['id'] ) ) {
wp_die( __( 'Refund ID not supplied. Please try again.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ) );
}
$refund_id = absint( $_GET['id'] );
$refund = edd_get_order( $refund_id );
// Check that the refund exists in the database.
// @todo Avoid killing page ouput.
if ( empty( $refund ) || 'refund' !== $refund->type ) {
wp_die( __( 'The specified ID does not belong to an refund. Please try again.', 'easy-digital-downloads' ), __( 'Error', 'easy-digital-downloads' ) );
}
wp_enqueue_script( 'edd-admin-orders' );
// Enqueued for backwards compatibility. Empty file.
wp_enqueue_script( 'edd-admin-payments' );
?>
<?php edd_refund_details_notice( $refund ); ?>
<div class="wrap edd-wrap">
<h1><?php printf( esc_html__( 'Refund: %s', 'easy-digital-downloads' ), $refund->order_number ); ?></h1>
<?php
/**
* Allows output before Refund page content.
*
* @since 3.0
*
* @param int $refund_id ID of the current Refund.
*/
do_action( 'edd_view_refund_details_before', $refund->id );
?>
<div id="poststuff">
<div id="edd-dashboard-widgets-wrap">
<div id="post-body" class="metabox-holder columns-2">
<div id="postbox-container-2" class="postbox-container">
<div id="normal-sortables">
<?php
/**
* Allows output before the Refund details.
*
* @since 3.0
*
* @param int $refund_id ID of the current Refund.
*/
do_action( 'edd_view_refund_details_main_before', $refund->id );
// Refund Items.
edd_refund_details_items( $refund );
// Notes.
edd_refund_details_notes( $refund );
/**
* Allows further output after the Refund details.
*
* @since 3.0
*
* @param int $refund_id ID of the current Refund.
*/
do_action( 'edd_view_refund_details_main_after', $refund->id );
?>
</div>
</div>
<div id="postbox-container-1" class="postbox-container">
<div id="side-sortables">
<?php
/**
* Allows output before Refund sidebar content.
*
* @since 3.0
*
* @param int $refund_id ID of the current Refund.
*/
do_action( 'edd_view_refund_details_sidebar_before', $refund->id );
// Attributes.
edd_refund_details_attributes( $refund );
// Related Refunds.
edd_refund_details_related_refunds( $refund );
/**
* Allows further output after Refund sidebar content.
*
* @since 3.0
*
* @param int $refund_id ID of the current Refund.
*/
do_action( 'edd_view_refund_details_sidebar_after', $refund->id );
?>
</div>
</div>
</div>
</div>
</div>
</div><!-- /.wrap -->
<?php
}