installed plugin Easy Digital Downloads
version 3.1.0.3
This commit is contained in:
wp-content/plugins/easy-digital-downloads
assets
css
admin
chosen
datepicker.scssdownloads
email-tags.scssextension-manager.scssforms
gateways
general
menu.scssnotifications
orders
promos
reports
style.scsstax-rates
upgrades
variables
vendor
images
edd-cpt-2x.pngedd-cpt.pngedd-cross-hair.pngedd-icon-2x.pngedd-icon.pngedd-logo-pdf.pngedd-logo-white-2x.pngedd-logo.pngedd-logo.svgedd-media.pngedd-peeking.png
icons
icon-arrow-down.pngicon-arrow-up.pngicon-average.pngicon-chevron-down.svgicon-gross.pngicon-megaphone.pngicon-net.pngicon-new-customers.pngicon-top-products.pngiphone.png
loading.giflogo-edd-dark.svgmedia-button.pngpromo
screenshots
17checkout.png17direct.png17quantities.png18-button-colors.png18cart-saving.png20-discount.png20-register-login.png20-sequential.png20-unlimited-downloads.png22-logs.png22-purchased-downloads.png22-purchased-downloads2.png22-quantity.png24-category-earnings.png24-checkout.png24-export.png26-customer.png26-import.png26-refund.pngbundles.pngcustomer-ui.pngedit-download.pngemail-template-21.pnggrid.pngorder-details.pngproduct-earnings.pngproduct-tax.pngpurchase-link.pngtax-rates.png
ui-icons_21759b_256x240.pngui-icons_333333_256x240.pngui-icons_999999_256x240.pngui-icons_cc0000_256x240.pngxit.gifjs
admin
components
advanced-filters
chosen
date-picker
location
notifications
promos
sortable-list
taxonomies
tooltips
user-search
vertical-sections
customers
dashboard
discounts
downloads
index.jsnotes
notices
orders
index.jslist-table.js
order-details
order-overview
_refund.js
collections
index.jsmodels
views
actions.jsbase.jscopy-download-link.jsdialog.jsform-add-order-adjustment.jsform-add-order-discount.jsform-add-order-item.jsno-order-items.jsorder-adjustment.jsorder-adjustments.jsorder-credits.jsorder-discounts-fees.jsorder-item.jsorder-items.jsorder-refund.jsorder-refunds.jsorder-subtotal.jsorder-tax.jsorder-total.jsoverview.jssummary.js
payments
reports
settings
tools
upgrades
frontend
jquery.validate.min.jspackages
paypal-checkout.jsutils
vendor
chartjs.min.jschosen.jquery.min.jsjquery.creditcardvalidator.min.jsjquery.flot.min.jsjquery.flot.pie.min.jsjquery.flot.time.min.jsjquery.payment.min.jsmoment-timezone.min.jsmoment.min.js
wp-polyfill.min.jsincludes
EDD_SL_Plugin_Updater.phpactions.phpedd-blocks.phpmime-types.phpmisc-functions.php
adjustments
admin
add-ons.php
ajax-functions.phpadjustments
admin-actions.phpadmin-bar.phpadmin-deprecated-functions.phpadmin-footer.phpadmin-pages.phpclass-api-keys-table.phpclass-edd-heartbeat.phpclass-edd-notices.phpclass-list-table.phpclass-pass-manager.phpclass-sections.phpcustomers
class-customer-addresses-table.phpclass-customer-email-addresses-table.phpclass-customer-table.phpcustomer-actions.phpcustomer-functions.phpcustomers.php
dashboard-widgets.phpdiscounts
add-discount.phpclass-discount-codes-table.phpcontextual-help.phpdiscount-actions.phpdiscount-codes.phpedit-discount.php
downloads
emails
email-summary
extensions
abstract-extension.phpclass-extension-manager.phpclass-extension-product-data.phpclass-extensions-api.php
product-education
import
class-batch-import-downloads.phpclass-batch-import-payments.phpclass-batch-import.phpimport-actions.phpimport-functions.php
installers
notes
payments
actions.phpadd-order.phpclass-order-sections.phpclass-payments-table.phpclass-refund-items-table.phpcontextual-help.phporders.phppayments-history.phprefunds.phpview-order-details.phpview-refund.php
plugins.phppromos
reporting
class-api-requests-logs-list-table.phpclass-base-logs-list-table.phpclass-categories-reports-table.phpclass-download-reports-table.phpclass-edd-graph.phpclass-edd-pie-graph.phpclass-export-customers.phpclass-export-download-history.phpclass-export-payments.phpclass-export.phpclass-file-downloads-logs-list-table.phpclass-gateway-error-logs-list-table.phpclass-gateways-reports-table.phpclass-reports-sections.phpclass-sales-logs-list-table.phpcontextual-help.php
export
class-batch-export-api-requests.phpclass-batch-export-customers.phpclass-batch-export-downloads.phpclass-batch-export-earnings-report.phpclass-batch-export-file-downloads.phpclass-batch-export-payments.phpclass-batch-export-sales-and-earnings.phpclass-batch-export-sales.phpclass-batch-export-taxed-customers.phpclass-batch-export-taxed-orders.phpclass-batch-export.phpexport-actions.phpexport-functions.php
graphing.phplogs.phpreports-callbacks.phpreports.phpsettings
thickbox.phptools.phptools
class-edd-tools-recount-all-stats.phpclass-edd-tools-recount-customer-stats.phpclass-edd-tools-recount-download-stats.phpclass-edd-tools-recount-single-customer-stats.phpclass-edd-tools-recount-store-earnings.phpclass-edd-tools-reset-stats.phplogs.phptools-actions.php
tracking.phpupgrades
upload-functions.phpviews
notifications.phptmpl-order-actions.phptmpl-order-adjustment-discount.phptmpl-order-adjustment.phptmpl-order-copy-download-link.phptmpl-order-form-add-order-adjustment.phptmpl-order-form-add-order-discount.phptmpl-order-form-add-order-item.phptmpl-order-item.phptmpl-order-no-items.phptmpl-order-refund.phptmpl-order-subtotal.phptmpl-order-tax.phptmpl-order-total.phptmpl-tax-rates-table-add.phptmpl-tax-rates-table-bulk-actions.phptmpl-tax-rates-table-meta.phptmpl-tax-rates-table-row-empty.phptmpl-tax-rates-table-row.php
api
blocks
assets
build
buy-button
cart
checkout
confirmation
downloads
login
order-history
receipt
register
terms
includes
readme.mdviews
checkout
cart
cart-discounts.phpcart-fees.phpcart-footer-row.phpcart-item.phpcart-subtotal.phpcart-taxes.phpcart-total.phpcart.phpmini.php
discount.phplogged-in.phppurchase-form
downloads
forms
orders
credits.phpdiscounts.phpfees.phpguest.phporders.phppagination.phpreceipt-files.phpreceipt-item.phpreceipt-items.phptotals.php
terms.phpcart
checkout
class-base-object.phpclass-component.phpclass-easy-digital-downloads.phpclass-edd-cache-helper.phpclass-edd-cli.phpclass-edd-cron.phpclass-edd-customer-query.phpclass-edd-customer.phpclass-edd-db-customer-meta.phpclass-edd-db-customers.phpclass-edd-db.phpclass-edd-discount.phpclass-edd-download.phpclass-edd-fees.phpclass-edd-html-elements.phpclass-edd-license-handler.phpclass-edd-logging.phpclass-edd-register-meta.phpclass-edd-roles.phpclass-edd-session.phpclass-edd-stats.phpclass-stats.phpclass-structured-data.phpclass-utilities.phpcompat-functions.phpcompat
class-base.phpclass-customer.phpclass-customermeta.phpclass-discount-query.phpclass-discount.phpclass-edd-payment-compat.phpclass-log.phpclass-payment.phpclass-tax.phpclass-template.php
component-functions.phpcountry-functions.phpcurrency
customer-functions.phpcustomers
database
NotificationsDB.phpREADME.md
date-functions.phpdeprecated-functions.phpdeprecated-hooks.phpdiscount-functions.phpdownload-functions.phpengine
class-base.phpclass-column.phpclass-compare.phpclass-date.phpclass-meta.phpclass-query.phpclass-row.phpclass-schema.phpclass-table.php
queries
class-adjustment.phpclass-customer-address.phpclass-customer-email-address.phpclass-customer.phpclass-log-api-request.phpclass-log-file-download.phpclass-log.phpclass-note.phpclass-order-address.phpclass-order-adjustment.phpclass-order-item.phpclass-order-transaction.phpclass-order.php
rows
class-adjustment.phpclass-customer-address.phpclass-customer-email-address.phpclass-customer.phpclass-log-api-request.phpclass-log-file-download.phpclass-log.phpclass-note.phpclass-order-address.phpclass-order-adjustment.phpclass-order-item.phpclass-order-transaction.phpclass-order.php
schemas
class-adjustments.phpclass-customer-addresses.phpclass-customer-email-addresses.phpclass-customers.phpclass-logs-api-requests.phpclass-logs-file-downloads.phpclass-logs.phpclass-notes.phpclass-order-addresses.phpclass-order-adjustments.phpclass-order-items.phpclass-order-transactions.phpclass-orders.php
tables
class-adjustment-meta.phpclass-adjustments.phpclass-customer-addresses.phpclass-customer-email-addresses.phpclass-customer-meta.phpclass-customers.phpclass-log-meta.phpclass-logs-api-request-meta.phpclass-logs-api-requests.phpclass-logs-file-download-meta.phpclass-logs-file-downloads.phpclass-logs.phpclass-note-meta.phpclass-notes.phpclass-order-addresses.phpclass-order-adjustment-meta.phpclass-order-adjustments.phpclass-order-item-meta.phpclass-order-items.phpclass-order-meta.phpclass-order-transactions.phpclass-orders.php
downloads
emails
actions.phpclass-edd-email-tags.phpclass-edd-emails.php
error-tracking.phpemail-summary
class-edd-email-summary-blurb.phpclass-edd-email-summary-cron.phpclass-edd-email-summary.phpedd-email-summary-template.php
functions.phptags-inserter.phptags.phptemplate.phpextensions
formatting.phpgateways
actions.phpamazon-payments.phpfunctions.php
install.phpinterface-edd-exception.phplibs
manual.phppaypal-standard.phppaypal
admin
buy-now.phpcheckout-actions.phpclass-account-status-validator.phpclass-merchant-account.phpclass-paypal-api.phpclass-token.phpdeprecated.phpexceptions
class-api-exception.phpclass-authentication-exception.phpclass-gateway-exception.phpclass-invalid-merchant-details.phpclass-missing-merchant-details.php
functions.phpgateway-filters.phpintegrations.phpipn.phppaypal.phprefunds.phpscripts.phpwebhooks
stripe
apple-developer-merchantid-domain-associationedd-stripe.phppayment-receipt.phpscripts.phptemplate-functions.php
assets
css
build
src
js
includes
admin
admin-actions.phpadmin-filters.phpclass-notices-registry.phpclass-notices.phpnotices.php
card-actions.phpclass-edd-stripe-rate-limiting.phpclass-edd-stripe.phpclass-stripe-api.phpcompat.phpdeprecated.phpelements.phpemails.phpfunctions.phpgateway-actions.phpgateway-filters.phpi18n.phpnotices
reporting
settings.phpsettings
upgrade-functions.phpintegrations
payment-actions.phppayment-methods
buy-now
payment-request
utils
class-registry.php
webhooks.phpexceptions
class-attribute-not-found.phpclass-gateway-exception.phpclass-stripe-api-unmet-requirements.phpclass-stripe-object-not-found.php
interface-static-registry.phpmodal.phpvendor
autoload.php
composer
ClassLoader.phpInstalledVersions.phpLICENSEautoload_classmap.phpautoload_namespaces.phpautoload_psr4.phpautoload_real.phpautoload_static.phpinstalled.jsoninstalled.php
stripe
stripe-php
CHANGELOG.mdCODE_OF_CONDUCT.mdLICENSEMakefileREADME.mdVERSIONbuild.phpcomposer.json
data
init.phplib
Account.phpAccountLink.phpAlipayAccount.php
phpdoc.dist.xmlphpstan-baseline.neonphpstan.neon.distupdate_certs.phpApiOperations
ApiRequestor.phpApiResource.phpApiResponse.phpApplePayDomain.phpApplicationFee.phpApplicationFeeRefund.phpBalance.phpBalanceTransaction.phpBankAccount.phpBaseStripeClient.phpBillingPortal
BitcoinReceiver.phpBitcoinTransaction.phpCapability.phpCard.phpCharge.phpCheckout
Collection.phpCountrySpec.phpCoupon.phpCreditNote.phpCreditNoteLineItem.phpCustomer.phpCustomerBalanceTransaction.phpDiscount.phpDispute.phpEphemeralKey.phpErrorObject.phpEvent.phpException
ApiConnectionException.phpApiErrorException.phpAuthenticationException.phpBadMethodCallException.phpCardException.phpExceptionInterface.phpIdempotencyException.phpInvalidArgumentException.phpInvalidRequestException.php
ExchangeRate.phpFile.phpFileLink.phpOAuth
ExceptionInterface.phpInvalidClientException.phpInvalidGrantException.phpInvalidRequestException.phpInvalidScopeException.phpOAuthErrorException.phpUnknownOAuthErrorException.phpUnsupportedGrantTypeException.phpUnsupportedResponseTypeException.php
PermissionException.phpRateLimitException.phpSignatureVerificationException.phpUnexpectedValueException.phpUnknownApiErrorException.phpHttpClient
Invoice.phpInvoiceItem.phpInvoiceLineItem.phpIssuing
LineItem.phpLoginLink.phpMandate.phpOAuth.phpOAuthErrorObject.phpOrder.phpOrderItem.phpOrderReturn.phpPaymentIntent.phpPaymentMethod.phpPayout.phpPerson.phpPlan.phpPrice.phpProduct.phpPromotionCode.phpRadar
Recipient.phpRecipientTransfer.phpRefund.phpReporting
RequestTelemetry.phpReview.phpSKU.phpService
AbstractService.phpAbstractServiceFactory.phpAccountLinkService.phpAccountService.phpApplePayDomainService.phpApplicationFeeService.phpBalanceService.phpBalanceTransactionService.php
SetupIntent.phpBillingPortal
ChargeService.phpCheckout
CoreServiceFactory.phpCountrySpecService.phpCouponService.phpCreditNoteService.phpCustomerService.phpDisputeService.phpEphemeralKeyService.phpEventService.phpExchangeRateService.phpFileLinkService.phpFileService.phpInvoiceItemService.phpInvoiceService.phpIssuing
AuthorizationService.phpCardService.phpCardholderService.phpDisputeService.phpIssuingServiceFactory.phpTransactionService.php
MandateService.phpOAuthService.phpOrderReturnService.phpOrderService.phpPaymentIntentService.phpPaymentMethodService.phpPayoutService.phpPlanService.phpPriceService.phpProductService.phpPromotionCodeService.phpRadar
RefundService.phpReporting
ReviewService.phpSetupIntentService.phpSigma
SkuService.phpSourceService.phpSubscriptionItemService.phpSubscriptionScheduleService.phpSubscriptionService.phpTaxRateService.phpTerminal
TokenService.phpTopupService.phpTransferService.phpWebhookEndpointService.phpSigma
SingletonApiResource.phpSource.phpSourceTransaction.phpStripe.phpStripeClient.phpStripeClientInterface.phpStripeObject.phpSubscription.phpSubscriptionItem.phpSubscriptionSchedule.phpTaxId.phpTaxRate.phpTerminal
ThreeDSecure.phpToken.phpTopup.phpTransfer.phpTransferReversal.phpUsageRecord.phpUsageRecordSummary.phpUtil
CaseInsensitiveArray.phpDefaultLogger.phpLoggerInterface.phpObjectTypes.phpRandomGenerator.phpRequestOptions.phpSet.phpUtil.php
Webhook.phpWebhookEndpoint.phpWebhookSignature.phplibraries
Carbon.phparray2xml.phpbrowser.phpclass-ArrayToXML.phpclass-persistent-dismissible.phpclass-recursive-arrayaccess.phpclass-wp-session.phpwp-session.php
logs
api-request-log
file-download-log
log
models
notes
orders
classes
class-order-address.phpclass-order-adjustment.phpclass-order-item.phpclass-order-transaction.phpclass-order.phpclass-refund-validator.php
functions
payments
plugin-compatibility.phppost-types.phpprivacy-functions.phpprocess-download.phpprocess-purchase.phpquery-filters.phprefund-functions.phpreports
class-init.phpclass-registry.phpclass-base-object.phpclass-chart-endpoint.phpclass-endpoint-registry.phpclass-endpoint-view-registry.phpclass-endpoint.phpclass-report-registry.phpclass-report.phpclass-table-endpoint.phpclass-tile-endpoint.php
scripts.phpshortcodes.phptax-functions.phptemplate-actions.phptemplate-functions.phptheme-compatibility.phpdata
charts
v2
customers
discounts
downloads
file-downloads
payment-gateways
taxes
exceptions
reports-functions.phptraits
user-functions.phpusers
utils
EnvironmentChecker.phpNotificationImporter.phpclass-date.phpclass-edd-exception.phpclass-registry.phpclass-tokenizer.php
widgets.phpexceptions
interface-error-logger.phpinterface-static-registry.phplanguages
license.txtreadme.txttemplates
account-pending.phpcheckout_cart.phpedd.css
uninstall.phpemails
fonts
history-downloads.phphistory-purchases.phpimages
payment-processing.phpshortcode-content-cart-button.phpshortcode-content-excerpt.phpshortcode-content-full.phpshortcode-content-image.phpshortcode-content-price.phpshortcode-content-title.phpshortcode-download.phpshortcode-login.phpshortcode-profile-editor.phpshortcode-receipt.phpshortcode-register.phpwidget-cart-checkout.phpwidget-cart-empty.phpwidget-cart-item.phpwidget-cart.php@ -0,0 +1,472 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Action Functions
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage 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
|
||||
use EDD\Adjustments\Adjustment;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Manually add an order.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Order form data.
|
||||
* @return void
|
||||
*/
|
||||
function edd_add_manual_order( $args = array() ) {
|
||||
// Bail if user cannot manage shop settings or no data was passed.
|
||||
if ( empty( $args ) || ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up parameters.
|
||||
$nonce = isset( $_POST['edd_add_order_nonce'] )
|
||||
? sanitize_text_field( $_POST['edd_add_order_nonce'] )
|
||||
: '';
|
||||
|
||||
// Bail if nonce fails.
|
||||
if ( empty( $nonce ) || ! wp_verify_nonce( $nonce, 'edd_add_order_nonce' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get now one time to avoid microsecond issues
|
||||
$now = EDD()->utils->date( 'now', null, true )->timestamp;
|
||||
|
||||
// Parse args.
|
||||
$order_data = wp_parse_args( $args, array(
|
||||
'downloads' => array(),
|
||||
'adjustments' => array(),
|
||||
'subtotal' => 0.00,
|
||||
'tax' => 0.00,
|
||||
'total' => 0.00,
|
||||
'discount' => 0.00,
|
||||
'edd-payment-status' => 'complete',
|
||||
'payment_key' => '',
|
||||
'gateway' => '',
|
||||
'transaction_id' => '',
|
||||
'receipt' => '',
|
||||
'edd-payment-date' => date( 'Y-m-d', $now ),
|
||||
'edd-payment-time-hour' => date( 'G', $now ),
|
||||
'edd-payment-time-min' => date( 'i', $now ),
|
||||
'edd-unlimited-downloads' => 0,
|
||||
) );
|
||||
|
||||
/** Customer data *********************************************************/
|
||||
|
||||
// Defaults.
|
||||
$customer_id = 0;
|
||||
$user_id = 0;
|
||||
$email = '';
|
||||
$name = '';
|
||||
|
||||
// Create a new customer record.
|
||||
if ( isset( $order_data['edd-new-customer'] ) && 1 === absint( $order_data['edd-new-customer'] ) ) {
|
||||
|
||||
// Sanitize first name.
|
||||
$first_name = isset( $order_data['edd-new-customer-first-name'] )
|
||||
? sanitize_text_field( $order_data['edd-new-customer-first-name'] )
|
||||
: '';
|
||||
|
||||
// Sanitize last name.
|
||||
$last_name = isset( $order_data['edd-new-customer-last-name'] )
|
||||
? sanitize_text_field( $order_data['edd-new-customer-last-name'] )
|
||||
: '';
|
||||
|
||||
// Combine.
|
||||
$name = trim( $first_name . ' ' . $last_name );
|
||||
|
||||
// Sanitize the email address.
|
||||
$email = isset( $order_data['edd-new-customer-email'] )
|
||||
? sanitize_email( $order_data['edd-new-customer-email'] )
|
||||
: '';
|
||||
|
||||
$new_customer_args = array(
|
||||
'name' => $name,
|
||||
'email' => $email,
|
||||
);
|
||||
|
||||
// Determine if there is an existing user with this email address.
|
||||
$possible_user = get_user_by( 'email', $email );
|
||||
if ( $possible_user instanceof WP_User ) {
|
||||
$new_customer_args['user_id'] = $possible_user->ID;
|
||||
}
|
||||
|
||||
// Save to database.
|
||||
$customer_id = edd_add_customer(
|
||||
$new_customer_args
|
||||
);
|
||||
|
||||
$customer = edd_get_customer( $customer_id );
|
||||
|
||||
// Existing customer.
|
||||
} elseif ( isset( $order_data['edd-new-customer'] ) && 0 === absint( $order_data['edd-new-customer'] ) && isset( $order_data['customer-id'] ) ) {
|
||||
$customer_id = absint( $order_data['customer-id'] );
|
||||
$customer = edd_get_customer( $customer_id );
|
||||
|
||||
if ( $customer ) {
|
||||
$email = $customer->email;
|
||||
$user_id = $customer->user_id;
|
||||
$name = $customer->name;
|
||||
}
|
||||
}
|
||||
|
||||
/** Insert order **********************************************************/
|
||||
|
||||
// Parse order status.
|
||||
$status = sanitize_text_field( $order_data['edd-payment-status'] );
|
||||
|
||||
if ( empty( $status ) || ! in_array( $status, array_keys( edd_get_payment_statuses() ), true ) ) {
|
||||
$status = 'complete';
|
||||
}
|
||||
|
||||
// Get the date string.
|
||||
$date_string = EDD()->utils->get_date_string(
|
||||
sanitize_text_field( $order_data['edd-payment-date'] ),
|
||||
sanitize_text_field( $order_data['edd-payment-time-hour'] ),
|
||||
sanitize_text_field( $order_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' );
|
||||
|
||||
// Get mode
|
||||
$mode = edd_is_test_mode()
|
||||
? 'test'
|
||||
: 'live';
|
||||
|
||||
// Amounts
|
||||
$order_subtotal = floatval( $order_data['subtotal'] );
|
||||
$order_tax = floatval( $order_data['tax'] );
|
||||
$order_discount = floatval( $order_data['discount'] );
|
||||
$order_total = floatval( $order_data['total'] );
|
||||
|
||||
$tax_rate = false;
|
||||
// If taxes are enabled, get the tax rate for the order location.
|
||||
if ( edd_use_taxes() ) {
|
||||
$country = ! empty( $order_data['edd_order_address']['country'] )
|
||||
? $order_data['edd_order_address']['country']
|
||||
: false;
|
||||
|
||||
$region = ! empty( $order_data['edd_order_address']['region'] )
|
||||
? $order_data['edd_order_address']['region']
|
||||
: false;
|
||||
|
||||
$tax_rate = edd_get_tax_rate_by_location(
|
||||
array(
|
||||
'country' => $country,
|
||||
'region' => $region,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Add the order ID
|
||||
$order_id = edd_add_order(
|
||||
array(
|
||||
'status' => 'pending', // Always insert as pending initially.
|
||||
'user_id' => $user_id,
|
||||
'customer_id' => $customer_id,
|
||||
'email' => $email,
|
||||
'ip' => sanitize_text_field( $order_data['ip'] ),
|
||||
'gateway' => sanitize_text_field( $order_data['gateway'] ),
|
||||
'mode' => $mode,
|
||||
'currency' => edd_get_currency(),
|
||||
'payment_key' => $order_data['payment_key'] ? sanitize_text_field( $order_data['payment_key'] ) : edd_generate_order_payment_key( $email ),
|
||||
'tax_rate_id' => ! empty( $tax_rate->id ) ? $tax_rate->id : null,
|
||||
'subtotal' => $order_subtotal,
|
||||
'tax' => $order_tax,
|
||||
'discount' => $order_discount,
|
||||
'total' => $order_total,
|
||||
'date_created' => $date,
|
||||
)
|
||||
);
|
||||
|
||||
// Attach order to the customer record.
|
||||
if ( ! empty( $customer ) ) {
|
||||
$customer->attach_payment( $order_id, false );
|
||||
}
|
||||
|
||||
// If we have tax, but no tax rate, manually save the percentage.
|
||||
if ( empty( $tax_rate->id ) && $order_tax > 0 ) {
|
||||
$tax_rate_percentage = $order_data['tax_rate'];
|
||||
if ( ! empty( $tax_rate_percentage ) ) {
|
||||
if ( $tax_rate_percentage > 0 && $tax_rate_percentage < 1 ) {
|
||||
$tax_rate_percentage = $tax_rate_percentage * 100;
|
||||
}
|
||||
|
||||
edd_update_order_meta( $order_id, 'tax_rate', $tax_rate_percentage );
|
||||
}
|
||||
}
|
||||
|
||||
/** Insert order address **************************************************/
|
||||
|
||||
if ( isset( $order_data['edd_order_address'] ) ) {
|
||||
|
||||
// Parse args
|
||||
$address = wp_parse_args( $order_data['edd_order_address'], array(
|
||||
'name' => $name,
|
||||
'address' => '',
|
||||
'address2' => '',
|
||||
'city' => '',
|
||||
'postal_code' => '',
|
||||
'country' => '',
|
||||
'region' => '',
|
||||
) );
|
||||
|
||||
$order_address_data = $address;
|
||||
$order_address_data['order_id'] = $order_id;
|
||||
|
||||
// Remove empty data.
|
||||
$order_address_data = array_filter( $order_address_data );
|
||||
|
||||
// Add to edd_order_addresses table.
|
||||
edd_add_order_address( $order_address_data );
|
||||
|
||||
// Maybe add the address to the edd_customer_addresses.
|
||||
$customer_address_data = $order_address_data;
|
||||
|
||||
// We don't need to pass this data to edd_maybe_add_customer_address().
|
||||
unset( $customer_address_data['order_id'] );
|
||||
|
||||
edd_maybe_add_customer_address( $customer->id, $customer_address_data );
|
||||
}
|
||||
|
||||
/** Insert order items ****************************************************/
|
||||
|
||||
// Any adjustments specific to an order item need to be added to the item.
|
||||
foreach ( $order_data['adjustments'] as $key => $adjustment ) {
|
||||
if ( 'order_item' === $adjustment['object_type'] ) {
|
||||
$order_data['downloads'][ $adjustment['object_id'] ]['adjustments'][] = $adjustment;
|
||||
|
||||
unset( $order_data['adjustments'][ $key ] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $order_data['downloads'] ) ) {
|
||||
|
||||
// Re-index downloads.
|
||||
$order_data['downloads'] = array_values( $order_data['downloads'] );
|
||||
|
||||
$downloads = array_reverse( $order_data['downloads'] );
|
||||
|
||||
foreach ( $downloads as $cart_key => $download ) {
|
||||
$d = edd_get_download( absint( $download['id'] ) );
|
||||
|
||||
// Skip if download no longer exists
|
||||
if ( empty( $d ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Quantity.
|
||||
$quantity = isset( $download['quantity'] )
|
||||
? absint( $download['quantity'] )
|
||||
: 1;
|
||||
|
||||
// Price ID.
|
||||
$price_id = isset( $download['price_id'] ) && is_numeric( $download['price_id'] )
|
||||
? absint( $download['price_id'] )
|
||||
: null;
|
||||
|
||||
// Amounts.
|
||||
$amount = isset( $download[ 'amount' ] )
|
||||
? floatval( $download[ 'amount' ] )
|
||||
: 0.00;
|
||||
|
||||
$subtotal = isset( $download[ 'subtotal' ] )
|
||||
? floatval( $download[ 'subtotal' ] )
|
||||
: 0.00;
|
||||
|
||||
$discount = isset( $download[ 'discount' ] )
|
||||
? floatval( $download[ 'discount' ] )
|
||||
: 0.00;
|
||||
|
||||
$tax = isset( $download[ 'tax' ] )
|
||||
? floatval( $download[ 'tax' ] )
|
||||
: 0.00;
|
||||
|
||||
$total = isset( $download[ 'total' ] )
|
||||
? floatval( $download[ 'total' ] )
|
||||
: 0.00;
|
||||
|
||||
// Add to edd_order_items table.
|
||||
$order_item_id = edd_add_order_item( array(
|
||||
'order_id' => $order_id,
|
||||
'product_id' => absint( $download['id'] ),
|
||||
'product_name' => edd_get_download_name( $download['id'], absint( $price_id ) ),
|
||||
'price_id' => $price_id,
|
||||
'cart_index' => $cart_key,
|
||||
'type' => 'download',
|
||||
'status' => 'complete',
|
||||
'quantity' => $quantity,
|
||||
'amount' => $amount,
|
||||
'subtotal' => $subtotal,
|
||||
'discount' => $discount,
|
||||
'tax' => $tax,
|
||||
'total' => $total,
|
||||
) );
|
||||
|
||||
if ( false !== $order_item_id ) {
|
||||
if ( isset( $download['adjustments'] ) ) {
|
||||
$order_item_adjustments = array_reverse( $download['adjustments'] );
|
||||
|
||||
foreach ( $order_item_adjustments as $index => $order_item_adjustment ) {
|
||||
|
||||
// Discounts are not tracked at the Order Item level.
|
||||
if ( 'discount' === $order_item_adjustment['type'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type_key = ! empty( $order_item_adjustment['description'] )
|
||||
? sanitize_text_field( strtolower( sanitize_title( $order_item_adjustment['description'] ) ) )
|
||||
: $index;
|
||||
|
||||
$order_item_adjustment_subtotal = floatval( $order_item_adjustment['subtotal'] );
|
||||
$order_item_adjustment_tax = floatval( $order_item_adjustment['tax'] );
|
||||
$order_item_adjustment_total = floatval( $order_item_adjustment['total'] );
|
||||
|
||||
edd_add_order_adjustment( array(
|
||||
'object_id' => $order_item_id,
|
||||
'object_type' => 'order_item',
|
||||
'type' => sanitize_text_field( $order_item_adjustment['type'] ),
|
||||
'type_key' => $type_key,
|
||||
'description' => sanitize_text_field( $order_item_adjustment['description'] ),
|
||||
'subtotal' => $order_item_adjustment_subtotal,
|
||||
'tax' => $order_item_adjustment_tax,
|
||||
'total' => $order_item_adjustment_total,
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Insert adjustments ****************************************************/
|
||||
|
||||
// Adjustments.
|
||||
if ( isset( $order_data['adjustments'] ) ) {
|
||||
$adjustments = array_reverse( $order_data['adjustments'] );
|
||||
|
||||
foreach ( $adjustments as $index => $adjustment ) {
|
||||
if ( 'order_item' === $adjustment['object_type'] ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$type_key = ! empty( $adjustment['description'] )
|
||||
? sanitize_text_field( strtolower( sanitize_title( $adjustment['description'] ) ) )
|
||||
: $index;
|
||||
|
||||
$adjustment_subtotal = floatval( $adjustment['subtotal'] );
|
||||
$adjustment_tax = floatval( $adjustment['tax'] );
|
||||
$adjustment_total = floatval( $adjustment['total'] );
|
||||
|
||||
edd_add_order_adjustment( array(
|
||||
'object_id' => $order_id,
|
||||
'object_type' => 'order',
|
||||
'type' => sanitize_text_field( $adjustment['type'] ),
|
||||
'type_key' => $type_key,
|
||||
'description' => sanitize_text_field( $adjustment['description'] ),
|
||||
'subtotal' => $adjustment_subtotal,
|
||||
'tax' => $adjustment_tax,
|
||||
'total' => $adjustment_total,
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
// Discounts.
|
||||
if ( isset( $order_data['discounts'] ) ) {
|
||||
$discounts = array_reverse( $order_data['discounts'] );
|
||||
|
||||
foreach ( $discounts as $discount ) {
|
||||
$d = edd_get_discount( absint( $discount['type_id'] ) );
|
||||
|
||||
if ( empty( $d ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$discount_subtotal = floatval( $discount['subtotal'] );
|
||||
$discount_total = floatval( $discount['total'] );
|
||||
|
||||
// Store discount.
|
||||
edd_add_order_adjustment( array(
|
||||
'object_id' => $order_id,
|
||||
'object_type' => 'order',
|
||||
'type_id' => intval( $discount['type_id'] ),
|
||||
'type' => 'discount',
|
||||
'description' => sanitize_text_field( $discount['code'] ),
|
||||
'subtotal' => $discount_subtotal,
|
||||
'total' => $discount_total,
|
||||
) );
|
||||
}
|
||||
}
|
||||
|
||||
// Insert transaction ID.
|
||||
if ( ! empty( $order_data['transaction_id'] ) ) {
|
||||
edd_add_order_transaction( array(
|
||||
'object_id' => $order_id,
|
||||
'object_type' => 'order',
|
||||
'transaction_id' => sanitize_text_field( $order_data['transaction_id'] ),
|
||||
'gateway' => sanitize_text_field( $order_data['gateway'] ),
|
||||
'status' => 'complete',
|
||||
'total' => $order_total,
|
||||
) );
|
||||
}
|
||||
|
||||
// Unlimited downloads.
|
||||
if ( isset( $order_data['edd-unlimited-downloads'] ) && 1 === (int) $order_data['edd-unlimited-downloads'] ) {
|
||||
edd_update_order_meta( $order_id, 'unlimited_downloads', 1 );
|
||||
}
|
||||
|
||||
// Setup order number.
|
||||
$order_number = '';
|
||||
|
||||
if ( edd_get_option( 'enable_sequential' ) ) {
|
||||
$number = edd_get_next_payment_number();
|
||||
|
||||
$order_number = edd_format_payment_number( $number );
|
||||
|
||||
update_option( 'edd_last_payment_number', $number );
|
||||
|
||||
// Update totals & maybe add order number.
|
||||
edd_update_order( $order_id, array(
|
||||
'order_number' => $order_number,
|
||||
) );
|
||||
}
|
||||
|
||||
// Stop purchase receipt from being sent.
|
||||
if ( ! isset( $order_data['edd_order_send_receipt'] ) ) {
|
||||
remove_action( 'edd_complete_purchase', 'edd_trigger_purchase_receipt', 999 );
|
||||
}
|
||||
|
||||
// Trigger edd_complete_purchase.
|
||||
if ( 'complete' === $status ) {
|
||||
edd_update_order_status( $order_id, $status );
|
||||
}
|
||||
|
||||
/**
|
||||
* Action hook which runs after a manual order has been added to the database.
|
||||
*
|
||||
* @since 3.0
|
||||
* @param int $order_id The new order ID.
|
||||
* @param array $order_data The array of order data.
|
||||
* @param array $args The original form data.
|
||||
*/
|
||||
do_action( 'edd_post_add_manual_order', $order_id, $order_data, $args );
|
||||
|
||||
// Redirect to `Edit Order` page.
|
||||
edd_redirect( edd_get_admin_url( array(
|
||||
'page' => 'edd-payment-history',
|
||||
'view' => 'view-order-details',
|
||||
'id' => urlencode( $order_id ),
|
||||
'edd-message' => 'order_added',
|
||||
) ) );
|
||||
}
|
||||
add_action( 'edd_add_order', 'edd_add_manual_order' );
|
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Address Functions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage 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;
|
||||
|
||||
/**
|
||||
* Add an order address.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $data {
|
||||
* Array of order address data. Default empty.
|
||||
*
|
||||
* The `date_created` and `date_modified` parameters do not need to be passed.
|
||||
* They will be automatically populated if empty.
|
||||
*
|
||||
* @type int $order_id Order ID. Default `0`.
|
||||
* @type string $name Customer's full name. Default empty.
|
||||
* @type string $address First line of address. Default empty.
|
||||
* @type string $address2 Second line of address. Default empty.
|
||||
* @type string $city City. Default empty.
|
||||
* @type string $region Region. See `edd_get_shop_states()` for
|
||||
* accepted values. Default empty.
|
||||
* @type string $postal_code Postal code. Default empty.
|
||||
* @type string $country Country. See `edd_get_country_list()` for
|
||||
* accepted values. Default empty.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the address was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the address was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
* @return int|false ID of newly created order address, false on error.
|
||||
*/
|
||||
function edd_add_order_address( $data ) {
|
||||
|
||||
// An order ID must be supplied for every address inserted.
|
||||
if ( empty( $data['order_id'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up an array with empty address keys. If all of these are empty in $data, the address should not be added.
|
||||
$empty_address = array(
|
||||
'address' => '',
|
||||
'address2' => '',
|
||||
'city' => '',
|
||||
'region' => '',
|
||||
'country' => '',
|
||||
'postal_code' => '',
|
||||
);
|
||||
$address_to_check = array_intersect_key( $data, $empty_address );
|
||||
$address_to_check = array_filter( $address_to_check );
|
||||
if ( empty( $address_to_check ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instantiate a query object
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address();
|
||||
|
||||
return $order_addresses->add_item( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an order address.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_address_id Order address ID.
|
||||
* @return int|false `1` if the address was deleted successfully, false on error.
|
||||
*/
|
||||
function edd_delete_order_address( $order_address_id = 0 ) {
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address();
|
||||
|
||||
return $order_addresses->delete_item( $order_address_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an order address.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_address_id Order address ID.
|
||||
* @param array $data {
|
||||
* Array of order address data. Default empty.
|
||||
*
|
||||
* @type int $order_id Order ID. Default `0`.
|
||||
* @type string $name Customer's full name. Default empty.
|
||||
* @type string $address First line of address. Default empty.
|
||||
* @type string $address2 Second line of address. Default empty.
|
||||
* @type string $city City. Default empty.
|
||||
* @type string $region Region. See `edd_get_shop_states()` for
|
||||
* accepted values. Default empty.
|
||||
* @type string $postal_code Postal code. Default empty.
|
||||
* @type string $country Country. See `edd_get_country_list()` for
|
||||
* accepted values. Default empty.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the address was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the address was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
*
|
||||
* @return bool Whether or not the API request order was updated.
|
||||
*/
|
||||
function edd_update_order_address( $order_address_id = 0, $data = array() ) {
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address();
|
||||
|
||||
return $order_addresses->update_item( $order_address_id, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order address by ID.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_address_id Order address ID.
|
||||
* @return \EDD\Orders\Order_Address|false Order_Address if successful, false
|
||||
* otherwise.
|
||||
*/
|
||||
function edd_get_order_address( $order_address_id = 0 ) {
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address();
|
||||
|
||||
// Return order address
|
||||
return $order_addresses->get_item( $order_address_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order address by a specific field value.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $field Database table field.
|
||||
* @param string $value Value of the row.
|
||||
*
|
||||
* @return \EDD\Orders\Order_Address|false Order_Address if successful, false otherwise.
|
||||
*/
|
||||
function edd_get_order_address_by( $field = '', $value = '' ) {
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address();
|
||||
|
||||
// Return order address
|
||||
return $order_addresses->get_item_by( $field, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for order addresses.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Address::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Address` for
|
||||
* accepted arguments.
|
||||
* @return \EDD\Orders\Order_Address[] Array of `Order_Address` objects.
|
||||
*/
|
||||
function edd_get_order_addresses( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'number' => 30,
|
||||
) );
|
||||
|
||||
// Instantiate a query object
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address();
|
||||
|
||||
// Return orders
|
||||
return $order_addresses->query( $r );
|
||||
}
|
||||
|
||||
/**
|
||||
* Count order addresses.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Address::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Address` for
|
||||
* accepted arguments.
|
||||
* @return int Number of order addresses returned based on query arguments passed.
|
||||
*/
|
||||
function edd_count_order_addresses( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'count' => true,
|
||||
) );
|
||||
|
||||
// Query for count(s)
|
||||
$order_addresses = new EDD\Database\Queries\Order_Address( $r );
|
||||
|
||||
// Return count(s)
|
||||
return absint( $order_addresses->found_items );
|
||||
}
|
@ -0,0 +1,264 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Adjustment Functions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Orders\Adjustments
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Add an order adjustment.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $data {
|
||||
* Array of order adjustment data. Default empty.
|
||||
*
|
||||
* The `date_created` and `date_modified` parameters do not need to be passed.
|
||||
* They will be automatically populated if empty.
|
||||
*
|
||||
* @type int $parent Parent ID. Only used when creating refunds to link
|
||||
* a refund order adjustment to the original order adjustment.
|
||||
* Default 0.
|
||||
* @type int $object_id Object ID that the adjustment refers to. This would
|
||||
* be an ID that corresponds to the object type
|
||||
* specified. E.g. an object ID of 25 with object
|
||||
* type of `order` refers to order 25 in the
|
||||
* `edd_orders` table. Default empty.
|
||||
* @type string $object_type Object type that the adjustment refers to.
|
||||
* E.g. `order` or `order_item`. Default empty.
|
||||
* @type int $type_id Object ID of the adjustment type. E.g. a type
|
||||
* ID of 25 with type of `discount` refers to
|
||||
* discount 25 in te `edd_discounts` table.
|
||||
* Default empty.
|
||||
* @type string $type Object type of the adjustment type. E.g. `discount`.
|
||||
* Default empty.
|
||||
* @type string $description Description. Default empty.
|
||||
* @type float $subtotal Subtotal. Default 0.
|
||||
* @type float $tax Tax applicable. Default 0.
|
||||
* @type float $total Adjustment total. Default 0.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the adjustment was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the adjustment was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
* @return int|false ID of newly created order adjustment, false on error.
|
||||
*/
|
||||
function edd_add_order_adjustment( $data ) {
|
||||
|
||||
// An object ID and object ID must be supplied for every order that is
|
||||
// inserted into the database.
|
||||
if ( empty( $data['object_id'] ) || empty( $data['object_type'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instantiate a query object
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
|
||||
|
||||
$order_adjustment_id = $order_adjustments->add_item( $data );
|
||||
|
||||
if ( ! empty( $order_adjustment_id ) ) {
|
||||
/**
|
||||
* Action that runs when an order item is successfully added.
|
||||
*
|
||||
* @since 3.1
|
||||
* @param int Order adjustment ID.
|
||||
* @param array Array of order adjustment data.
|
||||
*/
|
||||
do_action( 'edd_order_adjustment_added', $order_adjustment_id, $data );
|
||||
}
|
||||
|
||||
return $order_adjustment_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an order adjustment.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_adjustment_id Order adjustment ID.
|
||||
* @return int|false `1` if the adjustment was deleted successfully, false on error.
|
||||
*/
|
||||
function edd_delete_order_adjustment( $order_adjustment_id = 0 ) {
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
|
||||
|
||||
return $order_adjustments->delete_item( $order_adjustment_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an order adjustment.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_adjustment_id Order adjustment ID.
|
||||
* @param array $data {
|
||||
* Array of order adjustment data. Default empty.
|
||||
*
|
||||
* @type int $object_id Object ID that the adjustment refers to. This would
|
||||
* be an ID that corresponds to the object type
|
||||
* specified. E.g. an object ID of 25 with object
|
||||
* type of `order` refers to order 25 in the
|
||||
* `edd_orders` table. Default empty.
|
||||
* @type string $object_type Object type that the adjustment refers to.
|
||||
* E.g. `order` or `order_item`. Default empty.
|
||||
* @type int $type_id Object ID of the adjustment type. E.g. a type
|
||||
* ID of 25 with type of `discount` refers to
|
||||
* discount 25 in te `edd_discounts` table.
|
||||
* Default empty.
|
||||
* @type string $type Object type of the adjustment type. E.g. `discount`.
|
||||
* Default empty.
|
||||
* @type string $description Description. Default empty.
|
||||
* @type float $subtotal Subtotal. Default 0.
|
||||
* @type float $tax Tax applicable. Default 0.
|
||||
* @type float $total Adjustment total. Default 0.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the adjustment was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the adjustment was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
*
|
||||
* @return int|false Number of rows updated if successful, false otherwise.
|
||||
*/
|
||||
function edd_update_order_adjustment( $order_adjustment_id = 0, $data = array() ) {
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
|
||||
|
||||
$previous_adjustment = edd_get_order_adjustment( $order_adjustment_id );
|
||||
$order_adjustment_updated = $order_adjustments->update_item( $order_adjustment_id, $data );
|
||||
|
||||
if ( ! empty( $order_adjustment_updated ) ) {
|
||||
/**
|
||||
* Action that runs when an order item is updated.
|
||||
*
|
||||
* @since 3.1
|
||||
* @param int The order adjustment ID.
|
||||
* @param array The array of data to update.
|
||||
* @param EDD\Orders\Order_Adjustment The original order adjustment object.
|
||||
*/
|
||||
do_action( 'edd_order_adjustment_updated', $order_adjustment_id, $data, $previous_adjustment );
|
||||
}
|
||||
|
||||
return $order_adjustment_updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order adjustment by ID.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_adjustment_id Order adjustment ID.
|
||||
* @return EDD\Orders\Order_Adjustment|false Order_Adjustment object if successful,
|
||||
* false otherwise.
|
||||
*/
|
||||
function edd_get_order_adjustment( $order_adjustment_id = 0 ) {
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
|
||||
|
||||
// Return order adjustment
|
||||
return $order_adjustments->get_item( $order_adjustment_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order adjustment by a specific field value.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $field Database table field.
|
||||
* @param string $value Value of the row.
|
||||
*
|
||||
* @return EDD\Orders\Order_Adjustment|false Order_Adjustment object if successful,
|
||||
* false otherwise.
|
||||
*/
|
||||
function edd_get_order_adjustment_by( $field = '', $value = '' ) {
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
|
||||
|
||||
// Return order adjustment
|
||||
return $order_adjustments->get_item_by( $field, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for order adjustments.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Adjustment::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Adjustment` for
|
||||
* accepted arguments.
|
||||
* @return \EDD\Orders\Order_Adjustment[] Array of `Order_Adjustment` objects.
|
||||
*/
|
||||
function edd_get_order_adjustments( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'number' => 30,
|
||||
) );
|
||||
|
||||
// Instantiate a query object
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment();
|
||||
|
||||
// Return orders
|
||||
return $order_adjustments->query( $r );
|
||||
}
|
||||
|
||||
/**
|
||||
* Count order adjustments.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Adjustment::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Adjustment` for
|
||||
* accepted arguments.
|
||||
* @return int Number of order adjustments returned based on query arguments passed.
|
||||
*/
|
||||
function edd_count_order_adjustments( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'count' => true,
|
||||
) );
|
||||
|
||||
// Query for count(s)
|
||||
$order_adjustments = new EDD\Database\Queries\Order_Adjustment( $r );
|
||||
|
||||
// Return count(s)
|
||||
return absint( $order_adjustments->found_items );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for and return array of order adjustment counts, keyed by status.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Adjustment::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Adjustment` for
|
||||
* accepted arguments.
|
||||
*
|
||||
* @return array Order adjustment counts keyed by status.
|
||||
*/
|
||||
function edd_get_order_adjustment_counts( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'object_id' => 0,
|
||||
'object_type' => 'order',
|
||||
'count' => true,
|
||||
'groupby' => 'type',
|
||||
) );
|
||||
|
||||
// Query for count
|
||||
$counts = new EDD\Database\Queries\Order_Adjustment( $r );
|
||||
|
||||
// Format & return
|
||||
return edd_format_counts( $counts, $r['groupby'] );
|
||||
}
|
@ -0,0 +1,273 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Item Functions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage 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;
|
||||
|
||||
/**
|
||||
* Add an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $data {
|
||||
* Array of order item data. Default empty.
|
||||
*
|
||||
* The `date_created` and `date_modified` parameters do not need to be passed.
|
||||
* They will be automatically populated if empty.
|
||||
*
|
||||
* @type int $parent Parent ID. Only used when creating refunds to link
|
||||
* a refund order item to the original order item.
|
||||
* Default 0.
|
||||
* @type int $order_id Order ID. Default 0.
|
||||
* @type int $product_id Product ID of the order item purchased. ID
|
||||
* refers to the download in the `wp_posts` table.
|
||||
* Default 0.
|
||||
* @type string $product_name Name of the order item. Default empty.
|
||||
* @type int|null $price_id ID of the price option purchased. Default null (no price ID).
|
||||
* @type int $cart_index Position of the order item in the cart.
|
||||
* Default 0.
|
||||
* @type string $type Order item type. Default `download`.
|
||||
* @type string $status Status of the order item. Default `pending`.
|
||||
* @type int $quantity Quantity purchased of the order item. Default 0.
|
||||
* @type float $amount Amount for the order item. Default 0.
|
||||
* @type float $subtotal Subtotal of the order item. Default 0.
|
||||
* @type float $discount Discount applied to the order item. Default 0.
|
||||
* @type float $tax Tax applied to the order item. Default 0.
|
||||
* @type float $total Item total. Default 0.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the order item was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the order item was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
* @return int|false ID of newly created order, false on error.
|
||||
*/
|
||||
function edd_add_order_item( $data = array() ) {
|
||||
|
||||
// An order ID and product ID must be supplied for every order that is
|
||||
// inserted into the database.
|
||||
if ( empty( $data['order_id'] ) || empty( $data['product_id'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instantiate a query object
|
||||
$order_items = new EDD\Database\Queries\Order_Item();
|
||||
|
||||
$order_item_id = $order_items->add_item( $data );
|
||||
|
||||
if ( ! empty( $order_item_id ) ) {
|
||||
/**
|
||||
* Action that runs when an order item is successfully added.
|
||||
*
|
||||
* @since 3.1
|
||||
* @param int Order item ID.
|
||||
* @param array Array of order item data.
|
||||
*/
|
||||
do_action( 'edd_order_item_added', $order_item_id, $data );
|
||||
}
|
||||
|
||||
return $order_item_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order item ID.
|
||||
* @return int|false `1` if the item was deleted successfully, false on error.
|
||||
*/
|
||||
function edd_delete_order_item( $order_item_id = 0 ) {
|
||||
$order_items = new EDD\Database\Queries\Order_Item();
|
||||
|
||||
$order_item_deleted = $order_items->delete_item( $order_item_id );
|
||||
|
||||
if ( ! empty( $order_item_deleted ) ) {
|
||||
/**
|
||||
* Action that runs when an order item is deleted.
|
||||
*
|
||||
* @since 3.0.5
|
||||
*
|
||||
* @param int $order_item_id Order item ID being deleted.
|
||||
*/
|
||||
do_action( 'edd_order_item_deleted', $order_item_id );
|
||||
}
|
||||
|
||||
return $order_item_deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order item ID.
|
||||
* @param array $data {
|
||||
* Array of order item data. Default empty.
|
||||
*
|
||||
* @type int $order_id Order ID. Default 0.
|
||||
* @type int $product_id Product ID of the order item purchased. ID
|
||||
* refers to the download in the `wp_posts` table.
|
||||
* Default 0.
|
||||
* @type string $product_name Name of the order item. Default empty.
|
||||
* @type int $price_id ID of the price option purchased. Default 0.
|
||||
* @type int $cart_index Position of the order item in the cart.
|
||||
* Default 0.
|
||||
* @type string $type Order item type. Default `download`.
|
||||
* @type string $status Status of the order item. Default `inherit`.
|
||||
* @type int $quantity Quantity purchased of the order item. Default 0.
|
||||
* @type float $amount Amount for the order item. Default 0.
|
||||
* @type float $subtotal Subtotal of the order item. Default 0.
|
||||
* @type float $discount Discount applied to the order item. Default 0.
|
||||
* @type float $tax Tax applied to the order item. Default 0.
|
||||
* @type float $total Item total. Default 0.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the order item was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the order item was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
*
|
||||
* @return int|false Number of rows updated if successful, false otherwise.
|
||||
*/
|
||||
function edd_update_order_item( $order_item_id = 0, $data = array() ) {
|
||||
$order_items = new EDD\Database\Queries\Order_Item();
|
||||
|
||||
$previous_order_item_data = edd_get_order_item( $order_item_id );
|
||||
$order_item_updated = $order_items->update_item( $order_item_id, $data );
|
||||
|
||||
if ( ! empty( $order_item_updated ) ) {
|
||||
/**
|
||||
* Action that runs when an order item is updated.
|
||||
*
|
||||
* @since 3.1
|
||||
* @param int The order item ID.
|
||||
* @param array The array of data to update.
|
||||
* @param EDD\Orders\Order_Item The original order item object.
|
||||
*/
|
||||
do_action( 'edd_order_item_updated', $order_item_id, $data, $previous_order_item_data );
|
||||
}
|
||||
|
||||
return $order_item_updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order item by ID.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order item ID.
|
||||
* @return EDD\Orders\Order_Item|false Order_Item object if successful, false
|
||||
* otherwise.
|
||||
*/
|
||||
function edd_get_order_item( $order_item_id = 0 ) {
|
||||
$order_items = new EDD\Database\Queries\Order_Item();
|
||||
|
||||
// Return order item
|
||||
return $order_items->get_item( $order_item_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order item by field and value.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $field Database table field.
|
||||
* @param string $value Value of the row.
|
||||
*
|
||||
* @return EDD\Orders\Order_Item|false Order_Item object if successful, false
|
||||
* otherwise.
|
||||
*/
|
||||
function edd_get_order_item_by( $field = '', $value = '' ) {
|
||||
$order_items = new EDD\Database\Queries\Order_Item();
|
||||
|
||||
// Return order item
|
||||
return $order_items->get_item_by( $field, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for order items.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Item::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Item` for
|
||||
* accepted arguments.
|
||||
* @return \EDD\Orders\Order_Item[] Array of `Order_Item` objects.
|
||||
*/
|
||||
function edd_get_order_items( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'number' => 30,
|
||||
) );
|
||||
|
||||
// Instantiate a query object
|
||||
$order_items = new EDD\Database\Queries\Order_Item();
|
||||
|
||||
// Return items
|
||||
return $order_items->query( $r );
|
||||
}
|
||||
|
||||
/**
|
||||
* Count order items.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Item::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Item` for
|
||||
* accepted arguments.
|
||||
* @return int Number of order items returned based on query arguments passed.
|
||||
*/
|
||||
function edd_count_order_items( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'count' => true,
|
||||
) );
|
||||
|
||||
// Query for count(s)
|
||||
$order_items = new EDD\Database\Queries\Order_Item( $r );
|
||||
|
||||
// Return count(s)
|
||||
return absint( $order_items->found_items );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for and return array of order item counts, keyed by status.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Item::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Item` for
|
||||
* accepted arguments.
|
||||
* @return array Order items keyed by status.
|
||||
*/
|
||||
function edd_get_order_item_counts( $args = array() ) {
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'order_id' => 0,
|
||||
'count' => true,
|
||||
'groupby' => 'status',
|
||||
) );
|
||||
|
||||
// Query for count
|
||||
$counts = new EDD\Database\Queries\Order_Item( $r );
|
||||
|
||||
// Format & return
|
||||
return edd_format_counts( $counts, $r['groupby'] );
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Meta Functions
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage 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;
|
||||
|
||||
/** Orders ********************************************************************/
|
||||
|
||||
/**
|
||||
* Add meta data field to an order.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param string $meta_key Meta data name.
|
||||
* @param mixed $meta_value Meta data value. Must be serializable if non-scalar.
|
||||
* @param bool $unique Optional. Whether the same key should not be added. Default false.
|
||||
*
|
||||
* @return int|false Meta ID on success, false on failure.
|
||||
*/
|
||||
function edd_add_order_meta( $order_id, $meta_key, $meta_value, $unique = false ) {
|
||||
return add_metadata( 'edd_order', $order_id, $meta_key, $meta_value, $unique );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove meta data matching criteria from an order.
|
||||
*
|
||||
* You can match based on the key, or key and value. Removing based on key and value, will keep from removing duplicate
|
||||
* meta data with the same key. It also allows removing all meta data matching key, if needed.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param string $meta_key Meta data name.
|
||||
* @param mixed $meta_value Optional. Meta data value. Must be serializable if non-scalar. Default empty.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function edd_delete_order_meta( $order_id, $meta_key, $meta_value = '' ) {
|
||||
return delete_metadata( 'edd_order', $order_id, $meta_key, $meta_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve order meta field for an order.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param string $key Optional. The meta key to retrieve. By default, returns data for all keys. Default empty.
|
||||
* @param bool $single Optional, default is false. If true, return only the first value of the specified meta_key.
|
||||
* This parameter has no effect if meta_key is not specified.
|
||||
*
|
||||
* @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
|
||||
*/
|
||||
function edd_get_order_meta( $order_id, $key = '', $single = false ) {
|
||||
return get_metadata( 'edd_order', $order_id, $key, $single );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update order meta field based on order ID.
|
||||
*
|
||||
* Use the $prev_value parameter to differentiate between meta fields with the
|
||||
* same key and order ID.
|
||||
*
|
||||
* If the meta field for the order does not exist, it will be added.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param string $meta_key Meta data key.
|
||||
* @param mixed $meta_value Meta data value. Must be serializable if non-scalar.
|
||||
* @param mixed $prev_value Optional. Previous value to check before removing. Default empty.
|
||||
*
|
||||
* @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
|
||||
*/
|
||||
function edd_update_order_meta( $order_id, $meta_key, $meta_value, $prev_value = '' ) {
|
||||
return update_metadata( 'edd_order', $order_id, $meta_key, $meta_value, $prev_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete everything from order meta matching meta key.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $meta_key Key to search for when deleting.
|
||||
*
|
||||
* @return bool Whether the order meta key was deleted from the database.
|
||||
*/
|
||||
function edd_delete_order_meta_by_key( $meta_key ) {
|
||||
return delete_metadata( 'edd_order', null, $meta_key, '', true );
|
||||
}
|
||||
|
||||
/** Order Items ***************************************************************/
|
||||
|
||||
/**
|
||||
* Add meta data field to an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order ID.
|
||||
* @param string $meta_key Meta data name.
|
||||
* @param mixed $meta_value Meta data value. Must be serializable if non-scalar.
|
||||
* @param bool $unique Optional. Whether the same key should not be added. Default false.
|
||||
*
|
||||
* @return int|false Meta ID on success, false on failure.
|
||||
*/
|
||||
function edd_add_order_item_meta( $order_item_id, $meta_key, $meta_value, $unique = false ) {
|
||||
return add_metadata( 'edd_order_item', $order_item_id, $meta_key, $meta_value, $unique );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove meta data matching criteria from an order item.
|
||||
*
|
||||
* You can match based on the key, or key and value. Removing based on key and value, will keep from removing duplicate
|
||||
* meta data with the same key. It also allows removing all meta data matching key, if needed.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order ID.
|
||||
* @param string $meta_key Meta data name.
|
||||
* @param mixed $meta_value Optional. Meta data value. Must be serializable if non-scalar. Default empty.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function edd_delete_order_item_meta( $order_item_id, $meta_key, $meta_value = '' ) {
|
||||
return delete_metadata( 'edd_order_item', $order_item_id, $meta_key, $meta_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve order_item meta field for an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order ID.
|
||||
* @param string $key Optional. The meta key to retrieve. By default, returns data for all keys. Default empty.
|
||||
* @param bool $single Optional, default is false. If true, return only the first value of the specified meta_key.
|
||||
* This parameter has no effect if meta_key is not specified.
|
||||
*
|
||||
* @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
|
||||
*/
|
||||
function edd_get_order_item_meta( $order_item_id, $key = '', $single = false ) {
|
||||
return get_metadata( 'edd_order_item', $order_item_id, $key, $single );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update order_item meta field based on order_item ID.
|
||||
*
|
||||
* Use the $prev_value parameter to differentiate between meta fields with the
|
||||
* same key and order_item ID.
|
||||
*
|
||||
* If the meta field for the order_item does not exist, it will be added.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_item_id Order Item ID.
|
||||
* @param string $meta_key Meta data key.
|
||||
* @param mixed $meta_value Meta data value. Must be serializable if non-scalar.
|
||||
* @param mixed $prev_value Optional. Previous value to check before removing. Default empty.
|
||||
*
|
||||
* @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
|
||||
*/
|
||||
function edd_update_order_item_meta( $order_item_id, $meta_key, $meta_value, $prev_value = '' ) {
|
||||
return update_metadata( 'edd_order_item', $order_item_id, $meta_key, $meta_value, $prev_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete everything from order_item meta matching meta key.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $meta_key Key to search for when deleting.
|
||||
*
|
||||
* @return bool Whether the order_item meta key was deleted from the database.
|
||||
*/
|
||||
function edd_delete_order_item_meta_by_key( $meta_key ) {
|
||||
return delete_metadata( 'edd_order_item', null, $meta_key, '', true );
|
||||
}
|
||||
|
||||
/** Order Adjustments *********************************************************/
|
||||
|
||||
/**
|
||||
* Add meta data field to an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $adjustment_id Order ID.
|
||||
* @param string $meta_key Meta data name.
|
||||
* @param mixed $meta_value Meta data value. Must be serializable if non-scalar.
|
||||
* @param bool $unique Optional. Whether the same key should not be added. Default false.
|
||||
*
|
||||
* @return int|false Meta ID on success, false on failure.
|
||||
*/
|
||||
function edd_add_order_adjustment_meta( $adjustment_id, $meta_key, $meta_value, $unique = false ) {
|
||||
return add_metadata( 'edd_order_adjustment', $adjustment_id, $meta_key, $meta_value, $unique );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove meta data matching criteria from an order item.
|
||||
*
|
||||
* You can match based on the key, or key and value. Removing based on key and value, will keep from removing duplicate
|
||||
* meta data with the same key. It also allows removing all meta data matching key, if needed.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $adjustment_id Order ID.
|
||||
* @param string $meta_key Meta data name.
|
||||
* @param mixed $meta_value Optional. Meta data value. Must be serializable if non-scalar. Default empty.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
*/
|
||||
function edd_delete_order_adjustment_meta( $adjustment_id, $meta_key, $meta_value = '' ) {
|
||||
return delete_metadata( 'edd_order_adjustment', $adjustment_id, $meta_key, $meta_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve order_item meta field for an order item.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $adjustment_id Order ID.
|
||||
* @param string $key Optional. The meta key to retrieve. By default, returns data for all keys. Default empty.
|
||||
* @param bool $single Optional, default is false. If true, return only the first value of the specified meta_key.
|
||||
* This parameter has no effect if meta_key is not specified.
|
||||
*
|
||||
* @return mixed Will be an array if $single is false. Will be value of meta data field if $single is true.
|
||||
*/
|
||||
function edd_get_order_adjustment_meta( $adjustment_id, $key = '', $single = false ) {
|
||||
return get_metadata( 'edd_order_adjustment', $adjustment_id, $key, $single );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update order_item meta field based on order_item ID.
|
||||
*
|
||||
* Use the $prev_value parameter to differentiate between meta fields with the
|
||||
* same key and order_item ID.
|
||||
*
|
||||
* If the meta field for the order_item does not exist, it will be added.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $adjustment_id Order Item ID.
|
||||
* @param string $meta_key Meta data key.
|
||||
* @param mixed $meta_value Meta data value. Must be serializable if non-scalar.
|
||||
* @param mixed $prev_value Optional. Previous value to check before removing. Default empty.
|
||||
*
|
||||
* @return int|bool Meta ID if the key didn't exist, true on successful update, false on failure.
|
||||
*/
|
||||
function edd_update_order_adjustment_meta( $adjustment_id, $meta_key, $meta_value, $prev_value = '' ) {
|
||||
return update_metadata( 'edd_order_adjustment', $adjustment_id, $meta_key, $meta_value, $prev_value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete everything from order_item meta matching meta key.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $meta_key Key to search for when deleting.
|
||||
*
|
||||
* @return bool Whether the order_item meta key was deleted from the database.
|
||||
*/
|
||||
function edd_delete_order_adjustment_meta_by_key( $meta_key ) {
|
||||
return delete_metadata( 'edd_order_adjustment', null, $meta_key, '', true );
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,469 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Refund Functions
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Orders
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
use EDD\Orders\Refund_Validator;
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Check order can be refunded.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @return bool True if refundable, false otherwise.
|
||||
*/
|
||||
function edd_is_order_refundable( $order_id = 0 ) {
|
||||
global $wpdb;
|
||||
|
||||
// Bail if no order ID was passed.
|
||||
if ( empty( $order_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = edd_get_order( $order_id );
|
||||
|
||||
// Bail if order was not found.
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only orders with a supported status can be refunded.
|
||||
if ( ! in_array( $order->status, edd_get_refundable_order_statuses(), true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check order hasn't already been refunded.
|
||||
$query = "SELECT COUNT(id) FROM {$wpdb->edd_orders} WHERE parent = %d AND status = '%s'";
|
||||
$prepare = sprintf( $query, $order_id, esc_sql( 'refunded' ) );
|
||||
$refunded_order = $wpdb->get_var( $prepare ); // WPCS: unprepared SQL ok.
|
||||
|
||||
if ( 0 < absint( $refunded_order ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow overrides.
|
||||
if ( true === edd_is_order_refundable_by_override( $order->id ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Outside of Refund window.
|
||||
if ( true === edd_is_order_refund_window_passed( $order->id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we have reached here, every other check holds so the order is refundable.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check order is passed its refund window.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @return bool True if in window, false otherwise.
|
||||
*/
|
||||
function edd_is_order_refund_window_passed( $order_id = 0 ) {
|
||||
// Bail if no order ID was passed.
|
||||
if ( empty( $order_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = edd_get_order( $order_id );
|
||||
|
||||
// Bail if order was not found.
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Refund dates may not have been set retroactively so we need to calculate it manually.
|
||||
if ( empty( $order->date_refundable ) ) {
|
||||
$refund_window = absint( edd_get_option( 'refund_window', 30 ) );
|
||||
|
||||
// Refund window is infinite.
|
||||
if ( 0 === $refund_window ) {
|
||||
return true;
|
||||
} else {
|
||||
$date_refundable = \Carbon\Carbon::parse( $order->date_completed, 'UTC' )->setTimezone( edd_get_timezone_id() )->addDays( $refund_window );
|
||||
}
|
||||
|
||||
// Parse date using Carbon.
|
||||
} else {
|
||||
$date_refundable = \Carbon\Carbon::parse( $order->date_refundable, 'UTC' )->setTimezone( edd_get_timezone_id() );
|
||||
}
|
||||
|
||||
return true === $date_refundable->isPast();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check order can be refunded via a capability override.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @return bool True if refundable via capability override, false otherwise.
|
||||
*/
|
||||
function edd_is_order_refundable_by_override( $order_id = 0 ) {
|
||||
// Bail if no order ID was passed.
|
||||
if ( empty( $order_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$order = edd_get_order( $order_id );
|
||||
|
||||
// Bail if order was not found.
|
||||
if ( ! $order ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Allow certain capabilities to always provide refunds.
|
||||
$caps = array( 'edit_shop_payments' );
|
||||
|
||||
/**
|
||||
* Filters the user capabilities that are required for overriding
|
||||
* refundability requirements.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $caps List of capabilities that can override
|
||||
* refundability. Default `edit_shop_payments`.
|
||||
* @param int $order_id ID of current Order being refunded.
|
||||
*/
|
||||
$caps = apply_filters( 'edd_is_order_refundable_by_override_caps', $caps, $order_id );
|
||||
|
||||
$can_override = false;
|
||||
|
||||
foreach ( $caps as $cap ) {
|
||||
if ( true === current_user_can( $cap ) ) {
|
||||
$can_override = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the allowance of refunds on an Order.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param bool $can_override If the refundability can be overriden by
|
||||
* the current user.
|
||||
* @param int $order_id ID of current Order being refunded.
|
||||
*/
|
||||
$can_override = apply_filters( 'edd_is_order_refundable_by_override', $can_override, $order_id );
|
||||
|
||||
return $can_override;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refund entire order.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @param array|string $order_items {
|
||||
* Optional. Either `all` as a string to refund all order items, or an array of
|
||||
* order item IDs, amounts, and quantities to refund.
|
||||
*
|
||||
* @type int $order_item_id Required. ID of the order item.
|
||||
* @type int $quantity Required. Quantity being refunded.
|
||||
* @type float $subtotal Required. Amount to refund, excluding tax.
|
||||
* @type float $tax Optional. Amount of tax to refund.
|
||||
* }
|
||||
*
|
||||
* @param array|string $adjustments {
|
||||
* Optional. Either `all` as a string to refund all order adjustments, or an array of
|
||||
* order adjustment IDs and amounts to refund.
|
||||
*
|
||||
* @type int $adjustment_id Required. ID of the order adjustment being refunded.
|
||||
* @type float $subtotal Required. Amount to refund, excluding tax.
|
||||
* @type float $tax Required. Amount of tax to refund.
|
||||
* }
|
||||
*
|
||||
* @return int|WP_Error New order ID if successful, WP_Error on failure.
|
||||
*/
|
||||
function edd_refund_order( $order_id, $order_items = 'all', $adjustments = 'all' ) {
|
||||
global $wpdb;
|
||||
|
||||
// Ensure the order ID is an integer.
|
||||
$order_id = absint( $order_id );
|
||||
|
||||
// Fetch order.
|
||||
$order = edd_get_order( $order_id );
|
||||
|
||||
if ( ! $order ) {
|
||||
return new WP_Error( 'invalid_order', __( 'Invalid order.', 'easy-digital-downloads' ) );
|
||||
}
|
||||
|
||||
if ( false === edd_is_order_refundable( $order_id ) ) {
|
||||
return new WP_Error( 'not_refundable', __( 'Order not refundable.', 'easy-digital-downloads' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter whether refunds should be allowed.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
*/
|
||||
$should_refund = apply_filters( 'edd_should_process_order_refund', true, $order_id );
|
||||
|
||||
// Bail if refund is blocked.
|
||||
if ( true !== $should_refund ) {
|
||||
return new WP_Error( 'refund_not_allowed', __( 'Refund not allowed on this order.', 'easy-digital-downloads' ) );
|
||||
}
|
||||
|
||||
/** Generate new order number *********************************************/
|
||||
|
||||
$last_order = $wpdb->get_row( $wpdb->prepare( "SELECT id, order_number
|
||||
FROM {$wpdb->edd_orders}
|
||||
WHERE parent = %d
|
||||
ORDER BY id DESC
|
||||
LIMIT 1", $order_id ) );
|
||||
|
||||
/**
|
||||
* Filter the suffix applied to order numbers for refunds.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string Suffix.
|
||||
*/
|
||||
$refund_suffix = apply_filters( 'edd_order_refund_suffix', '-R-' );
|
||||
|
||||
if ( $last_order ) {
|
||||
|
||||
// Check for order number first.
|
||||
if ( $last_order->order_number && ! empty( $last_order->order_number ) ) {
|
||||
|
||||
// Order has been previously revised.
|
||||
if ( false !== strpos( $last_order->order_number, $refund_suffix ) ) {
|
||||
$number = $last_order->order_number;
|
||||
++$number;
|
||||
|
||||
// First revision to order.
|
||||
} else {
|
||||
$number = $last_order->id . $refund_suffix . '1';
|
||||
}
|
||||
|
||||
// Append to ID.
|
||||
} else {
|
||||
$number = $last_order->id . $refund_suffix . '1';
|
||||
}
|
||||
} else {
|
||||
$number = $order->id . $refund_suffix . '1';
|
||||
}
|
||||
|
||||
/** Validate refund amounts *************************************************/
|
||||
|
||||
try {
|
||||
$validator = new Refund_Validator( $order, $order_items, $adjustments );
|
||||
$validator->validate_and_calculate_totals();
|
||||
} catch( \EDD\Utils\Exceptions\Invalid_Argument $e ) {
|
||||
return new WP_Error( 'refund_validation_error', __( 'Invalid argument. Please check your amounts and try again.', 'easy-digital-downloads' ) );
|
||||
} catch ( \Exception $e ) {
|
||||
return new WP_Error( 'refund_validation_error', $e->getMessage() );
|
||||
}
|
||||
|
||||
/** Insert order **********************************************************/
|
||||
|
||||
$order_data = array(
|
||||
'parent' => $order_id,
|
||||
'order_number' => $number,
|
||||
'status' => 'complete',
|
||||
'type' => 'refund',
|
||||
'user_id' => $order->user_id,
|
||||
'customer_id' => $order->customer_id,
|
||||
'email' => $order->email,
|
||||
'ip' => $order->ip,
|
||||
'gateway' => $order->gateway,
|
||||
'mode' => $order->mode,
|
||||
'currency' => $order->currency,
|
||||
'payment_key' => strtolower( md5( uniqid() ) ),
|
||||
'tax_rate_id' => $order->tax_rate_id,
|
||||
'subtotal' => edd_negate_amount( $validator->subtotal ),
|
||||
'tax' => edd_negate_amount( $validator->tax ),
|
||||
'total' => edd_negate_amount( $validator->total ),
|
||||
);
|
||||
|
||||
// Full refund is inserted first to allow for conditional checks to run later
|
||||
// and update the order, but we need an INSERT to be executed to generate a
|
||||
// new order ID.
|
||||
$refund_id = edd_add_order( $order_data );
|
||||
|
||||
// If we have tax, but no tax rate, manually save the percentage.
|
||||
$tax_rate_meta = edd_get_order_meta( $order_id, 'tax_rate', true );
|
||||
if ( $tax_rate_meta ) {
|
||||
edd_update_order_meta( $refund_id, 'tax_rate', $tax_rate_meta );
|
||||
}
|
||||
|
||||
/** Insert order items ****************************************************/
|
||||
|
||||
// Maintain a mapping of old order item IDs => new for easier lookup when we do fees.
|
||||
$order_item_id_map = array();
|
||||
foreach ( $validator->get_refunded_order_items() as $order_item ) {
|
||||
$order_item['order_id'] = $refund_id;
|
||||
|
||||
$new_item_id = edd_add_order_item( $order_item );
|
||||
|
||||
if ( ! empty( $order_item['parent'] ) ) {
|
||||
$order_item_id_map[ $order_item['parent'] ] = $new_item_id;
|
||||
}
|
||||
|
||||
// Update the status on the original order item.
|
||||
if ( ! empty( $order_item['parent'] ) && ! empty( $order_item['original_item_status'] ) ) {
|
||||
edd_update_order_item( $order_item['parent'], array( 'status' => $order_item['original_item_status'] ) );
|
||||
}
|
||||
}
|
||||
|
||||
/** Insert order adjustments **********************************************/
|
||||
|
||||
foreach ( $validator->get_refunded_adjustments() as $adjustment ) {
|
||||
if ( ! empty( $adjustment['object_type'] ) && 'order' === $adjustment['object_type'] ) {
|
||||
$adjustment['object_id'] = $refund_id;
|
||||
} elseif ( ! empty( $adjustment['object_type'] ) && 'order_item' === $adjustment['object_type'] ) {
|
||||
/*
|
||||
* At this point, `object_id` references an order item which is attached to the
|
||||
* original order record. We need to try to convert this to a _refund_ order item
|
||||
* instead.
|
||||
*
|
||||
* If we can't (such as, if the order item was never refunded), we'll have to
|
||||
* convert the adjustment to be an `order` object type instead. That's because we
|
||||
* _have_ to reference a refund object of some kind.
|
||||
*/
|
||||
$order_item_match_found = false;
|
||||
if ( ! empty( $adjustment['object_id'] ) && ! empty( $order_item_id_map[ $adjustment['object_id'] ] ) ) {
|
||||
// We don't need to convert to an `order` adjustment if we are also refunding the original order item.
|
||||
$adjustment['object_id'] = $order_item_id_map[ $adjustment['object_id'] ];
|
||||
$order_item_match_found = true;
|
||||
}
|
||||
|
||||
if ( ! $order_item_match_found ) {
|
||||
$adjustment['object_type'] = 'order';
|
||||
$adjustment['object_id'] = $refund_id;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note: Order item adjustments retain their `object_id` link to the *original* order item -- not the
|
||||
* refunded order item. This isn't ideal, but it's because you could refund an order item fee without
|
||||
* refunding the associated item, in which case there would be no refunded order item to reference.
|
||||
* So we link back to the *original* order item in all cases to be consistent.
|
||||
*/
|
||||
|
||||
edd_add_order_adjustment( $adjustment );
|
||||
}
|
||||
|
||||
// Update order status to `refunded` once refund is complete and if all items are marked as refunded.
|
||||
$all_refunded = true;
|
||||
$remaining_items = edd_count_order_items(
|
||||
array(
|
||||
'order_id' => $order_id,
|
||||
'status__not_in' => array( 'refunded' ),
|
||||
)
|
||||
);
|
||||
if ( edd_get_order_total( $order_id ) > 0 || $remaining_items > 0 ) {
|
||||
$all_refunded = false;
|
||||
}
|
||||
|
||||
$order_status = true === $all_refunded
|
||||
? 'refunded'
|
||||
: 'partially_refunded';
|
||||
|
||||
edd_update_order( $order_id, array( 'status' => $order_status ) );
|
||||
|
||||
edd_update_order( $refund_id, array( 'date_completed' => date( 'Y-m-d H:i:s' ) ) );
|
||||
/**
|
||||
* Fires when an order has been refunded.
|
||||
* This hook will trigger the legacy `edd_pre_refund_payment` and `edd_post_refund_payment`
|
||||
* hooks for the time being, but any code using either of those should be updated.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID of the original order.
|
||||
* @param int $refund_id ID of the new refund object.
|
||||
* @param bool $all_refunded Whether or not the entire order was refunded.
|
||||
*/
|
||||
do_action( 'edd_refund_order', $order_id, $refund_id, $all_refunded );
|
||||
|
||||
return $refund_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Queries for order refunds.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Parent Order.
|
||||
* @return \EDD\Orders\Order[] Array of `Order` objects.
|
||||
*/
|
||||
function edd_get_order_refunds( $order_id = 0 ) {
|
||||
$order_refunds = new \EDD\Database\Queries\Order();
|
||||
|
||||
return $order_refunds->query( array(
|
||||
'type' => 'refund',
|
||||
'parent' => $order_id,
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate order total. This method is used to calculate the total of an order
|
||||
* by also taking into account any refunds/partial refunds.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_id Order ID.
|
||||
* @return float $total Order total.
|
||||
*/
|
||||
function edd_get_order_total( $order_id ) {
|
||||
global $wpdb;
|
||||
|
||||
$query = "SELECT SUM(total) FROM {$wpdb->edd_orders} WHERE id = %d OR parent = %d";
|
||||
$prepare = $wpdb->prepare( $query, $order_id, $order_id );
|
||||
$total = $wpdb->get_var( $prepare ); // WPCS: unprepared SQL ok.
|
||||
$retval = ( null === $total )
|
||||
? 0.00
|
||||
: floatval( $total );
|
||||
|
||||
return $retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate order item total. This method is used to calculate the total of an
|
||||
* order item by also taking into account any refunds/partial refunds.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $order_ids Order IDs.
|
||||
* @param int $product_id Product ID.
|
||||
*
|
||||
* @return float $total Order total.
|
||||
*/
|
||||
function edd_get_order_item_total( $order_ids = array(), $product_id = 0 ) {
|
||||
global $wpdb;
|
||||
|
||||
// Bail if no order IDs were passed.
|
||||
if ( empty( $order_ids ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$query = "SELECT SUM(total) FROM {$wpdb->edd_order_items} WHERE order_id IN (%s) AND product_id = %d";
|
||||
$ids = join( ',', array_map( 'absint', $order_ids ) );
|
||||
$prepare = sprintf( $query, $ids, $product_id );
|
||||
$total = $wpdb->get_var( $prepare ); // WPCS: unprepared SQL ok.
|
||||
$retval = ( null === $total )
|
||||
? 0.00
|
||||
: floatval( $total );
|
||||
|
||||
return $retval;
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Status Functions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Orders
|
||||
* @copyright Copyright (c) 2022, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the order status array keys that can be used to run reporting related to gross reporting.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return array An array of order status array keys that can be related to gross reporting.
|
||||
*/
|
||||
function edd_get_gross_order_statuses() {
|
||||
$statuses = array(
|
||||
'complete',
|
||||
'refunded',
|
||||
'partially_refunded',
|
||||
'revoked',
|
||||
);
|
||||
|
||||
/**
|
||||
* Statuses that affect gross order statistics.
|
||||
*
|
||||
* This filter allows extensions and developers to alter the statuses that can affect the reporting of gross
|
||||
* sales statistics.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $statuses {
|
||||
* An array of order status array keys.
|
||||
*
|
||||
*/
|
||||
return apply_filters( 'edd_gross_order_statuses', $statuses );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order status array keys that can be used to run reporting related to net reporting.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return array An array of order status array keys that can be related to net reporting.
|
||||
*/
|
||||
function edd_get_net_order_statuses() {
|
||||
$statuses = array(
|
||||
'complete',
|
||||
'partially_refunded',
|
||||
'revoked',
|
||||
);
|
||||
|
||||
/**
|
||||
* Statuses that affect net order statistics.
|
||||
*
|
||||
* This filter allows extensions and developers to alter the statuses that can affect the reporting of net
|
||||
* sales statistics.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $statuses {
|
||||
* An array of order status array keys.
|
||||
*
|
||||
*/
|
||||
return apply_filters( 'edd_net_order_statuses', $statuses );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order status array keys which are considered recoverable.
|
||||
*
|
||||
* @since 3.0
|
||||
* @param bool $include_labels Whether to return a multidimensional array including status labels.
|
||||
* @return array An array of order status keys which are considered recoverable.
|
||||
*/
|
||||
function edd_recoverable_order_statuses( $include_labels = false ) {
|
||||
$statuses = array( 'pending', 'abandoned', 'failed' );
|
||||
|
||||
/**
|
||||
* Order statuses which are considered recoverable.
|
||||
*
|
||||
* @param $statuses {
|
||||
* An array of order status array keys.
|
||||
* }
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_recoverable_payment_statuses', $statuses );
|
||||
|
||||
return $include_labels ? array_intersect_key( edd_get_payment_statuses(), array_flip( $statuses ) ) : $statuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order status keys which are considered complete.
|
||||
*
|
||||
* @since 3.0
|
||||
* @param bool $include_labels Whether to return a multidimensional array including status labels.
|
||||
* @return array An array of order status keys which are considered completed.
|
||||
*/
|
||||
function edd_get_complete_order_statuses( $include_labels = false ) {
|
||||
$statuses = array( 'publish', 'complete', 'completed', 'partially_refunded', 'revoked', 'refunded' );
|
||||
|
||||
/**
|
||||
* Order statuses which are considered completed or at their final state.
|
||||
*
|
||||
* @param $statuses {
|
||||
* An array of order status array keys.
|
||||
* }
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_complete_order_statuses', $statuses );
|
||||
|
||||
return $include_labels ? array_intersect_key( edd_get_payment_statuses(), array_flip( $statuses ) ) : $statuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the order status array keys which are considered incomplete.
|
||||
*
|
||||
* @since 3.0
|
||||
* @param bool $include_labels Whether to return a multidimensional array including status labels.
|
||||
* @return array An array of order status keys which are considered incomplete.
|
||||
*/
|
||||
function edd_get_incomplete_order_statuses( $include_labels = false ) {
|
||||
$statuses = array( 'pending', 'abandoned', 'processing', 'failed', 'cancelled' );
|
||||
|
||||
/**
|
||||
* Filters the payment key
|
||||
* Order statuses which are considered incomplete.
|
||||
*
|
||||
* @param $statuses {
|
||||
* An array of order status array keys.
|
||||
* }
|
||||
*/
|
||||
$statuses = apply_filters( 'edd_incomplete_order_statuses', $statuses );
|
||||
|
||||
return $include_labels ? array_intersect_key( edd_get_payment_statuses(), array_flip( $statuses ) ) : $statuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of order statuses that support refunds.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return array
|
||||
*/
|
||||
function edd_get_refundable_order_statuses() {
|
||||
$refundable_order_statuses = array( 'complete', 'publish', 'partially_refunded' );
|
||||
|
||||
/**
|
||||
* Filters the order statuses that are allowed to be refunded.
|
||||
*
|
||||
* @param array $refundable_order_statuses
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
return (array) apply_filters( 'edd_refundable_order_statuses', $refundable_order_statuses );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of order item statuses that allow assets to be delivvered.
|
||||
*
|
||||
* @since 3.0
|
||||
* @return array
|
||||
*/
|
||||
function edd_get_deliverable_order_item_statuses() {
|
||||
$deliverable_order_item_statuses = array( 'complete', 'partially_refunded' );
|
||||
|
||||
/**
|
||||
* Filters the order item statuses that aallow assets to be delivered.
|
||||
*
|
||||
* @param array $refundable_order_statuses
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
return (array) apply_filters( 'edd_deliverable_order_item_statuses', $deliverable_order_item_statuses );
|
||||
}
|
227
wp-content/plugins/easy-digital-downloads/includes/orders/functions/transactions.php
Normal file
227
wp-content/plugins/easy-digital-downloads/includes/orders/functions/transactions.php
Normal file
@ -0,0 +1,227 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Transaction Functions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Orders\Transactions
|
||||
* @copyright Copyright (c) 2018, Easy Digital Downloads, LLC
|
||||
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Add an order transaction.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $data {
|
||||
* Array of order transaction data. Default empty.
|
||||
*
|
||||
* The `date_created` and `date_modified` parameters do not need to be passed.
|
||||
* They will be automatically populated if empty.
|
||||
*
|
||||
* @type int $object_id Object ID that the transaction refers to. This
|
||||
* would be an ID that corresponds to the object
|
||||
* type specified. E.g. an object ID of 25 with object
|
||||
* type of `order` refers to order 25 in the
|
||||
* `edd_orders` table. Default 0.
|
||||
* @type string $object_type Object type that the transaction refers to.
|
||||
* Default empty.
|
||||
* @type string $transaction_id Transaction ID from the payment gateway.
|
||||
* Default empty.
|
||||
* @type string $gateway Payment gateway used for the order. Default
|
||||
* empty.
|
||||
* @type string $status Status of the transaction. Default `pending`.
|
||||
* @type float $total Total amount processed in the transaction.
|
||||
* Default 0.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the transaction was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the transaction was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
* @return int|false ID of newly created order transaction, false on error.
|
||||
*/
|
||||
function edd_add_order_transaction( $data ) {
|
||||
|
||||
// An object ID and object type must be supplied for every transaction inserted.
|
||||
if ( empty( $data['object_id'] ) || empty( $data['object_type'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Instantiate a query object.
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction();
|
||||
|
||||
return $order_transactions->add_item( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an order transaction.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_transaction_id Order transaction ID.
|
||||
* @return int|false `1` if the transaction was deleted successfully, false on error.
|
||||
*/
|
||||
function edd_delete_order_transaction( $order_transaction_id = 0 ) {
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction();
|
||||
|
||||
return $order_transactions->delete_item( $order_transaction_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update an order address.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_transaction_id Order transaction ID.
|
||||
* @param array $data {
|
||||
* Array of order transaction data. Default empty.
|
||||
*
|
||||
* @type int $object_id Object ID that the transaction refers to. This
|
||||
* would be an ID that corresponds to the object
|
||||
* type specified. E.g. an object ID of 25 with object
|
||||
* type of `order` refers to order 25 in the
|
||||
* `edd_orders` table. Default 0.
|
||||
* @type string $object_type Object type that the transaction refers to.
|
||||
* Default empty.
|
||||
* @type string $transaction_id Transaction ID from the payment gateway.
|
||||
* Default empty.
|
||||
* @type string $gateway Payment gateway used for the order. Default
|
||||
* empty.
|
||||
* @type string $status Status of the transaction. Default `pending`.
|
||||
* @type float $total Total amount processed in the transaction.
|
||||
* Default 0.
|
||||
* @type string $date_created Optional. Automatically calculated on add/edit.
|
||||
* The date & time the transaction was inserted.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* @type string $date_modified Optional. Automatically calculated on add/edit.
|
||||
* The date & time the transaction was last modified.
|
||||
* Format: YYYY-MM-DD HH:MM:SS. Default empty.
|
||||
* }
|
||||
*
|
||||
* @return int|false Number of rows updated if successful, false otherwise.
|
||||
*/
|
||||
function edd_update_order_transaction( $order_transaction_id = 0, $data = array() ) {
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction();
|
||||
|
||||
return $order_transactions->update_item( $order_transaction_id, $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order transaction by ID.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param int $order_transaction_id Order transaction ID.
|
||||
* @return EDD\Orders\Order_Transaction|false Order_Transaction object if successful,
|
||||
* false otherwise.
|
||||
*/
|
||||
function edd_get_order_transaction( $order_transaction_id = 0 ) {
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction();
|
||||
|
||||
// Return order transaction.
|
||||
return $order_transactions->get_item( $order_transaction_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an order transaction by a specific field value.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $field Database table field.
|
||||
* @param string $value Value of the row.
|
||||
*
|
||||
* @return EDD\Orders\Order_Transaction|false Order_Transaction object if successful,
|
||||
* false otherwise.
|
||||
*/
|
||||
function edd_get_order_transaction_by( $field = '', $value = '' ) {
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction();
|
||||
|
||||
// Return order transaction.
|
||||
return $order_transactions->get_item_by( $field, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Query for order transactions.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Transaction::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Transaction` for
|
||||
* accepted arguments.
|
||||
* @return \EDD\Orders\Order_Transaction[] Array of `Order_Transaction` objects.
|
||||
*/
|
||||
function edd_get_order_transactions( $args = array() ) {
|
||||
|
||||
// Parse args.
|
||||
$r = wp_parse_args( $args, array(
|
||||
'number' => 30,
|
||||
) );
|
||||
|
||||
// Instantiate a query object.
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction();
|
||||
|
||||
// Return order transactions.
|
||||
return $order_transactions->query( $r );
|
||||
}
|
||||
|
||||
/**
|
||||
* Count order transactions.
|
||||
*
|
||||
* @see \EDD\Database\Queries\Order_Transaction::__construct()
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args Arguments. See `EDD\Database\Queries\Order_Transaction` for
|
||||
* accepted arguments.
|
||||
* @return int Number of order transactions returned based on query arguments
|
||||
* passed.
|
||||
*/
|
||||
function edd_count_order_transactions( $args = array() ) {
|
||||
|
||||
// Parse args.
|
||||
$r = wp_parse_args( $args, array(
|
||||
'count' => true,
|
||||
) );
|
||||
|
||||
// Query for count(s).
|
||||
$order_transactions = new EDD\Database\Queries\Order_Transaction( $r );
|
||||
|
||||
// Return count(s).
|
||||
return absint( $order_transactions->found_items );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve order ID based on the transaction ID.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param string $transaction_id Transaction ID. Default empty.
|
||||
* @return int $order_id Order ID. Default 0.
|
||||
*/
|
||||
function edd_get_order_id_from_transaction_id( $transaction_id = '' ) {
|
||||
|
||||
// Default return value.
|
||||
$retval = 0;
|
||||
|
||||
// Continue if transaction ID was passed.
|
||||
if ( ! empty( $transaction_id ) ) {
|
||||
|
||||
// Look for a transaction by gateway transaction ID.
|
||||
$transaction = edd_get_order_transaction_by( 'transaction_id', $transaction_id );
|
||||
|
||||
// Return object ID if found.
|
||||
if ( ! empty( $transaction->object_id ) ) {
|
||||
$retval = $transaction->object_id;
|
||||
}
|
||||
}
|
||||
|
||||
// Return.
|
||||
return absint( $retval );
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Transition Functions.
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage Orders
|
||||
* @copyright Copyright (c) 2022, Easy Digital Downloads
|
||||
* @license https://opensource.org/licenses/gpl-2.0.php GNU Public License
|
||||
* @since 3.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Record order status change
|
||||
*
|
||||
* @since 3.0
|
||||
* @param string $old_status the status of the order prior to this change.
|
||||
* @param string $new_status The new order status.
|
||||
* @param int $order_id the ID number of the order.
|
||||
* @return void
|
||||
*/
|
||||
function edd_record_order_status_change( $old_status, $new_status, $order_id ) {
|
||||
|
||||
// Get the list of statuses so that status in the payment note can be translated.
|
||||
$stati = edd_get_payment_statuses();
|
||||
$old_status = isset( $stati[ $old_status ] ) ? $stati[ $old_status ] : $old_status;
|
||||
$new_status = isset( $stati[ $new_status ] ) ? $stati[ $new_status ] : $new_status;
|
||||
|
||||
$status_change = sprintf(
|
||||
/* translators: %1$s Old order status. %2$s New order status. */
|
||||
__( 'Status changed from %1$s to %2$s', 'easy-digital-downloads' ),
|
||||
$old_status,
|
||||
$new_status
|
||||
);
|
||||
|
||||
edd_insert_payment_note( $order_id, $status_change );
|
||||
}
|
||||
add_action( 'edd_transition_order_status', 'edd_record_order_status_change', 100, 3 );
|
||||
|
||||
/**
|
||||
* Triggers `edd_update_payment_status` hook when an order status changes
|
||||
* for backwards compatibility.
|
||||
*
|
||||
* @since 3.0
|
||||
* @param string $old_status the status of the order prior to this change.
|
||||
* @param string $new_status The new order status.
|
||||
* @param int $order_id the ID number of the order.
|
||||
* @return void
|
||||
*/
|
||||
add_action( 'edd_transition_order_status', function( $old_status, $new_status, $order_id ) {
|
||||
// Trigger the payment status action hook for backwards compatibility.
|
||||
do_action( 'edd_update_payment_status', $order_id, $new_status, $old_status );
|
||||
if ( 'complete' === $old_status ) {
|
||||
// Trigger the action again to account for add-ons listening for status changes from "publish".
|
||||
do_action( 'edd_update_payment_status', $order_id, $new_status, 'publish' );
|
||||
}
|
||||
}, 10, 3 );
|
@ -0,0 +1,106 @@
|
||||
<?php
|
||||
/**
|
||||
* Order Type Functions
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage 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;
|
||||
|
||||
/**
|
||||
* Retrieve the registered order types.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function edd_get_order_types() {
|
||||
|
||||
// Get the
|
||||
$component = edd_get_component( 'order' );
|
||||
|
||||
// Setup an empty types array
|
||||
if ( ! isset( $component->types ) ) {
|
||||
$component->types = array();
|
||||
}
|
||||
|
||||
// Return types
|
||||
return (array) $component->types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an Order Type.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
function edd_register_order_type( $type = '', $args = array() ) {
|
||||
|
||||
// Sanitize the type
|
||||
$type = sanitize_key( $type );
|
||||
|
||||
// Parse args
|
||||
$r = wp_parse_args( $args, array(
|
||||
'show_ui' => true,
|
||||
'labels' => array(
|
||||
'singular' => '',
|
||||
'plural' => ''
|
||||
)
|
||||
) );
|
||||
|
||||
// Get the
|
||||
$component = edd_get_component( 'order' );
|
||||
|
||||
// Setup an empty types array
|
||||
if ( ! isset( $component->types ) ) {
|
||||
$component->types = array();
|
||||
}
|
||||
|
||||
// Add the order type to the `types` array
|
||||
$component->types[ $type ] = $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the default Order Types.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
function edd_register_default_order_types( $name = '' ) {
|
||||
|
||||
// Bail if not the `order` name
|
||||
if ( 'order' !== $name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sales
|
||||
edd_register_order_type( 'sale', array(
|
||||
'labels' => array(
|
||||
'singular' => __( 'Order', 'easy-digital-downloads' ),
|
||||
'plural' => __( 'Orders', 'easy-digital-downloads' )
|
||||
)
|
||||
) );
|
||||
|
||||
// Refunds
|
||||
edd_register_order_type( 'refund', array(
|
||||
'labels' => array(
|
||||
'singular' => __( 'Refund', 'easy-digital-downloads' ),
|
||||
'plural' => __( 'Refunds', 'easy-digital-downloads' )
|
||||
)
|
||||
) );
|
||||
|
||||
// Invoices
|
||||
edd_register_order_type( 'invoice', array(
|
||||
'show_ui' => false,
|
||||
'labels' => array(
|
||||
'singular' => __( 'Invoice', 'easy-digital-downloads' ),
|
||||
'plural' => __( 'Invoices', 'easy-digital-downloads' )
|
||||
)
|
||||
) );
|
||||
}
|
||||
add_action( 'edd_registered_component', 'edd_register_default_order_types' );
|
@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Order User Interface Functions
|
||||
*
|
||||
* @package EDD
|
||||
* @subpackage 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;
|
||||
|
||||
/**
|
||||
* Add "Order" to the "+ New" admin menu bar.
|
||||
*
|
||||
* @since 3.0
|
||||
*
|
||||
* @param WP_Admin_Bar $wp_admin_bar Admin bar object.
|
||||
*/
|
||||
function edd_add_new_order_to_wp_admin_bar( $wp_admin_bar ) {
|
||||
// Bail if no admin bar
|
||||
if ( empty( $wp_admin_bar ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Bail if incorrect user.
|
||||
if ( ! current_user_can( 'manage_shop_settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the menu item
|
||||
$wp_admin_bar->add_menu( array(
|
||||
'id' => 'new-order',
|
||||
'title' => __( 'Order', 'easy-digital-downloads' ),
|
||||
'parent' => 'new-content',
|
||||
'href' => edd_get_admin_url( array(
|
||||
'page' => 'edd-payment-history',
|
||||
'view' => 'add-order',
|
||||
) ),
|
||||
) );
|
||||
}
|
||||
add_action( 'admin_bar_menu', 'edd_add_new_order_to_wp_admin_bar', 99 );
|
Reference in New Issue
Block a user