--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php
@@ -1,6 +1,7 @@
<?php
use EventEspressocoreservicesloadersLoaderFactory;
+use EventEspressocoreservicesrequestRequest;
use EventEspressocoreservicesrequestRequestInterface;
use EventEspressoPaymentMethodsPayPalCommercetoolsloggingPayPalLogger;
@@ -14,6 +15,16 @@
class EEG_PayPalCheckout extends EE_Onsite_Gateway
{
/**
+ * @var $payment EE_Payment|null
+ */
+ protected ?EE_Payment $payment = null;
+
+ /**
+ * @var $payment EE_Transaction|null
+ */
+ protected ?EE_Transaction $transaction = null;
+
+ /**
* Currencies supported by this gateway.
*
* @var array
@@ -58,59 +69,61 @@
public function do_direct_payment($payment, $billing_info = null)
{
$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
- $post_parameters = $request->postParams();
+ $post_parameters = $request instanceof Request ? $request->postParams() : $_POST;
// Check the payment.
- $payment = $this->validatePayment($payment, $request);
- if ($payment->details() === 'error' && $payment->status() === EEM_Payment::status_id_failed) {
- return $payment;
+ $this->payment = $this->validatePayment($payment, $post_parameters);
+ if ($this->payment->details() === 'error' && $this->payment->status() === EEM_Payment::status_id_failed) {
+ return $this->payment;
}
- $transaction = $payment->transaction();
- $payment_method = $transaction->payment_method();
- // Get the order details.
- $order_id = $request->getRequestParam('pp_order_id');
- if (! $order_id) {
+ $this->transaction = $this->validateTransaction($this->payment, $post_parameters);
+ if (! $this->transaction instanceof EE_Transaction) {
+ return $this->payment;
+ }
+ $payment_method = $this->transaction->payment_method();
+ if (! $payment_method instanceof EE_Payment_Method) {
+ return $this->payment;
+ }
+ if (empty($post_parameters['pp_order_id'])) {
return EEG_PayPalCheckout::updatePaymentStatus(
- $payment,
+ $this->payment,
EEM_Payment::status_id_declined,
$post_parameters,
esc_html__('Can't charge the Order. The Order ID is missing.', 'event_espresso')
);
}
+ // Get the order details.
+ $order_id = sanitize_text_field($post_parameters['pp_order_id']);
// Capture the order.
- $capture_status = EED_PayPalCommerce::captureOrder($transaction, $payment_method, $order_id);
+ $capture_status = EED_PayPalCommerce::captureOrder($this->transaction, $payment_method, $order_id);
// Check the order status.
- $order_status = $this->isOrderCompleted($order_id, $transaction, $payment_method);
+ $order_details = EED_PayPalCommerce::getOrderDetails($order_id, $this->transaction, $payment_method);
+ $order_status = $this->isOrderCompleted($order_details);
if (! $order_status['completed']) {
return EEG_PayPalCheckout::updatePaymentStatus(
- $payment,
+ $this->payment,
EEM_Payment::status_id_declined,
- $order_status,
+ $order_details,
$order_status['message'] ?? ''
);
}
// Looks like all is good. Mark payment as a success.
- $this->saveBillingDetails($payment, $transaction, $order_status['details'], $billing_info);
- return EEG_PayPalCheckout::updatePaymentStatus($payment, EEM_Payment::status_id_approved, $capture_status);
+ $this->saveBillingDetails($order_details, $billing_info, $this->payment);
+ return EEG_PayPalCheckout::updatePaymentStatus(
+ $this->payment,
+ EEM_Payment::status_id_approved,
+ $capture_status
+ );
}
/**
* Validate the Order.
*
- * @param string $order_id
- * @param EE_Transaction $transaction
- * @param EE_Payment_Method $payment_method
+ * @param array|null $order_details
* @return array ['completed' => {boolean}, 'message' => {string}]
- * @throws EE_Error
- * @throws ReflectionException
*/
- public static function isOrderCompleted(
- string $order_id,
- EE_Transaction $transaction,
- EE_Payment_Method $payment_method
- ): array
+ public static function isOrderCompleted(?array $order_details): array
{
- $order_details = EED_PayPalCommerce::getOrderDetails($order_id, $transaction, $payment_method);
$conclusion = [
'completed' => false,
'details' => $order_details,
@@ -127,19 +140,16 @@
'There was an error with this payment. The status of the Order could not be determined.',
'event_espresso'
);
- } elseif ($order_details['status'] !== 'COMPLETED') {
- $conclusion['message'] = esc_html__(
- 'There was an error with this payment. Order was not approved.',
- 'event_espresso'
- );
- } elseif (empty($order_details['purchase_units'][0]['payments']['captures'][0]['status'])) {
+ } elseif (! empty($order_details['purchase_units'][0]['payments']['captures'][0]['status'])
+ && $order_details['purchase_units'][0]['payments']['captures'][0]['status'] !== 'COMPLETED'
+ ) {
$conclusion['message'] = esc_html__(
- 'There was an error with this payment. The status of the Payment could not be determined.',
+ 'This payment was declined or failed validation. Please check the payment and billing information you provided.',
'event_espresso'
);
- } elseif ($order_details['purchase_units'][0]['payments']['captures'][0]['status'] !== 'COMPLETED') {
+ } elseif ($order_details['status'] !== 'COMPLETED') {
$conclusion['message'] = esc_html__(
- 'This payment was declined or failed validation. Please check the billing information you provided.',
+ 'There was an error with this payment. Order was not approved.',
'event_espresso'
);
} else {
@@ -163,14 +173,14 @@
*/
public static function updatePaymentStatus(
EE_Payment $payment,
- string $status,
- $response_data,
- string $update_message = ''
+ string $status,
+ $response_data,
+ string $update_message = ''
): EE_Payment {
$paypal_pm = ! empty($payment->payment_method())
? EEM_Payment_Method::instance()->get_one_by_slug($payment->payment_method()->name())
: null;
- // Is this a successful payment ?
+ // Is this a successful payment?
if ($status === EEM_Payment::status_id_approved) {
$default_message = esc_html__('Successful payment.', 'event_espresso');
$amount = $response_data['purchase_units'][0]['payments']['captures'][0]['amount']['value'] ?? 0;
@@ -178,24 +188,25 @@
if (! empty($amount)) {
$payment->set_amount((float) $amount);
}
- $payment->set_txn_id_chq_nmbr(
- $response_data['purchase_units'][0]['payments']['captures'][0]['id'] ?? $response_data['id']
- );
+ $txn_id_chq_nmbr = $response_data['purchase_units'][0]['payments']['captures'][0]['id']
+ ?? (! empty($response_data['id']) ? $response_data['id'] : 0);
+ $payment->set_txn_id_chq_nmbr($txn_id_chq_nmbr);
} else {
$default_message = sprintf(
esc_html__(
- 'Your payment could not be processed successfully due to a technical issue.%1$sPlease try again or contact%2$s for assistance.',
+ 'Your payment could not be processed successfully due to an error.%1$sPlease try again or contact %2$s for assistance.',
'event_espresso'
),
'<br/>',
EE_Registry::instance()->CFG->organization->get_pretty('email')
);
}
- $log_message = $update_message ?: $default_message;
- PayPalLogger::errorLog($log_message, $response_data, $paypal_pm, false, $payment->transaction());
+ // Try getting a better error message from the response.
+ $response_message = EEG_PayPalCheckout::getResponseMessage($response_data, $update_message ?: $default_message);
+ PayPalLogger::errorLog($response_message, $response_data, $paypal_pm, false, $payment->transaction());
$payment->set_status($status);
- $payment->set_details($log_message);
- $payment->set_gateway_response($log_message);
+ $payment->set_details($response_message);
+ $payment->set_gateway_response($response_message);
$payment->save();
return $payment;
}
@@ -204,63 +215,147 @@
/**
* Validate the payment.
*
- * @param EE_Payment|null $payment
- * @param RequestInterface $request
+ * @param array|string $response_data
+ * @param string|null $message
+ * @return string
+ */
+ public static function getResponseMessage($response_data, ?string $message): string
+ {
+ $new_message = $message;
+ if (is_string($response_data)) {
+ // Try to decode.
+ $decoded_response = json_decode($response_data, true);
+ if ($decoded_response && is_array($decoded_response)) {
+ $response_data = $decoded_response;
+ }
+ }
+ if (is_array($response_data)) {
+ // Do we have a capture status ?
+ if (! empty($response_data['purchase_units']['0']['payments']['captures'][0]['status'])) {
+ $new_message .= sprintf(
+ /* translators: 1: <br/><br/>, 2: payment capture status */
+ esc_html__('%1$sPayment capture status: %2$s', 'event_espresso'),
+ '<br/><br/>',
+ $response_data['purchase_units']['0']['payments']['captures'][0]['status']
+ );
+ }
+ if (
+ ! empty($response_data['purchase_units']['0']['payments']['captures'][0]['processor_response'])
+ && is_array($response_data['purchase_units']['0']['payments']['captures'][0]['processor_response'])
+ ) {
+ $new_message .= sprintf(
+ /* translators: 1: <br/><br/> */
+ esc_html__('%1$sProcessor responded: ', 'event_espresso'),
+ '<br/><br/>'
+ );
+ $processor_response =
+ $response_data['purchase_units']['0']['payments']['captures'][0]['processor_response'];
+ $iteration = 1;
+ $foreach_count = count($processor_response);
+ foreach ($processor_response as $key => $value) {
+ $new_message .= " $key: $value";
+ $new_message .= $iteration < $foreach_count ? ', ' : '.';
+ $iteration++;
+ }
+ }
+ if (
+ ! empty($response_data['details'][0]['description'])
+ && ! empty($response_data['details'][0]['issue'])
+ ) {
+ $iteration = 1;
+ $new_message .= sprintf(
+ /* translators: 1: <br/><br/> */
+ esc_html__('%1$sError details: ', 'event_espresso'),
+ '<br/><br/>'
+ );
+ $foreach_count = count($response_data['details'][0]);
+ foreach ($response_data['details'][0] as $key => $value) {
+ $new_message .= "$key: $value";
+ $new_message .= $iteration < $foreach_count ? ', ' : '';
+ $iteration++;
+ }
+ }
+ }
+ return $new_message;
+ }
+
+
+ /**
+ * Validate the payment.
+ *
+ * @param EE_Payment|null $payment
+ * @param array $post_parameters
* @return EE_Payment
* @throws EE_Error
* @throws ReflectionException
*/
- public function validatePayment(?EE_Payment $payment, RequestInterface $request): EE_Payment
+ public function validatePayment(?EE_Payment $payment, array $post_parameters): EE_Payment
{
- $failed_status = $this->_pay_model->failed_status();
// Check the payment.
if (! $payment instanceof EE_Payment) {
$payment = EE_Payment::new_instance();
$error_message = esc_html__('Error. No associated payment was found.', 'event_espresso');
return EEG_PayPalCheckout::updatePaymentStatus(
$payment,
- $failed_status,
- $request->postParams(),
+ $this->_pay_model->failed_status(),
+ $post_parameters,
$error_message
);
}
+ return $payment;
+ }
+
+
+ /**
+ * Validate the transaction.
+ *
+ * @param EE_Payment|null $payment
+ * @param array $post_parameters
+ * @return EE_Transaction|null
+ * @throws EE_Error
+ * @throws ReflectionException
+ */
+ public function validateTransaction(?EE_Payment $payment, array $post_parameters): ?EE_Transaction
+ {
// Check the transaction.
$transaction = $payment->transaction();
if (! $transaction instanceof EE_Transaction) {
- $error_message = esc_html__(
- 'Could not process this payment because it has no associated transaction.',
- 'event_espresso'
- );
- return EEG_PayPalCheckout::updatePaymentStatus(
- $payment,
- $failed_status,
- $request->postParams(),
- $error_message
- );
+ return null;
}
- return $payment;
+ if (! empty($post_parameters['spco_transaction_id'])) {
+ $spco_transaction_id = (int) sanitize_text_field($post_parameters['spco_transaction_id']);
+ if ($transaction->ID() !== $spco_transaction_id) {
+ $error_message = esc_html__(
+ 'Sorry, but this registration transaction was abandoned or got outdated and cannot be processed anymore. This can happen if you have started another registration checkout in a different browser tab or window. Please finish the last checkout or start over.',
+ 'event_espresso'
+ );
+ $this->payment = EEG_PayPalCheckout::updatePaymentStatus(
+ $payment,
+ $this->_pay_model->failed_status(),
+ $post_parameters,
+ $error_message
+ );
+ return null;
+ }
+ }
+ return $transaction;
}
/**
- * Save some transaction details, like billing information.
+ * Save transaction details, like billing information.
*
- * @param EE_Payment $payment
- * @param EE_Transaction $transaction
- * @param array $order
- * @param array $billing
+ * @param array $order
+ * @param array $billing
+ * @param EE_Payment $payment
* @return void
* @throws EE_Error
* @throws ReflectionException
*/
- public static function saveBillingDetails(
- EE_Payment $payment,
- EE_Transaction $transaction,
- array $order,
- array $billing
- ): void {
- $primary_reg = $transaction->primary_registration();
- $att = $primary_reg instanceof EE_Registration ? $primary_reg->attendee() : null;
+ public function saveBillingDetails(array $order, array $billing, EE_Payment $payment): void
+ {
+ $primary_reg = $this->transaction->primary_registration();
+ $att = $primary_reg instanceof EE_Registration ? $primary_reg->attendee() : null;
if (! $att instanceof EE_Attendee) {
// I guess we are done here then. Just save what we have.
$payment->set_details($order);
@@ -284,7 +379,7 @@
// A card (ACDC) payment ?
if (! empty($order['payment_source']['card'])) {
$payer = $order['payment_source']['card'];
- // Or maybe a PayPal Express payment ?
+ // Or maybe a PayPal Express payment ?
} elseif (! empty($order['payment_source']['paypal'])) {
$payer = $order['payment_source']['paypal'];
}
@@ -292,7 +387,7 @@
if (! empty($payer['name'])) {
// Yup, payment_source card vs PayPal have different info about the payer. So need to differentiate.
if (is_string($payer['name'])) {
- $full_name = explode(' ', $payer['name']);
+ $full_name = explode(' ', $payer['name']);
$billing['first_name'] = $full_name[0] ?? $billing['first_name'];
$billing['last_name'] = $full_name[1] ?? $billing['last_name'];
}
@@ -313,8 +408,9 @@
}
}
// Update attendee billing info in the transaction details.
- $payment_method = $transaction->payment_method();
- $post_meta_name = $payment_method->type_obj() instanceof EE_PMT_Base
+ $payment_method = $this->transaction->payment_method();
+ $post_meta_name = $payment_method instanceof EE_Payment_Method
+ && $payment_method->type_obj() instanceof EE_PMT_Base
? 'billing_info_' . $payment_method->type_obj()->system_name()
: '';
update_post_meta($att->ID(), $post_meta_name, $billing);
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCheckout/forms/BillingForm.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCheckout/forms/BillingForm.php
@@ -39,9 +39,9 @@
{
protected EE_Payment_Method $paypal_pmt;
- protected ?EE_Transaction $transaction = null;
+ protected ?EE_Transaction $transaction = null;
- protected string $checkout_type;
+ protected string $checkout_type;
/**
* Filepath to template files
@@ -54,14 +54,14 @@
/**
* Class constructor.
*
- * @param EE_Payment_Method $payment_method
- * @param array $options
+ * @param EE_Payment_Method $payment_method
+ * @param array $options
* @throws EE_Error
* @throws ReflectionException
*/
public function __construct(EE_Payment_Method $payment_method, array $options)
{
- $this->paypal_pmt = $payment_method;
+ $this->paypal_pmt = $payment_method;
// Can't be too careful.
$this->transaction = $options['transaction'] ?? null;
$this->template_path = $options['template_path'] ?? '';
@@ -201,7 +201,7 @@
*/
public static function excludeBillingFormFields(
EE_Billing_Info_Form $billing_form,
- EE_Payment_Method $payment_method
+ EE_Payment_Method $payment_method
): EE_Billing_Info_Form {
$request = LoaderFactory::getShared(Request::class);
$request_params = $request->requestParams();
@@ -407,7 +407,7 @@
*/
public function addPayPalCheckout(): EE_Form_Section_Proper
{
- $template_args['pm_slug'] = $this->paypal_pmt->slug();
+ $template_args['pm_slug'] = $this->paypal_pmt->slug();
return new EE_Form_Section_Proper(
[
'layout_strategy' => new EE_Template_Layout(
@@ -459,9 +459,7 @@
// Setup default values
$client_id_key = Domain::META_KEY_CLIENT_ID;
$merchant_id = false;
- $funding_options = ['venmo', 'paylater'];
-
- // Override the above if thrid party integration
+ // Override the above if third party integration
if (EED_PayPalCommerce::isThirdParty($this->_pm_instance)) {
$client_id_key = Domain::META_KEY_PARTNER_CLIENT_ID;
$merchant_id = PayPalExtraMetaManager::getPmOption(
@@ -469,35 +467,29 @@
Domain::META_KEY_SELLER_MERCHANT_ID
);
}
-
// Setup query args
- $url_params = [
- 'client-id' => PayPalExtraMetaManager::getPmOption($this->_pm_instance, $client_id_key),
- 'currency' => CurrencyManager::currencyCode(),
- 'components' => implode(',', ['buttons','hosted-fields']),
- 'intent' => 'capture',
- 'merchant-id' => $merchant_id,
+ $url_params = [
+ 'client-id' => PayPalExtraMetaManager::getPmOption($this->_pm_instance, $client_id_key),
+ 'currency' => CurrencyManager::currencyCode(),
+ 'components' => implode(',', ['buttons', 'hosted-fields']),
+ 'intent' => 'capture',
+ 'merchant-id' => $merchant_id,
];
-
// Which funding methods are active?
- $enabled_funding = $this->_pm_instance->get_extra_meta(Domain::META_KEY_FUNDING_OPTIONS, true, $funding_options);
-
- // Any funding method not enabled should be disabled.
- $disabled_funding = array_diff(
- $funding_options,
- $enabled_funding
+ $enabled_funding = $this->_pm_instance->get_extra_meta(
+ Domain::META_KEY_FUNDING_OPTIONS,
+ true,
+ Domain::FUNDING_OPTIONS
);
-
- // Any funding options enabled?
- if (count($enabled_funding) > 0) {
- $url_params['enable-funding'] = implode(',', $enabled_funding);
+ if (! $enabled_funding || ! is_array($enabled_funding)) {
+ $enabled_funding = [];
}
-
+ // Any funding method not enabled should be disabled.
+ $disabled_funding = array_diff(Domain::FUNDING_OPTIONS, $enabled_funding);
// Any funding options disabled?
if (count($disabled_funding) > 0) {
$url_params['disable-funding'] = implode(',', $disabled_funding);
}
-
// Enqueue the PayPal JS
wp_enqueue_script(
'eea_paypal_commerce_js_lib',
@@ -505,7 +497,6 @@
[],
null
);
-
wp_enqueue_script(
'eea_paypal_commerce_js',
EEP_PAYPAL_COMMERCE_URL . 'assets/js/paypal-commerce-payments.js',
@@ -551,7 +542,7 @@
// Convert money for a display format.
$decimal_places = CurrencyManager::getDecimalPlaces();
$org_country = isset(EE_Registry::instance()->CFG->organization)
- && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
+ && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
? EE_Registry::instance()->CFG->organization->CNT_ISO
: 'US';
$transaction_id = $this->transaction instanceof EE_Transaction ? $this->transaction->ID() : 0;
@@ -595,10 +586,20 @@
'general_pp_error' => esc_html__('PayPal form threw an error.', 'event_espresso'),
'hf_render_error' => esc_html__('Hosted fields could not be rendered!', 'event_espresso'),
'pm_capture_error' => esc_html__('Payment could not be captured!', 'event_espresso'),
+ 'contact_support_msg' => sprintf(
+ /* translators: %1$s: organization email, %2$s: the transaction ID */
+ esc_html__(
+ 'Please contact support (%1$s) for more details on this transaction #%2$s.',
+ 'event_espresso'
+ ),
+ EE_Registry::instance()->CFG->organization->get_pretty('email'),
+ $transaction_id
+ ),
'not_acdc_eligible' => esc_html__(
'This merchant is not eligible for Advanced Card Fields checkout type.',
'event_espresso'
),
+ 'processor_response' => esc_html__('Processor response: ', 'event_espresso'),
];
}
}
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCheckout/forms/SettingsForm.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCheckout/forms/SettingsForm.php
@@ -11,7 +11,6 @@
use EE_Select_Input;
use EE_Checkbox_Multi_Input;
use EED_PayPalOnboard;
-use EEH_Array;
use EEH_HTML;
use EventEspressoPaymentMethodsPayPalCommercedomainDomain;
use EventEspressoPaymentMethodsPayPalCommercetoolsextra_metaPayPalExtraMetaManager;
@@ -70,13 +69,6 @@
parent::__construct($form_parameters);
// Add a form for PayPal Onboard.
$this->addOnboardingForm($payment_method, $pm_instance);
- // Add a form for PayPal Onboard.
- add_filter(
- 'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
- [__CLASS__, 'addFeesNotice'],
- 10,
- 2
- );
// Add the clear data button.
$this->clearMetadataButton($pm_instance);
// Disable inputs if needed.
@@ -109,58 +101,6 @@
/**
- * Add fees notice.
- *
- * @param array $subsections
- * @param EE_Payment_Method $payment_method
- * @return array
- */
- public static function addFeesNotice(array $subsections, EE_Payment_Method $payment_method): array
- {
- if (defined('EE_PPC_USE_PAYMENT_FEES') && ! EE_PPC_USE_PAYMENT_FEES) {
- // We want to be able to disable fees.
- return $subsections;
- }
- return EEH_Array::insert_into_array(
- $subsections,
- [
- 'partner_fees_notice' => new EE_Form_Section_HTML(
- EEH_HTML::tr(
- EEH_HTML::th()
- . EEH_HTML::thx()
- . EEH_HTML::td(
- EEH_HTML::div(
- EEH_HTML::strong(
- esc_html__(
- 'PayPal Partner Commission Fees are based upon the status of your Support License:',
- 'event_espresso'
- )
- )
- . EEH_HTML::ul()
- . EEH_HTML::li(
- esc_html__('- Active licenses commission fees: 0%', 'event_espresso')
- )
- . EEH_HTML::li(
- esc_html__('- Expired license commission fees: 3%', 'event_espresso')
- )
- . EEH_HTML::ulx()
- . esc_html__(
- 'Keep your support license active for: lower fees, up-to-date software and have access to our support team. By connecting and processing payments you agree to these terms.',
- 'event_espresso'
- ),
- '',
- 'ee-status-outline ee-status-bg--info'
- )
- )
- )
- ),
- ],
- 'fine_print'
- );
- }
-
-
- /**
* Add a checkout type select.
*
* @param array $form_parameters
@@ -172,7 +112,7 @@
{
$pm_slug = $this->pm_instance->slug();
// Section to be displayed if onboard.
- $form_parameters['extra_meta_inputs'][Domain::META_KEY_CHECKOUT_TYPE] = new EE_Select_Input(
+ $form_parameters['extra_meta_inputs'][ Domain::META_KEY_CHECKOUT_TYPE ] = new EE_Select_Input(
[
'express_checkout' => esc_html__('Express Checkout', 'event_espresso'),
'ppcp' => esc_html__('Advanced Credit and Debit Card payments', 'event_espresso'),
@@ -205,17 +145,27 @@
{
$pm_slug = $this->pm_instance->slug();
// Section to be displayed if onboard.
- $form_parameters['extra_meta_inputs'][Domain::META_KEY_FUNDING_OPTIONS] = new EE_Checkbox_Multi_Input(
+ $form_parameters['extra_meta_inputs'][ Domain::META_KEY_FUNDING_OPTIONS ] = new EE_Checkbox_Multi_Input(
[
- 'venmo' => esc_html__('Venmo', 'event_espresso'),
- 'paylater' => esc_html__('PayLater', 'event_espresso'),
+ 'venmo' => esc_html__('Venmo', 'event_espresso'),
+ 'paylater' => esc_html__('PayLater', 'event_espresso'),
+ 'bancontact' => esc_html__('Bancontact', 'event_espresso'),
+ 'blik' => esc_html__('BLIK', 'event_espresso'),
+ 'eps' => esc_html__('EPS', 'event_espresso'),
+ 'giropay' => esc_html__('giropay', 'event_espresso'),
+ 'ideal' => esc_html__('iDEAL', 'event_espresso'),
+ 'mercadopago' => esc_html__('Mercado Pago', 'event_espresso'),
+ 'mybank' => esc_html__('MyBank', 'event_espresso'),
+ 'p24' => esc_html__('Przelewy24', 'event_espresso'),
+ 'sepa' => esc_html__('SEPA-Lastschrift', 'event_espresso'),
+ 'sofort' => esc_html__('Sofort', 'event_espresso'),
],
[
'html_name' => "eep_checkout_funding_options_$pm_slug",
'html_id' => "eep_checkout_funding_options_$pm_slug",
'html_class' => "eep-checkout-funding-options-$pm_slug",
'html_label_text' => esc_html__('Enable PayPal funding options:', 'event_espresso'),
- 'default' => ['venmo', 'paylater'],
+ 'default' => Domain::FUNDING_OPTIONS,
]
);
return $form_parameters;
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCommerce.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/PayPalCommerce.php
@@ -83,6 +83,7 @@
null,
null,
'EventEspressocoredomainservicescapabilitiesFeatureFlags' => EE_Dependency_Map::load_from_cache,
+ 'EventEspressocoreservicespayment_methodsgatewaysGatewayDataFormatter' => EE_Dependency_Map::load_from_cache,
]
);
EE_Dependency_Map::instance()->registerDependencies(
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/api/orders/CaptureOrder.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/api/orders/CaptureOrder.php
@@ -110,9 +110,10 @@
error_log("PayPalLogger Error: $message: " . json_encode($response));
}
return [
- 'error' => $response['error'] ?? 'missing_order',
- 'message' => $response['message'] ?? $message,
- 'name' => $response['name'] ?? 'UNKNOWN_ERROR',
+ 'error' => $response['error'] ?? 'missing_order',
+ 'message' => $response['message'] ?? $message,
+ 'name' => $response['name'] ?? 'UNKNOWN_ERROR',
+ 'response' => $response,
];
}
return $response;
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php
@@ -3,12 +3,18 @@
namespace EventEspressoPaymentMethodsPayPalCommerceapiorders;
use EE_Error;
+use EE_Country;
use EE_Line_Item;
+use EE_Payment;
+use EE_State;
use EE_Transaction;
+use EEM_Country;
+use EEM_Payment;
use EventEspressocoredomainservicescapabilitiesFeatureFlag;
use EventEspressocoredomainservicescapabilitiesFeatureFlags;
use EventEspressocoredomainservicesvalidationemailstrategiesBasic;
use EventEspressocoreservicesloadersLoaderFactory;
+use EventEspressocoreservicespayment_methodsgatewaysGatewayDataFormatter;
use EventEspressocoreservicesrequestsanitizersRequestSanitizer;
use EventEspressoPaymentMethodsPayPalCommerceapiPayPalApi;
use EventEspressoPaymentMethodsPayPalCommercedomainDomain;
@@ -70,26 +76,38 @@
*
* @var EE_Transaction
*/
- protected EE_Transaction $transaction;
+ protected EE_Transaction $transaction;
- private FeatureFlags $feature;
+ private FeatureFlags $feature;
+
+ private GatewayDataFormatter $gateway_data_formatter;
+
+ private EE_Payment $payment;
/**
* CreateOrder constructor.
*
- * @param PayPalApi $api
- * @param EE_Transaction $transaction
- * @param array $billing_info
- * @param FeatureFlags $feature
- */
- public function __construct(PayPalApi $api, EE_Transaction $transaction, array $billing_info, FeatureFlags $feature)
- {
+ * @param PayPalApi $api
+ * @param EE_Transaction $transaction
+ * @param array $billing_info
+ * @param FeatureFlags $feature
+ * @param GatewayDataFormatter $gateway_data_formatter
+ */
+ public function __construct(
+ PayPalApi $api,
+ EE_Transaction $transaction,
+ array $billing_info,
+ FeatureFlags $feature,
+ GatewayDataFormatter $gateway_data_formatter
+ ) {
parent::__construct($api);
$this->transaction = $transaction;
$this->feature = $feature;
$this->currency_code = CurrencyManager::currencyCode();
$this->sanitizeRequestParameters($billing_info);
+ $this->gateway_data_formatter = $gateway_data_formatter;
+ $this->setPaymentPlaceholder();
}
@@ -120,6 +138,15 @@
$order_parameters = $this->getParameters();
// Create Order request.
$create_response = $this->api->sendRequest($order_parameters, $this->request_url);
+ // Check for MISMATCH errors.
+ if ($this->isMismatchError($create_response)) {
+ // Mismatch, fix items.
+ $order_parameters['purchase_units'][0]['items'] = $this->getSimplifiedItems();
+ // Add simplified breakdown.
+ $order_parameters['purchase_units'][0]['amount']['breakdown'] = $this->getSimplifiedAmountBreakdown();
+ // Retry Order request.
+ $create_response = $this->api->sendRequest($order_parameters, $this->request_url);
+ }
return $this->validateOrder($create_response, $order_parameters);
}
@@ -136,14 +163,10 @@
{
$registrant = $this->transaction->primary_registration();
$attendee = $registrant->attendee();
- $event = $registrant->event();
- $description = $event->name() ?: sprintf(
- esc_html__('Tickets for an event at %1$s', 'event_espresso'),
- get_bloginfo('name')
- );
+ $description = $this->gateway_data_formatter->formatOrderDescription($this->payment);
$parameters = [
- 'intent' => 'CAPTURE',
- 'purchase_units' => [
+ 'intent' => 'CAPTURE',
+ 'purchase_units' => [
[
'custom_id' => $this->transaction->ID(),
'description' => substr(wp_strip_all_tags($description), 0, 125),
@@ -155,19 +178,49 @@
],
],
],
- 'application_context' => [
- 'shipping_preference' => 'NO_SHIPPING',
- 'user_action' => 'PAY_NOW',
- ],
- 'payer' => [
- 'email_address' => $attendee->email(),
- 'name' => [
- 'given_name' => $attendee->fname(),
- 'surname' => $attendee->lname(),
-
+ 'payment_source' => [
+ 'paypal' => [
+ 'experience_context' => [
+ 'user_action' => 'PAY_NOW',
+ ],
+ 'email_address' => $attendee->email(),
+ 'name' => [
+ 'given_name' => $attendee->fname(),
+ 'surname' => $attendee->lname(),
+ ],
],
],
];
+ $CNT_ISO = $attendee->country_ID();
+
+ // No country ID set, maybe just state?
+ if (empty($CNT_ISO)) {
+ $state_obj = $attendee->state_obj();
+ if ($state_obj instanceof EE_State) {
+ $CNT_ISO = $state_obj->country_iso();
+ }
+ }
+
+ if (strlen($CNT_ISO) > 2) {
+ // uh-oh... did anyone save the country name for the ISO?
+ $country = EEM_Country::instance()->getCountryByName(ucwords(strtolower($CNT_ISO)));
+ if ($country instanceof EE_Country) {
+ $CNT_ISO = $country->ISO();
+ }
+ }
+
+ // If we have and address on the attendee, send it to PayPal.
+ if ($CNT_ISO && strlen($CNT_ISO) == 2) {
+ $parameters['payment_source']['paypal']['address'] = [
+ 'address_line_1' => $attendee->address(),
+ 'address_line_2' => $attendee->address2(),
+ 'admin_area_2' => $attendee->city(),
+ 'admin_area_1' => $attendee->state_abbrev(),
+ 'postal_code' => $attendee->zip(),
+ 'country_code' => $attendee->country_ID(),
+ ];
+ }
+
// Do we have the permissions for the fees ?
$scopes = PayPalExtraMetaManager::getPmOption(
$this->transaction->payment_method(),
@@ -180,7 +233,8 @@
&& $this->feature->allowed(FeatureFlag::USE_PAYMENT_PROCESSOR_FEES)
)
)
- && ! empty($scopes) && in_array('partnerfee', $scopes)
+ && ! empty($scopes)
+ && in_array('partnerfee', $scopes)
) {
/** @var PartnerPaymentFees $payment_fees */
$payment_fees = LoaderFactory::getShared(PartnerPaymentFees::class);
@@ -192,7 +246,7 @@
'currency_code' => $this->currency_code,
],
],
- ]
+ ],
];
}
return $parameters;
@@ -217,12 +271,23 @@
&& $line_item->OBJ_type() !== 'Promotion'
&& $line_item->quantity() > 0
) {
- $item_money = CurrencyManager::normalizeValue($line_item->unit_price());
- $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso');
- $line_items [] = [
- 'name' => substr(wp_strip_all_tags($line_item->name()), 0, 126),
+ $item_money = CurrencyManager::normalizeValue($line_item->unit_price());
+ $line_items [] = [
+ 'name' => substr(
+ wp_strip_all_tags(
+ $this->gateway_data_formatter->formatLineItemName($line_item, $this->payment)
+ ),
+ 0,
+ 125
+ ),
'quantity' => $line_item->quantity(),
- 'description' => substr(wp_strip_all_tags($li_description), 0, 125),
+ 'description' => substr(
+ wp_strip_all_tags(
+ $this->gateway_data_formatter->formatLineItemDesc($line_item, $this->payment)
+ ),
+ 0,
+ 125
+ ),
'unit_amount' => [
'currency_code' => $this->currency_code,
'value' => (string) $item_money,
@@ -318,14 +383,115 @@
[$this->request_url, $parameters, $response],
$this->transaction->payment_method()
);
- } catch (EE_Error | ReflectionException $e) {
+ } catch (EE_Error|ReflectionException $e) {
error_log("PayPalLogger Error: $message: " . json_encode($response));
}
return [
- 'error' => $response['error'] ?? 'missing_order',
- 'message' => $response['message'] ?? $message,
+ 'error' => $response['error'] ?? 'missing_order',
+ 'message' => $response['message'] ?? $message,
+ 'response' => $response,
];
}
return $response;
}
+
+
+ /**
+ * Check if PayPals response contains 'MISMATCH' errors.
+ *
+ * @return bool
+ */
+ public function isMismatchError($response): bool
+ {
+ if (! isset($response['details']) || ! is_array($response['details'])) {
+ return false;
+ }
+
+ foreach ($response['details'] as $detail) {
+ if (! empty($detail['issue'])) {
+ if (
+ strtoupper($detail['issue']) === 'ITEM_TOTAL_MISMATCH'
+ || strtoupper($detail['issue']) === 'AMOUNT_MISMATCH'
+ ) {
+ PayPalLogger::errorLog(
+ esc_html__('Mistmatch Error:', 'event_espresso'),
+ [$this->request_url, $response],
+ $this->transaction->payment_method(),
+ false,
+ $this->transaction
+ );
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Itemize the simplified payment breakdown list.
+ *
+ * @return array
+ */
+ protected function getSimplifiedAmountBreakdown(): array
+ {
+ $tax_total = $this->transaction->tax_total();
+ $breakdown['item_total'] = [
+ 'currency_code' => $this->currency_code,
+ 'value' => (string) CurrencyManager::normalizeValue($this->transaction->remaining() - $tax_total),
+ ];
+ if ($tax_total > 0) {
+ $breakdown['tax_total'] = [
+ 'currency_code' => $this->currency_code,
+ 'value' => (string) CurrencyManager::normalizeValue($tax_total),
+ ];
+ }
+ return $breakdown;
+ }
+
+
+ /**
+ * Generate single line item for full order.
+ *
+ * @return array
+ */
+ protected function getSimplifiedItems(): array
+ {
+ // Simplified single line item.
+ $line_items = [];
+ $primary_registrant = $this->transaction->primary_registration();
+ $event_obj = $primary_registrant->event_obj();
+ $name_and_description = $this->gateway_data_formatter->formatOrderDescription($this->payment);
+
+ $line_items[] = [
+ 'name' => substr(wp_strip_all_tags($name_and_description), 0, 125),
+ 'quantity' => 1,
+ 'description' => substr(wp_strip_all_tags($name_and_description), 0, 2047),
+ 'unit_amount' => [
+ 'currency_code' => $this->currency_code,
+ 'value' => (string) CurrencyManager::normalizeValue(
+ $this->transaction->remaining() - $this->transaction->tax_total()
+ ),
+ ],
+ 'category' => 'DIGITAL_GOODS',
+ ];
+ return $line_items;
+ }
+
+
+ /**
+ * Generates an EE_Payment object but doesn't save it.
+ */
+ private function setPaymentPlaceholder(): void
+ {
+ $this->payment = EE_Payment::new_instance(
+ [
+ 'STS_ID' => EEM_Payment::status_id_pending,
+ 'TXN_ID' => $this->transaction->ID(),
+ 'PMD_ID' => $this->transaction->payment_method_ID(),
+ 'PAY_amount' => 0.00,
+ 'PAY_timestamp' => time(),
+ ]
+ );
+ }
}
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/api/orders/OrderDetails.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/api/orders/OrderDetails.php
@@ -91,8 +91,9 @@
error_log("PayPalLogger Error: $message: " . json_encode($response));
}
return [
- 'error' => $response['error'] ?? 'missing_order_info',
- 'message' => $response['message'] ?? $message,
+ 'error' => $response['error'] ?? 'missing_order_info',
+ 'message' => $response['message'] ?? $message,
+ 'response' => $response,
];
}
return $response;
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/domain/Domain.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/domain/Domain.php
@@ -171,6 +171,32 @@
*/
public const PM_SLUG = 'paypalcheckout';
+ /**
+ * Holds an array of funding options.
+ */
+ public const FUNDING_OPTIONS = [
+ 'venmo',
+ 'paylater',
+ 'bancontact',
+ 'blik',
+ 'eps',
+ 'giropay',
+ 'ideal',
+ 'mercadopago',
+ 'mybank',
+ 'p24',
+ 'sepa',
+ 'sofort',
+ ];
+
+ /**
+ * Holds an array of default/enabled funding options.
+ */
+ public const DEFAULT_FUNDING_OPTIONS = [
+ 'venmo',
+ 'paylater',
+ ];
+
/**
* Returns the base PayPal API URL.
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/modules/EED_PayPalCommerce.module.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/modules/EED_PayPalCommerce.module.php
@@ -134,8 +134,8 @@
* @throws ReflectionException
*/
public static function createOrder(
- EE_Transaction $transaction,
- array $billing_info,
+ EE_Transaction $transaction,
+ array $billing_info,
EE_Payment_Method $paypal_pm
): array {
$create_order_api = EED_PayPalCommerce::getCreateOrderApi($transaction, $billing_info, $paypal_pm);
@@ -162,10 +162,12 @@
);
}
return [
- 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR',
- 'message' => $order['message'],
+ 'error' => 'CREATE_ORDER_API_RESPONSE_ERROR',
+ 'message' => EEG_PayPalCheckout::getResponseMessage($order['response'], $order['message']),
+ 'response' => $order['message'],
];
}
+ $transaction->save();
return [
'pp_order_id' => $order['id'],
];
@@ -235,8 +237,8 @@
* @throws ReflectionException
*/
public static function getCreateOrderApi(
- EE_Transaction $transaction,
- array $billing_info,
+ EE_Transaction $transaction,
+ array $billing_info,
EE_Payment_Method $paypal_pm
): ?CreateOrder {
$paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
@@ -258,9 +260,9 @@
* @throws ReflectionException
*/
public static function getCaptureOrderApi(
- EE_Transaction $transaction,
+ EE_Transaction $transaction,
EE_Payment_Method $paypal_pm,
- string $order_id
+ string $order_id
): ?CaptureOrder {
$paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
if (! $paypal_api instanceof PayPalApi) {
@@ -281,8 +283,8 @@
* @throws ReflectionException
*/
public static function getOrderDetailsApi(
- string $order_id,
- EE_Transaction $transaction,
+ string $order_id,
+ EE_Transaction $transaction,
EE_Payment_Method $paypal_pm
): ?OrderDetails {
$paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
@@ -392,7 +394,7 @@
{
$pp_meta_data = PayPalExtraMetaManager::getAllData($paypal_pm);
return ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
- && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]);
+ && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ]);
}
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php
@@ -61,13 +61,14 @@
// Get onboarding URL.
add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']);
// Catch the return/redirect from PayPal onboarding page.
- add_action('init', [__CLASS__, 'updateOnboardingStatus']);
+ add_action('admin_init', [__CLASS__, 'updateOnboardingStatus']);
// Return the connection/onboard status.
add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']);
// Revoke access.
add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']);
// Clear all metadata.
add_action('wp_ajax_eeaPpClearMetaData', [__CLASS__, 'clearMetaData']);
+ add_action('wp_ajax_eeaPpSaveDebugMode', [__CLASS__, 'eeaPpSaveDebugMode']);
// Admin notice.
add_action('admin_init', [__CLASS__, 'adminNotice']);
}
@@ -298,6 +299,15 @@
$get_params = EED_Module::getRequest()->getParams();
// Get the payment method.
$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
+ if (! $paypal_pm instanceof EE_Payment_Method) {
+ PayPalLogger::errorLog(
+ esc_html__('Not able to validate the payment method.', 'event_espresso'),
+ $get_params,
+ $paypal_pm
+ );
+ EED_PayPalOnboard::redirectToPmSettingsHome();
+ return;
+ }
// Check the response (GET) parameters.
if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
// Missing parameters. Can't proceed.
@@ -316,7 +326,7 @@
);
if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
PayPalLogger::errorLog(
- $onboarding_status['message'],
+ $onboarding_status['message'] ?? esc_html__('Failed to track seller onboarding.', 'event_espresso'),
array_merge($get_params, $onboarding_status),
$paypal_pm
);
@@ -365,7 +375,7 @@
*/
public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string
{
- // Do we have it saved ?
+ // See if it's already saved.
$access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN);
// If we don't have it, request/update it.
if (! $access_token) {
@@ -395,8 +405,8 @@
}
// Validate the token expiration date.
$minutes_left = round(($expires_at - time()) / 60);
- // Count as expired if less than 60 minutes till expiration left.
- if ($minutes_left <= 60) {
+ // Refresh if less than 2 hours till expiration left. Access tokens have a life of 15 minutes or 8 hours.
+ if ($minutes_left <= 60 * 2) {
return true;
}
return false;
@@ -562,6 +572,26 @@
wp_send_json(['success' => true]);
}
+
+ /**
+ * Save the sandbox mode option.
+ * (AJAX)
+ *
+ * @return void
+ * @throws EE_Error
+ * @throws ReflectionException
+ */
+ public static function eeaPpSaveDebugMode(): void
+ {
+ $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
+ EED_PayPalOnboard::validatePmAjax($paypal_pm);
+ // Reset the partner access token.
+ PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams());
+ // And do the data reset.
+ PayPalExtraMetaManager::deleteAllData($paypal_pm);
+ wp_send_json(['success' => true]);
+ }
+
/**
* Validate the PM instance, returning an ajax response on invalid.
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php
@@ -6,6 +6,7 @@
use EE_Payment_Method;
use EventEspressocoreservicesencryptionBase64Encoder;
use EventEspressocoreservicesloadersLoaderFactory;
+use EventEspressocoreservicesrequestRequestInterface;
use EventEspressoPaymentMethodsPayPalCommercedomainDomain;
use EventEspressoPaymentMethodsPayPalCommercetoolsencryptionOpenSSLEncryption;
use EventEspressoPaymentMethodsPayPalCommercetoolsencryptionPPCommerceEncryptionKeyManager;
@@ -37,9 +38,14 @@
*/
public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta
{
+ $post_params = LoaderFactory::getLoader()->getShared(RequestInterface::class)->postParams();
if (
! PayPalExtraMetaManager::$pay_pal_extra_meta instanceof PayPalExtraMeta
|| PayPalExtraMetaManager::$pay_pal_extra_meta->pm->slug() !== $paypal_pm->slug()
+ || (! empty($post_params['sandbox_mode'])
+ && in_array($post_params['sandbox_mode'], ['0', '1'], true)
+ && $paypal_pm->debug_mode() !== (bool) $post_params['sandbox_mode']
+ )
) {
PayPalExtraMetaManager::$pay_pal_extra_meta = new PayPalExtraMeta($paypal_pm);
}
--- a/event-espresso-decaf/PaymentMethods/PayPalCommerce/tools/logging/PayPalLogger.php
+++ b/event-espresso-decaf/PaymentMethods/PayPalCommerce/tools/logging/PayPalLogger.php
@@ -58,7 +58,7 @@
* @param string $error_message
* @param array $data
* @param EE_Payment_Method|null $paypal_pm
- * @param mixed $object_logged
+ * @param mixed $object_logged
* @param bool $popup_log
* @return bool
*/
@@ -81,7 +81,7 @@
}
$paypal_gateway = $paypal_pm->type_obj()->get_gateway();
if ($paypal_gateway instanceof EE_Gateway) {
- $paypal_gateway->log([$default_msg => $data], $object_logged);
+ $paypal_gateway->log([$default_msg, $data], $object_logged);
}
if ($popup_log) {
PayPalLogger::logInWindow(json_encode($data));
--- a/event-espresso-decaf/admin_pages/about/About_Admin_Page_Init.core.php
+++ b/event-espresso-decaf/admin_pages/about/About_Admin_Page_Init.core.php
@@ -1,6 +1,8 @@
<?php
+use EventEspressocoredomainentitiesadminmenuAdminMenuGroup;
use EventEspressocoredomainentitiesadminmenuAdminMenuItem;
+use EventEspressocoredomainentitiesadminmenuAdminMenuTopLevel;
/**
* EE_About_Admin_Page_Init
@@ -39,14 +41,14 @@
{
return [
'menu_type' => AdminMenuItem::TYPE_MENU_SUB_ITEM,
- 'menu_group' => 'extras',
+ 'menu_group' => AdminMenuGroup::MENU_SLUG_EXTRAS,
'menu_order' => 40,
'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_AND_NETWORK,
- 'parent_slug' => 'espresso_events',
- 'menu_slug' => 'espresso_about',
+ 'parent_slug' => AdminMenuTopLevel::MENU_PARENT_ACTIVE,
+ 'menu_slug' => EE_ABOUT_PG_SLUG,
'menu_label' => EE_ABOUT_LABEL,
'capability' => 'manage_options',
- 'maintenance_mode_parent' => 'espresso_maintenance_settings',
+ 'maintenance_mode_parent' => AdminMenuTopLevel::MENU_PARENT_MAINTENANCE,
];
}
}
--- a/event-espresso-decaf/admin_pages/events/Events_Admin_Page.core.php
+++ b/event-espresso-decaf/admin_pages/events/Events_Admin_Page.core.php
@@ -1726,7 +1726,7 @@
*/
/** @var EEM_Datetime $datetime_model */
$datetime_model = EE_Registry::instance()->load_model('Datetime');
- /** @var EEM_Ticket $datetime_model */
+ /** @var EEM_Ticket $ticket_model */
$ticket_model = EE_Registry::instance()->load_model('Ticket');
$times = $datetime_model->get_all_event_dates($event_id);
/** @type EE_Datetime $first_datetime */
@@ -1754,13 +1754,11 @@
}
} else {
$template_args['total_ticket_rows'] = 1;
- /** @type EE_Ticket $ticket */
$ticket = $ticket_model->create_default_object();
$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
}
} else {
$template_args['time'] = $times[0];
- /** @type EE_Ticket[] $tickets */
$tickets = $ticket_model->get_all_default_tickets();
$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
// NOTE: we're just sending the first default row
@@ -2627,7 +2625,7 @@
$registration_config->default_STS_ID = $valid_data['default_reg_status'];
}
if (isset($valid_data['default_max_tickets'])) {
- $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
+ $registration_config->default_maximum_number_of_tickets = (int) $valid_data['default_max_tickets'];
}
do_action(
'AHEE__Events_Admin_Page___update_default_event_settings',
--- a/event-espresso-decaf/admin_pages/events/Events_Admin_Page_Init.core.php
+++ b/event-espresso-decaf/admin_pages/events/Events_Admin_Page_Init.core.php
@@ -1,6 +1,8 @@
<?php
+use EventEspressocoredomainentitiesadminmenuAdminMenuGroup;
use EventEspressocoredomainentitiesadminmenuAdminMenuItem;
+use EventEspressocoredomainentitiesadminmenuAdminMenuTopLevel;
/**
* Events_Admin_Page_Init
@@ -41,14 +43,14 @@
public function getMenuProperties(): array
{
return [
- 'menu_type' => AdminMenuItem::TYPE_MENU_SUB_ITEM,
- 'menu_group' => 'main',
- 'menu_order' => 10,
- 'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_ONLY,
- 'parent_slug' => 'espresso_events',
- 'menu_slug' => 'espresso_events',
- 'menu_label' => esc_html__('Events', 'event_espresso'),
- 'capability' => 'ee_read_events',
+ 'menu_type' => AdminMenuItem::TYPE_MENU_SUB_ITEM,
+ 'menu_group' => AdminMenuGroup::MENU_SLUG_MAIN,
+ 'menu_order' => 10,
+ 'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_ONLY,
+ 'parent_slug' => AdminM