From 3169fd5e226326b2c747934ef1e20ae06975791f Mon Sep 17 00:00:00 2001 From: Tony Warwick Date: Wed, 20 Mar 2024 00:32:44 +0000 Subject: [PATCH] Lastest cafe changes 5.0.19.p --- CHANGELOG.md | 24 ++- .../EEG_PayPalCheckout.gateway.php | 52 +++-- .../api/orders/CaptureOrder.php | 8 +- .../PayPalCommerce/api/orders/CreateOrder.php | 21 +- .../assets/js/eea-paypal-onboarding.js | 2 + .../PayPalCommerce/domain/Domain.php | 6 +- .../modules/EED_PayPalOnboard.module.php | 2 +- .../tools/extra_meta/PayPalExtraMeta.php | 9 +- .../extra_meta/PayPalExtraMetaManager.php | 14 +- .../events/Events_Admin_List_Table.class.php | 20 +- .../maintenance/assets/ee-maintenance.css | 26 +-- .../EE_Attendee_Contact_List_Table.class.php | 17 +- .../Registrations_Admin_Page.core.php | 22 ++ core/CPTs/CptQueryModifier.php | 18 +- core/CPTs/EE_CPT_Attendee_Strategy.core.php | 12 +- core/CPTs/EE_CPT_Default_Strategy.core.php | 11 +- core/CPTs/EE_CPT_Event_Strategy.core.php | 190 ++++++++++-------- core/CPTs/EE_CPT_Strategy.core.php | 20 +- core/CPTs/EE_CPT_Venue_Strategy.core.php | 19 +- core/EE_Dependency_Map.core.php | 5 + core/EE_System.core.php | 2 - core/admin/EE_Admin_Page.core.php | 50 +++-- core/admin/EE_Admin_Page_CPT.core.php | 4 +- core/db_classes/EE_Term.class.php | 51 +++-- core/db_models/EEM_Base.model.php | 26 +-- .../CustomPostTypeDefinitions.php | 56 ++---- .../CustomTaxonomyDefinitions.php | 80 ++++---- .../custom_post_types/CustomTaxonomyTerm.php | 43 +--- .../status_change/StatusChangeNotice.php | 2 +- .../status_change/status_change_notice.css | 1 + .../status_change/status_change_notice.js | 1 + .../registrations/list_table/QueryBuilder.php | 25 ++- core/helpers/EEH_Debug_Tools.helper.php | 4 +- core/helpers/EEH_Event_View.helper.php | 15 +- .../batch/JobHandlers/RegistrationsReport.php | 48 ++++- .../global_assets/css/espresso_default.css | 5 - espresso.php | 4 +- .../EED_Thank_You_Page.module.php | 10 +- .../thank_you_page/assets/thank_you_page.css | 39 ++++ ...you-page-registration-details.template.php | 79 ++++---- 40 files changed, 592 insertions(+), 451 deletions(-) create mode 100644 modules/thank_you_page/assets/thank_you_page.css diff --git a/CHANGELOG.md b/CHANGELOG.md index ce0bc77d8ad..c9eb602db6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Releases +### [5.0.19] + +#### Fixed + - [PPC. Fix instantiating wrong extra metadata (#1150)](https://github.com/eventespresso/cafe/pull/1150) + - [Fix Status Codes Notice Container (#1156)](https://github.com/eventespresso/cafe/pull/1156) + - [Fix People Admin List Table Filters (#1139)](https://github.com/eventespresso/cafe/pull/1139) + - [Espresso Custom Post Type Fixes (#1163)](https://github.com/eventespresso/cafe/pull/1163) + - [PPC. Fix partial payments (#1134)](https://github.com/eventespresso/cafe/pull/1134) + +#### Changed + - [Build Machine 5.0.18.p changes (#1146)](https://github.com/eventespresso/cafe/pull/1146) + - [PPC. Add transaction to the logs (#1158)](https://github.com/eventespresso/cafe/pull/1158) + - [PPC. Update order status/error messages (#1162)](https://github.com/eventespresso/cafe/pull/1162) + - [Prevent fatal error from get_edit_post_link returning null (#1166)](https://github.com/eventespresso/cafe/pull/1166) + - [Remove Serialized Objects from Registration Report Requests (#1154)](https://github.com/eventespresso/cafe/pull/1154) + + ### [5.0.18] #### Added @@ -25,7 +42,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Improve AJAX Response Handling in SPCO (#1119)](https://github.com/eventespresso/cafe/pull/1119) - [Refactor Reg Admin List Table Columns (#1099)](https://github.com/eventespresso/cafe/pull/1099) - [Remove TAB Transaction Registrations from Reg Report CSV (#1093)](https://github.com/eventespresso/cafe/pull/1093) - - [Improve Custom Post Type Defense Against Hostile Themes - MOD Plugins (#1136)](https://github.com/eventespresso/cafe/pull/1136) + - [Improve Custom Post Type Defense Against Hostile Themes - [Build Machine 5.0.18.p changes (#1146)](https://github.com/eventespresso/cafe/pull/1146) + - [PPC. Add transaction to the logs (#1158)](https://github.com/eventespresso/cafe/pull/1158) + - [PPC. Update order status/error messages (#1162)](https://github.com/eventespresso/cafe/pull/1162) + - [Prevent fatal error from get_edit_post_link returning null (#1166)](https://github.com/eventespresso/cafe/pull/1166) + - [Remove Serialized Objects from Registration Report Requests (#1154)](https://github.com/eventespresso/cafe/pull/1154) + - MOD Plugins (#1136)](https://github.com/eventespresso/cafe/pull/1136) ### [5.0.17] diff --git a/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php b/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php index a504b344f25..63bbeaaa510 100644 --- a/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php +++ b/PaymentMethods/PayPalCommerce/PayPalCheckout/EEG_PayPalCheckout.gateway.php @@ -79,17 +79,16 @@ public function do_direct_payment($payment, $billing_info = null) $exception->getMessage() ); } - $order_id = $request->getRequestParam('pp_order_id', '', DataType::STRING); - $is_order_valid = $this->isOrderValid($order_id, $order); - if (! $is_order_valid['valid']) { + $order_id = $request->getRequestParam('pp_order_id', '', DataType::STRING); + $order_status = $this->isOrderCompleted($order_id, $order); + if (! $order_status['completed']) { return $this->setPaymentFailure( $payment, $failed_status, [$order, $request->postParams()], - $is_order_valid['message'] + $order_status['message'] ); } - // Remove the saved order data. PayPalExtraMetaManager::deletePmOption($payment_method, Domain::META_KEY_LAST_ORDER); // Looks like all is good. Do a payment success. @@ -139,30 +138,47 @@ public function validateThisPayment(?EE_Payment $payment, RequestInterface $requ * * @param string $provided_order_id * @param $order - * @return array [valid => {boolean}, message => {string}] + * @return array ['completed' => {boolean}, 'message' => {string}] */ - public function isOrderValid(string $provided_order_id, $order): array + public function isOrderCompleted(string $provided_order_id, $order): array { $conclusion = [ - 'valid' => false, - 'message' => esc_html__('Could not validate this Order.', 'event_espresso'), + 'completed' => false, + 'message' => esc_html__('Could not validate this Order.', 'event_espresso'), ]; // Check the provided Order and order ID. if (! $provided_order_id) { - $conclusion['message'] = esc_html__('Invalid Order ID provided !', 'event_espresso'); + $conclusion['message'] = esc_html__( + 'Invalid Order ID provided! Not able to confirm the order', + 'event_espresso' + ); } elseif (! $order || ! is_array($order)) { - $conclusion['message'] = esc_html__('Order data in wrong format.', 'event_espresso'); + $conclusion['message'] = esc_html__('Order data is in wrong format.', 'event_espresso'); } elseif ($order['id'] !== $provided_order_id) { $conclusion['message'] = esc_html__('Order ID mismatch.', 'event_espresso'); - } elseif (empty($order['status']) - || $order['status'] !== 'COMPLETED' - || empty($order['purchase_units'][0]['payments']['captures'][0]['status']) - || $order['purchase_units'][0]['payments']['captures'][0]['status'] !== 'COMPLETED' - ) { - $conclusion['message'] = esc_html__('Order not completed.', 'event_espresso'); + } elseif (empty($order['status'])) { + $conclusion['message'] = esc_html__( + 'There was an error with this payment. The status of the Order could not be determined.', + 'event_espresso' + ); + } elseif ($order['status'] !== 'COMPLETED') { + $conclusion['message'] = esc_html__( + 'There was an error with this payment. Order was not approved.', + 'event_espresso' + ); + } elseif (empty($order['purchase_units'][0]['payments']['captures'][0]['status'])) { + $conclusion['message'] = esc_html__( + 'There was an error with this payment. The status of the Payment could not be determined.', + 'event_espresso' + ); + } elseif ($order['purchase_units'][0]['payments']['captures'][0]['status'] !== 'COMPLETED') { + $conclusion['message'] = esc_html__( + 'This payment was declined or failed validation. Please check the billing information you provided.', + 'event_espresso' + ); } else { // If we didn't fail on the above, the Order should be considered valid. - $conclusion['valid'] = true; + $conclusion['completed'] = true; } return $conclusion; } diff --git a/PaymentMethods/PayPalCommerce/api/orders/CaptureOrder.php b/PaymentMethods/PayPalCommerce/api/orders/CaptureOrder.php index 892e1354ce2..4e6522d3acf 100644 --- a/PaymentMethods/PayPalCommerce/api/orders/CaptureOrder.php +++ b/PaymentMethods/PayPalCommerce/api/orders/CaptureOrder.php @@ -76,7 +76,13 @@ public function capture(): array public function validateOrder($response): array { $message = esc_html__('Validating Order Capture:', 'event_espresso'); - PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); + PayPalLogger::errorLog( + $message, + [$this->request_url, $response], + $this->transaction->payment_method(), + false, + $this->transaction + ); // We got a direct error response. Not valid. Return that error. if (! empty($response['error'])) { return $response; diff --git a/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php b/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php index 860f6d43ee9..ff41af7b343 100644 --- a/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php +++ b/PaymentMethods/PayPalCommerce/api/orders/CreateOrder.php @@ -139,7 +139,7 @@ protected function getParameters(): array 'description' => substr(wp_strip_all_tags($description), 0, 125), 'items' => $this->getLineItems(), 'amount' => [ - 'value' => $this->transaction->total(), + 'value' => $this->transaction->remaining(), 'currency_code' => $this->currency_code, 'breakdown' => $this->getBreakdown(), ], @@ -174,7 +174,10 @@ protected function getLineItems(): array $event_line_items = $this->transaction->items_purchased(); // List actual line items. foreach ($event_line_items as $line_item) { - if ($line_item instanceof EE_Line_Item && $line_item->OBJ_type() !== 'Promotion') { + if ($line_item instanceof EE_Line_Item + && $line_item->OBJ_type() !== 'Promotion' + && $line_item->quantity() > 0 + ) { $item_money = $line_item->unit_price(); $li_description = $line_item->desc() ?? esc_html__('Event Ticket', 'event_espresso'); $line_items [] = [ @@ -189,7 +192,7 @@ protected function getLineItems(): array ]; // Line item total. $this->items_total += $line_item->pretaxTotal(); - } elseif ($line_item->OBJ_type() === 'Promotion') { + } elseif ($line_item->OBJ_type() === 'Promotion' && $line_item->quantity() > 0) { // Promotions total. $this->promos_total += $line_item->total(); } @@ -197,6 +200,10 @@ protected function getLineItems(): array // Make sure we have an absolute number with only two decimal laces. $this->items_total = CurrencyManager::normalizeValue($this->items_total); $this->promos_total = CurrencyManager::normalizeValue($this->promos_total); + // If this is a partial payment, apply the paid amount as a promo. + if ($this->transaction->paid() > 0) { + $this->promos_total += CurrencyManager::normalizeValue($this->transaction->paid()); + } $this->countTaxTotal(); return $line_items; } @@ -255,7 +262,13 @@ protected function getBreakdown(): array public function validateOrder($response, $parameters): array { $message = esc_html__('Validating Order Create:', 'event_espresso'); - PayPalLogger::errorLog($message, [$this->request_url, $response], $this->transaction->payment_method()); + PayPalLogger::errorLog( + $message, + [$this->request_url, $response], + $this->transaction->payment_method(), + false, + $this->transaction + ); if (! empty($response['error'])) { return $response; } diff --git a/PaymentMethods/PayPalCommerce/assets/js/eea-paypal-onboarding.js b/PaymentMethods/PayPalCommerce/assets/js/eea-paypal-onboarding.js index 5c889982e22..760e3c74d63 100644 --- a/PaymentMethods/PayPalCommerce/assets/js/eea-paypal-onboarding.js +++ b/PaymentMethods/PayPalCommerce/assets/js/eea-paypal-onboarding.js @@ -356,6 +356,8 @@ jQuery(document).ready(function ($) { if (is_valid && typeof callback !== 'undefined' && callback) { // Run the callback if there are no errors. callback(this_pm, response); + } else { + this_pm.processing_icon.fadeOut('fast'); } if (update_ui) { this_pm.updateOnboardingUI(this_pm, false); diff --git a/PaymentMethods/PayPalCommerce/domain/Domain.php b/PaymentMethods/PayPalCommerce/domain/Domain.php index 2ac1955034c..25d52c284b8 100644 --- a/PaymentMethods/PayPalCommerce/domain/Domain.php +++ b/PaymentMethods/PayPalCommerce/domain/Domain.php @@ -30,7 +30,7 @@ class Domain public const META_KEY_SANDBOX_MODE = 'sandbox_mode'; /** - * Name of the extra meta that stores the PayPal Access Token that is used get onboarding URL. + * Name of the extra meta that stores the Access Token that is used to auth in API requests to PayPal. */ public const META_KEY_ACCESS_TOKEN = 'access_token'; @@ -55,9 +55,9 @@ class Domain public const META_KEY_CLIENT_SECRET = 'client_secret'; /** - * Name of the extra meta that stores the expiration date of the client ID. + * Name of the extra meta that stores the expiration date of the Access Token. */ - public const META_KEY_EXPIRES_IN = 'expires_in'; + public const META_KEY_TOKEN_EXPIRES_IN = 'expires_in'; /** * Name of the extra meta that holds the partner client ID. diff --git a/PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php b/PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php index c394763ec3b..2831fc12e88 100644 --- a/PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php +++ b/PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php @@ -370,7 +370,7 @@ public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): stri */ public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool { - $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_EXPIRES_IN); + $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN); if (! $expires_at) { return true; } diff --git a/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMeta.php b/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMeta.php index 5dfb364c18e..72684c04b97 100644 --- a/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMeta.php +++ b/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMeta.php @@ -37,6 +37,8 @@ class PayPalExtraMeta * Class constructor. * * @param EE_Payment_Method $pm_instance + * @throws EE_Error + * @throws ReflectionException */ public function __construct(EE_Payment_Method $pm_instance) { @@ -89,9 +91,9 @@ public function getOption(string $option_name) * Get PM metadata. * Return the metadata array if all good. False otherwise. * - * @return array|bool + * @return array */ - public function getMetaData() + public function getMetaData(): array { try { return $this->pm->get_extra_meta($this->metadata_key, true, []); @@ -101,7 +103,7 @@ public function getMetaData() $e->getMessage() ); PayPalLogger::errorLog($err_msg, [], $this->pm); - return false; + return []; } } @@ -119,7 +121,6 @@ public function saveOption(string $name, $value): bool if (! $meta_data) { $meta_data = []; } - $meta_data[ $name ] = $value; return $this->saveMetaData($meta_data); } diff --git a/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php b/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php index 45003055f08..6920f1439c9 100644 --- a/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php +++ b/PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php @@ -82,7 +82,7 @@ public static function savePmOptions(EE_Payment_Method $paypal_pm, array $option * @return bool */ public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool - { + { $pp_meta_data = self::extraMeta($paypal_pm); return $pp_meta_data->deleteOption($option_name); } @@ -129,7 +129,7 @@ public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $requ && $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode'] ) { try { - $paypal_pm->save(['PMD_debug_mode' => $request_data['sandbox_mode']]); + $paypal_pm->save(['PMD_debug_mode' => (bool) $request_data['sandbox_mode']]); } catch (EE_Error $e) { $err_msg = sprintf( esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'), @@ -156,7 +156,7 @@ public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, arra $paypal_data = []; $expected_parameters = [ Domain::META_KEY_ACCESS_TOKEN, - Domain::META_KEY_EXPIRES_IN, + Domain::META_KEY_TOKEN_EXPIRES_IN, Domain::META_KEY_APP_ID, Domain::META_KEY_PARTNER_CLIENT_ID, Domain::META_KEY_PARTNER_MERCHANT_ID, @@ -173,7 +173,7 @@ public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, arra case Domain::META_KEY_PARTNER_MERCHANT_ID: $paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm); break; - case Domain::META_KEY_EXPIRES_IN: + case Domain::META_KEY_TOKEN_EXPIRES_IN: $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]); break; default: @@ -253,10 +253,12 @@ public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $ * * @param EE_Payment_Method $paypal_pm * @return PayPalExtraMeta + * @throws EE_Error + * @throws ReflectionException */ public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta { - return LoaderFactory::getLoader()->getShared(PayPalExtraMeta::class, [$paypal_pm]); + return new PayPalExtraMeta($paypal_pm); } @@ -266,6 +268,8 @@ public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta * @param string $text * @param EE_Payment_Method $paypal_pm * @return string|null + * @throws EE_Error + * @throws ReflectionException */ public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string { diff --git a/admin_pages/events/Events_Admin_List_Table.class.php b/admin_pages/events/Events_Admin_List_Table.class.php index 735755f2f81..c0afccc4140 100644 --- a/admin_pages/events/Events_Admin_List_Table.class.php +++ b/admin_pages/events/Events_Admin_List_Table.class.php @@ -8,21 +8,14 @@ * Class for preparing the table listing all the events * note: anywhere there are no php docs it is because the docs are available in the parent class. * - * @package Events_Admin_List_Table - * @subpackage includes/core/admin/events/Events_Admin_List_Table.class.php - * @author Darren Ethier + * @package Events_Admin_List_Table + * @subpackage includes/core/admin/events/Events_Admin_List_Table.class.php + * @author Darren Ethier + * @property Events_Admin_Page $_admin_page */ class Events_Admin_List_Table extends EE_Admin_List_Table { - /** - * @var Events_Admin_Page - */ - protected EE_Admin_Page $_admin_page; - - /** - * @var EE_Datetime - */ - private $_dtt; + private ?EE_Datetime $_dtt = null; /** @@ -97,8 +90,7 @@ protected function _get_table_filters() * @throws InvalidInterfaceException * @throws InvalidArgumentException * @throws EE_Error - * @throws EE_Error - * @throws EE_Error + * @throws ReflectionException */ protected function _add_view_counts() { diff --git a/admin_pages/maintenance/assets/ee-maintenance.css b/admin_pages/maintenance/assets/ee-maintenance.css index e1fc54bc3ce..1eaa365caab 100644 --- a/admin_pages/maintenance/assets/ee-maintenance.css +++ b/admin_pages/maintenance/assets/ee-maintenance.css @@ -8,35 +8,35 @@ Styling the progress bar and migration page /* GENERAL DISPLAY STUFF */ -.espresso-admin .maintenance_settings #post-body-content h2 { +.espresso-admin.wp-core-ui .maintenance_settings #post-body-content h2 { margin-block-start: unset; } -.ee-reset-delete-data-actions h4 { +.espresso-admin.wp-core-ui .ee-reset-delete-data-actions h4 { align-items: center; display: flex; font-size: var(--ee-font-size-xl); justify-content: flex-start; } -.ee-reset-delete-data-actions .ee-card { +.espresso-admin.wp-core-ui .ee-reset-delete-data-actions .ee-card { background-color: hsl(207deg 25% 97.5%); font-size: var(--ee-font-size-3xl); } -.ee-reset-delete-data-actions h4 .dashicons, -.ee-reset-delete-data-actions h4 .dashicons:before { +.espresso-admin.wp-core-ui .ee-reset-delete-data-actions h4 .dashicons, +.espresso-admin.wp-core-ui .ee-reset-delete-data-actions h4 .dashicons:before { font-size: var(--ee-font-size-4xl); + height: var(--ee-font-size-4xl); + width: var(--ee-font-size-4xl); } -.ee-reset-delete-data-actions h4 .dashicons { - margin-inline-end: 2rem; -} -.ee-reset-delete-data-actions h4 .dashicons:before { - position: relative; - top: -0.25rem; +.espresso-admin.wp-core-ui .ee-reset-delete-data-actions h4 .dashicons { + align-items: center; + display: inline-flex; + justify-content: center; + margin-inline-end: 1rem; } - -.ee-reset-delete-data-actions .ee-admin-button-row { +.espresso-admin.wp-core-ui .ee-reset-delete-data-actions .ee-admin-button-row { margin-block-start: 2rem; margin-block-end: 1rem; } diff --git a/admin_pages/registrations/EE_Attendee_Contact_List_Table.class.php b/admin_pages/registrations/EE_Attendee_Contact_List_Table.class.php index b725706ded3..f3ddb24d80f 100644 --- a/admin_pages/registrations/EE_Attendee_Contact_List_Table.class.php +++ b/admin_pages/registrations/EE_Attendee_Contact_List_Table.class.php @@ -7,21 +7,17 @@ * EE_Attendee_Contact_List_Table * List table for the EE_Attendee records in the admin. * - * @package EventEspresso - * @author Darren Ethier + * @package EventEspresso + * @author Darren Ethier + * @property Registrations_Admin_Page $_admin_page */ class EE_Attendee_Contact_List_Table extends EE_Admin_List_Table { - /** - * @var Registrations_Admin_Page - */ - protected EE_Admin_Page $_admin_page; - - /** * Initial setup of data (called by parent). * * @throws EE_Error + * @throws ReflectionException */ protected function _setup_data() { @@ -101,6 +97,7 @@ protected function _get_table_filters() * @throws InvalidInterfaceException * @throws EE_Error * @throws EE_Error + * @throws ReflectionException */ protected function _add_view_counts() { @@ -308,6 +305,7 @@ class="ee-aria-tooltip" * @param EE_Attendee $attendee * @return string * @throws EE_Error + * @throws ReflectionException */ public function column_ATT_email(EE_Attendee $attendee): string { @@ -344,6 +342,7 @@ public function column_Registration_Count(EE_Attendee $attendee): string * @param EE_Attendee $attendee * @return string * @throws EE_Error + * @throws ReflectionException */ public function column_ATT_address(EE_Attendee $attendee): string { @@ -357,6 +356,7 @@ public function column_ATT_address(EE_Attendee $attendee): string * @param EE_Attendee $attendee * @return string * @throws EE_Error + * @throws ReflectionException */ public function column_ATT_city(EE_Attendee $attendee): string { @@ -415,6 +415,7 @@ public function column_CNT_ISO(EE_Attendee $attendee): string * @param EE_Attendee $attendee * @return string * @throws EE_Error + * @throws ReflectionException */ public function column_ATT_phone(EE_Attendee $attendee): string { diff --git a/admin_pages/registrations/Registrations_Admin_Page.core.php b/admin_pages/registrations/Registrations_Admin_Page.core.php index 9556d7eaaa1..27962161ff0 100644 --- a/admin_pages/registrations/Registrations_Admin_Page.core.php +++ b/admin_pages/registrations/Registrations_Admin_Page.core.php @@ -3267,6 +3267,7 @@ public function _registrations_report_base(string $method_name_for_getting_query $return_url = $this->request->getRequestParam('return_url', '', DataType::URL); $filters = $this->request->getRequestParam('filters', [], DataType::STRING, true); $report_params = $this->$method_name_for_getting_query_params($filters); + $report_params = $this->convertDatetimeObjectsToStrings($report_params); $use_filters = $this->request->getRequestParam('use_filters', false, DataType::BOOL); wp_redirect( EE_Admin_Page::add_query_args_and_nonce( @@ -3284,6 +3285,7 @@ public function _registrations_report_base(string $method_name_for_getting_query } else { // Pull the current request params $request_args = $this->request->requestParams(); + $request_args = $this->convertDatetimeObjectsToStrings($request_args); // Set the required request_args to be passed to the export $required_request_args = [ 'export' => 'report', @@ -3301,6 +3303,26 @@ public function _registrations_report_base(string $method_name_for_getting_query } + /** + * recursively convert Datetime objects in query params array to strings using MySQL format + * + * @param array $query_params + * @return array + * @since $VID:$ + */ + private function convertDatetimeObjectsToStrings(array $query_params): array + { + foreach ($query_params as $key => $value) { + if (is_array($value)) { + $query_params[$key] = $this->convertDatetimeObjectsToStrings($value); + } elseif ($value instanceof DateTime) { + $query_params[$key] = $value->format('Y-m-d H:i:s'); + } + } + return $query_params; + } + + /** * Creates a registration report using only query parameters in the request * diff --git a/core/CPTs/CptQueryModifier.php b/core/CPTs/CptQueryModifier.php index af0c472afcb..197ba6e0f66 100644 --- a/core/CPTs/CptQueryModifier.php +++ b/core/CPTs/CptQueryModifier.php @@ -95,7 +95,7 @@ public function __construct( $this->setWpQuery($wp_query); $this->setPostType($post_type); $this->setCptDetails($cpt_details); - $this->init($wp_query); + $this->init(); } @@ -371,15 +371,9 @@ protected function cptStrategyClass(string $model_name) // creates classname like: CPT_Event_Strategy $CPT_Strategy_class_name = 'EE_CPT_' . $model_name . '_Strategy'; // load and instantiate - $CPT_Strategy = $this->loader->getShared( - $CPT_Strategy_class_name, - ['WP_Query' => $this->wp_query, 'CPT' => $this->cpt_details] - ); + $CPT_Strategy = $this->loader->getShared($CPT_Strategy_class_name, [$this->wp_query, $this->cpt_details]); if ($CPT_Strategy === null) { - $CPT_Strategy = $this->loader->getShared( - 'EE_CPT_Default_Strategy', - ['WP_Query' => $this->wp_query, 'CPT' => $this->cpt_details] - ); + $CPT_Strategy = $this->loader->getShared('EE_CPT_Default_Strategy', [$this->wp_query, $this->cpt_details]); } return $CPT_Strategy; } @@ -456,11 +450,11 @@ public function thePosts(array $posts, WP_Query $wp_query): array /** - * @param string $url + * @param string|null $url * @param int $ID - * @return string + * @return null|string */ - public function getEditPostLink(string $url, int $ID): string + public function getEditPostLink(?string $url, int $ID): ?string { // need to make sure we only edit links if our cpt global $post; diff --git a/core/CPTs/EE_CPT_Attendee_Strategy.core.php b/core/CPTs/EE_CPT_Attendee_Strategy.core.php index 175885c0ce8..2e9ec07ba8c 100644 --- a/core/CPTs/EE_CPT_Attendee_Strategy.core.php +++ b/core/CPTs/EE_CPT_Attendee_Strategy.core.php @@ -12,18 +12,18 @@ class EE_CPT_Attendee_Strategy /** * $CPT - the current page, if it utilizes CPTs * - * @var array - * @access protected + * @var array */ - protected $CPT = null; + protected array $CPT; /** - * @param array $arguments + * @param WP_Query $wp_query + * @param array $CPT */ - public function __construct(array $arguments = []) + public function __construct(WP_Query $wp_query, array $CPT = []) { - $this->CPT = $arguments['CPT'] ?? null; + $this->CPT = $CPT; } diff --git a/core/CPTs/EE_CPT_Default_Strategy.core.php b/core/CPTs/EE_CPT_Default_Strategy.core.php index 295a62e932d..84fb3285422 100644 --- a/core/CPTs/EE_CPT_Default_Strategy.core.php +++ b/core/CPTs/EE_CPT_Default_Strategy.core.php @@ -12,17 +12,18 @@ class EE_CPT_Default_Strategy /** * $CPT - the current page, if it utilizes CPTs * - * @var object + * @var array */ - protected $CPT = null; + protected array $CPT; /** - * @param array $arguments + * @param WP_Query $wp_query + * @param array $CPT */ - public function __construct(array $arguments = []) + public function __construct(WP_Query $wp_query, array $CPT = []) { - $this->CPT = $arguments['CPT'] ?? null; + $this->CPT = $CPT; } diff --git a/core/CPTs/EE_CPT_Event_Strategy.core.php b/core/CPTs/EE_CPT_Event_Strategy.core.php index 40aef82c4ce..48762b6cb39 100644 --- a/core/CPTs/EE_CPT_Event_Strategy.core.php +++ b/core/CPTs/EE_CPT_Event_Strategy.core.php @@ -3,7 +3,7 @@ use EventEspresso\core\domain\entities\custom_post_types\EspressoPostType; /** - *EE_CPT_Event_Strategy + * EE_CPT_Event_Strategy * * @package Event Espresso * @subpackage /core/CPTs/EE_CPT_Event_Strategy.core.php @@ -18,19 +18,32 @@ class EE_CPT_Event_Strategy */ protected $CPT; + private string $current_time; + + private string $datetime_table; + + private string $event_table; + + private string $event_table_pk; + + public EE_Template_Config $template_settings; + /** - * @param array|WP_Query|null $wp_query - * @param array $CPT + * @param WP_Query $wp_query + * @param array $CPT + * @param EE_Template_Config $template_settings + * @throws EE_Error + * @throws ReflectionException */ - public function __construct($wp_query, array $CPT = []) + public function __construct(WP_Query $wp_query, array $CPT, EE_Template_Config $template_settings) { - if (is_array($wp_query) && $wp_query['WP_Query'] instanceof WP_Query) { - $this->CPT = $wp_query['CPT'] ?? $CPT; - $wp_query = $wp_query['WP_Query']; - } else { - $this->CPT = $CPT; - } + $this->CPT = $CPT; + $this->current_time = current_time('mysql', true); + $this->datetime_table = EEM_Datetime::instance()->table(); + $this->event_table = EEM_Event::instance()->table(); + $this->event_table_pk = EEM_Event::instance()->primary_key_name(); + $this->template_settings = $template_settings; // !!!!!!!!!! IMPORTANT !!!!!!!!!!!! // here's the list of available filters in the WP_Query object @@ -44,15 +57,13 @@ public function __construct($wp_query, array $CPT = []) // 'posts_fields' // 'posts_join' $this->_add_filters(); - if ($wp_query instanceof WP_Query) { - $wp_query->is_espresso_event_single = is_singular() - && ( - (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::EVENTS) - || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::EVENTS) - ); - $wp_query->is_espresso_event_archive = is_post_type_archive(EspressoPostType::EVENTS); - $wp_query->is_espresso_event_taxonomy = is_tax('espresso_event_categories'); - } + $wp_query->is_espresso_event_single = is_singular() + && ( + (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::EVENTS) + || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::EVENTS) + ); + $wp_query->is_espresso_event_archive = is_post_type_archive(EspressoPostType::EVENTS); + $wp_query->is_espresso_event_taxonomy = is_tax('espresso_event_categories'); } @@ -69,6 +80,7 @@ protected function _add_filters() // add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 ); add_filter('posts_orderby', [$this, 'posts_orderby'], 1, 2); add_filter('posts_groupby', [$this, 'posts_groupby'], 1, 2); + add_action('the_post', [$this, 'the_post'], 1); } @@ -83,169 +95,169 @@ public function remove_filters() /** - * @param string $SQL - * @param WP_Query|null $wp_query + * @param string $SQL + * @param WP_Query $wp_query * @return string - * @throws EE_Error - * @throws ReflectionException + * @noinspection PhpUndefinedFieldInspection */ - public function posts_fields(string $SQL, ?WP_Query $wp_query): string + public function posts_fields(string $SQL, WP_Query $wp_query): string { - if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::EVENTS) { - return $SQL; - } - if ( - $wp_query instanceof WP_Query - && ( + ( $wp_query->is_espresso_event_single || $wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy ) + && $this->isEspressoEvent($wp_query) + && strpos($SQL, $this->datetime_table) === false ) { // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement - $SQL .= ', ' . EEM_Datetime::instance()->table() . '.* '; + $SQL .= ", $this->datetime_table.* "; if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) { // because we only want to retrieve the next upcoming datetime for each event: // add something like: // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date " // to WP Query SELECT statement - $SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; + $SQL .= ", MIN( $this->datetime_table.DTT_EVT_start ) as event_start_date "; } - remove_filter('posts_fields', [$this, 'posts_fields'], 1); } return $SQL; } /** - * @param string $SQL - * @param WP_Query|null $wp_query + * @param string $SQL + * @param WP_Query $wp_query * @return string - * @throws EE_Error - * @throws ReflectionException + * @noinspection PhpUndefinedFieldInspection */ - public function posts_join(string $SQL, ?WP_Query $wp_query): string + public function posts_join(string $SQL, WP_Query $wp_query): string { - if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::EVENTS) { - return $SQL; - } if ( - $wp_query instanceof WP_Query - && ( + ( $wp_query->is_espresso_event_single || $wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy ) + && $this->isEspressoEvent($wp_query) + && strpos($SQL, $this->datetime_table) === false ) { // adds something like: // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) " // to WP Query JOIN statement - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table() - . '.ID = ' . EEM_Datetime::instance()->table() . '.' - . EEM_Event::instance()->primary_key_name() . ' ) '; - remove_filter('posts_join', [$this, 'posts_join'], 1); + $SQL .= " INNER JOIN $this->datetime_table"; + $SQL .= " ON ( $this->event_table.ID = $this->datetime_table.$this->event_table_pk ) "; } return $SQL; } /** - * @param string $SQL - * @param WP_Query|null $wp_query + * @param string $SQL + * @param WP_Query $wp_query * @return string - * @throws EE_Error - * @throws ReflectionException + * @noinspection PhpUndefinedFieldInspection */ - public function posts_where(string $SQL, ?WP_Query $wp_query): string + public function posts_where(string $SQL, WP_Query $wp_query): string { - if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::EVENTS) { - return $SQL; - } if ( - $wp_query instanceof WP_Query - && ( + ( $wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy ) + && $this->isEspressoEvent($wp_query) + && strpos($SQL, $this->datetime_table) === false ) { if ( - ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive) - || ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events) - || ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events + ! isset($this->template_settings->EED_Events_Archive) + || ! isset($this->template_settings->EED_Events_Archive->display_expired_events) + || ! $this->template_settings->EED_Events_Archive->display_expired_events ) { - $SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '" - . current_time('mysql', true) . "' "; + $SQL .= " AND $this->datetime_table.DTT_EVT_end > '$this->current_time' "; } // exclude trashed datetimes - $SQL .= ' AND ' . EEM_Datetime::instance()->table() . '.DTT_deleted = 0'; - remove_filter('posts_where', [$this, 'posts_where']); + $SQL .= " AND $this->datetime_table.DTT_deleted = 0"; } return $SQL; } /** - * @param string $SQL - * @param WP_Query|null $wp_query + * @param string $SQL + * @param WP_Query $wp_query * @return string + * @noinspection PhpUndefinedFieldInspection */ - public function posts_orderby(string $SQL, ?WP_Query $wp_query): string + public function posts_orderby(string $SQL, WP_Query $wp_query): string { - if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::EVENTS) { - return $SQL; - } - if ( - $wp_query instanceof WP_Query - && ( + ( $wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy ) + && $this->isEspressoEvent($wp_query) + && strpos($SQL, 'event_start_date') === false ) { $SQL = ' event_start_date ASC '; - remove_filter('posts_orderby', [$this, 'posts_orderby'], 1); } return $SQL; } /** - * @param string $SQL - * @param WP_Query|null $wp_query + * @param string $SQL + * @param WP_Query $wp_query * @return string + * @noinspection PhpUndefinedFieldInspection */ - public function posts_groupby(string $SQL, ?WP_Query $wp_query): string + public function posts_groupby(string $SQL, WP_Query $wp_query): string { - if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::EVENTS) { - return $SQL; - } + global $wpdb; if ( - $wp_query instanceof WP_Query - && ( - $wp_query->is_espresso_event_archive + ( + $wp_query->is_espresso_event_single + || $wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy ) + && $this->isEspressoEvent($wp_query) + && strpos($SQL, "$wpdb->posts.ID") === false ) { // TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default) // we're joining to the datetimes table, where there can be MANY datetimes for a single event, // but we want to only show each event only once // (whereas if we didn't group them by the post's ID, then we would end up with many repeats) - global $wpdb; - $SQL = $wpdb->posts . '.ID '; - remove_filter('posts_groupby', [$this, 'posts_groupby'], 1); + $SQL = "$wpdb->posts.ID "; } return $SQL; } /** - * @param array $posts - * @param WP_Query|null $wp_query + * @param array $posts + * @param WP_Query $wp_query * @return array */ - public function the_posts(array $posts, ?WP_Query $wp_query): array + public function the_posts(array $posts, WP_Query $wp_query): array { return $posts; } + + + /** + * @param WP_Post $post The Post object (passed by reference). + * @throws EE_Error + * @throws ReflectionException + */ + public function the_post(WP_Post &$post) + { + if ($post->post_type === EspressoPostType::EVENTS && ! isset($post->EE_Event)) { + $post->EE_Event = EEM_Event::instance()->get_one_by_ID($post->ID); + } + } + + + private function isEspressoEvent(WP_Query $wp_query): bool + { + return EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) === EspressoPostType::EVENTS; + } } diff --git a/core/CPTs/EE_CPT_Strategy.core.php b/core/CPTs/EE_CPT_Strategy.core.php index 56b81ee995a..612e638ced1 100644 --- a/core/CPTs/EE_CPT_Strategy.core.php +++ b/core/CPTs/EE_CPT_Strategy.core.php @@ -115,8 +115,11 @@ private function _set_CPT_endpoints(): array } - public function wpQueryPostType(WP_Query $wp_query): string + public function wpQueryPostType(?WP_Query $wp_query): string { + if (! $wp_query instanceof WP_Query) { + return ''; + } $post_type = $wp_query->query->post_type ?? ''; $post_type = $post_type === '' && isset($wp_query->query['post_type']) ? $wp_query->query['post_type'] : ''; return is_array($post_type) ? (string) reset($post_type) : (string) $post_type; @@ -142,10 +145,6 @@ public function isEspressoPostType(WP_Query $wp_query): bool */ public function pre_get_posts(WP_Query $wp_query) { - // check that post-type is one of ours - if (! $this->isEspressoPostType($wp_query)) { - return; - } // add our conditionals $this->_set_EE_tags_on_WP_Query($wp_query); // check for terms @@ -210,10 +209,10 @@ private function _set_post_type_for_terms(WP_Query $wp_query) if (! $term instanceof EE_Term) { return; } - $term->post_type = array_merge(['post', 'page'], (array) $term->post_type); - $term->post_type = apply_filters( + // set post_type from term + $term->post_type = (array) apply_filters( 'FHEE__EE_CPT_Strategy___set_post_type_for_terms__term_post_type', - $term->post_type, + array_merge(['post', 'page'], $term->post_type), $term ); // if a post type is already set @@ -328,7 +327,10 @@ protected function _process_WP_Query_post_types(WP_Query $wp_query) */ protected function _generate_CptQueryModifier(WP_Query $wp_query, string $post_type) { - if ($this->query_modifier[ $post_type ] instanceof CptQueryModifier) { + if ( + isset($this->query_modifier[ $post_type ]) + && $this->query_modifier[ $post_type ] instanceof CptQueryModifier + ) { return; } $this->query_modifier[ $post_type ] = LoaderFactory::getLoader()->getShared( diff --git a/core/CPTs/EE_CPT_Venue_Strategy.core.php b/core/CPTs/EE_CPT_Venue_Strategy.core.php index 5eaaf198201..cfc96684644 100644 --- a/core/CPTs/EE_CPT_Venue_Strategy.core.php +++ b/core/CPTs/EE_CPT_Venue_Strategy.core.php @@ -14,24 +14,19 @@ class EE_CPT_Venue_Strategy /** * $CPT - the current page, if it utilizes CPTs * - * @var array|null + * @var array */ - protected ?array $CPT = null; + protected array $CPT; /** - * @param array|WP_Query|null $wp_query - * @param array $CPT + * @param WP_Query $wp_query + * @param array $CPT */ - public function __construct($wp_query, array $CPT = []) + public function __construct(WP_Query $wp_query, array $CPT = []) { - if (is_array($wp_query) && $wp_query['WP_Query'] instanceof WP_Query) { - $this->CPT = $wp_query['CPT'] ?? $CPT; - $wp_query = $wp_query['WP_Query']; - } else { - $this->CPT = $CPT; - } - if ($wp_query instanceof WP_Query && ! $wp_query->is_tag) { + $this->CPT = $CPT; + if (! $wp_query->is_tag) { $wp_query->is_espresso_venue_single = is_singular() && ( (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::VENUES) diff --git a/core/EE_Dependency_Map.core.php b/core/EE_Dependency_Map.core.php index 92f405219cb..5c174d2e46c 100644 --- a/core/EE_Dependency_Map.core.php +++ b/core/EE_Dependency_Map.core.php @@ -882,6 +882,11 @@ protected function _register_core_dependencies() 'EventEspresso\core\services\request\sanitizers\RequestSanitizer' => [ 'EventEspresso\core\domain\services\validation\email\strategies\Basic' => EE_Dependency_Map::load_from_cache, ], + 'EE_CPT_Event_Strategy' => [ + null, + null, + 'EE_Template_Config' => EE_Dependency_Map::load_from_cache, + ], ]; } diff --git a/core/EE_System.core.php b/core/EE_System.core.php index b9555f73fd2..015fbb7e8f7 100644 --- a/core/EE_System.core.php +++ b/core/EE_System.core.php @@ -1098,8 +1098,6 @@ public function load_CPTs_and_session() $this->register_custom_taxonomies->registerCustomTaxonomies(); $this->register_custom_post_types->registerCustomPostTypes(); $this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms(); - // load legacy Custom Post Types and Taxonomies - $this->loader->getShared('EE_Register_CPTs'); do_action('AHEE__EE_System__load_CPTs_and_session__complete'); } diff --git a/core/admin/EE_Admin_Page.core.php b/core/admin/EE_Admin_Page.core.php index 70e0ba9182e..c3b91baf345 100644 --- a/core/admin/EE_Admin_Page.core.php +++ b/core/admin/EE_Admin_Page.core.php @@ -4,7 +4,6 @@ use EventEspresso\core\domain\services\assets\EspressoLegacyAdminAssetManager; use EventEspresso\core\domain\services\assets\JqueryAssetManager; use EventEspresso\core\domain\services\capabilities\FeatureFlags; -use EventEspresso\core\exceptions\ExceptionStackTraceDisplay; use EventEspresso\core\exceptions\InvalidDataTypeException; use EventEspresso\core\exceptions\InvalidInterfaceException; use EventEspresso\core\interfaces\InterminableInterface; @@ -334,7 +333,7 @@ abstract protected function _define_page_props(); /** * _set_page_routes * child classes use this to define the page routes for all subpages handled by the class. Page routes are - * assigned to a action => method pairs in an array and to the $_page_routes property. Each page route must also + * assigned to an action => method pairs in an array and to the $_page_routes property. Each page route must also * have a 'default' route. Here's the format * $this->_page_routes = array( * 'default' => array( @@ -394,13 +393,13 @@ abstract protected function _set_page_routes(); * given route has help popups setup and if it does then we need to make sure thickbox is enqueued. * 'columns' => array(4, 2), //this key triggers the setup of a page that uses columns (metaboxes). The * array indicates the max number of columns (4) and the default number of columns on page load (2). - * There is an option in the "screen_options" dropdown that is setup so users can pick what columns they + * There is an option in the "screen_options" dropdown that is set up so users can pick what columns they * want to display. * 'help_tabs' => array( //this is used for adding help tabs to a page * 'tab_id' => array( * 'title' => 'tab_title', * 'filename' => 'name_of_file_containing_content', //this is the primary method for setting - * help tab content. The fallback if it isn't present is to try a the callback. Filename + * help tab content. The fallback if it isn't present is to try the callback. Filename * should match a file in the admin folder's "help_tabs" dir (ie.. * events/help_tabs/name_of_file_containing_content.help_tab.php) * 'callback' => 'callback_method_for_content', //if 'filename' isn't present then system will @@ -439,7 +438,7 @@ abstract protected function _add_screen_options(); * Child classes should use this method for implementing any "feature pointers" (using built-in WP styling js). * Note child classes can also define _add_feature_pointers_($this->_current_view) to limit screen options to a * particular view. Note: this is just a placeholder for now. Implementation will come down the road See: - * WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be + * WP_Internal_Pointers class in wp-admin/includes/template.php for example (it's a final class so can't be * extended) also see: * * @link http://eamann.com/tech/wordpress-portland/ @@ -551,8 +550,7 @@ public function hideStatusChangeNotice() } catch (Exception $exception) { $response['errors'] = $exception->getMessage(); } - echo wp_json_encode($response); - exit(); + wp_send_json($response); } @@ -701,7 +699,7 @@ private function _do_other_page_hooks() { $registered_pages = apply_filters('FHEE_do_other_page_hooks_' . $this->page_slug, []); foreach ($registered_pages as $page) { - // now let's setup the file name and class that should be present + // now let's set up the file name and class that should be present $classname = str_replace('.class.php', '', $page); // autoloaders should take care of loading file if (! class_exists($classname)) { @@ -753,7 +751,7 @@ public function load_page_dependencies() /** * load_page_dependencies - * loads things specific to this page class when its loaded. Really helps with efficiency. + * loads things specific to this page class when it's loaded. Really helps with efficiency. * * @return void * @throws DomainException @@ -974,7 +972,7 @@ protected function _verify_routes(): bool // first lets' catch if the UI request has EVER been set. if ($this->_is_UI_request === null) { - // lets set if this is a UI request or not. + // let's set if this is a UI request or not. $this->_is_UI_request = ! $this->request->getRequestParam('noheader', false, DataType::BOOL); // wait a minute... we might have a noheader in the route array $this->_is_UI_request = ! (isset($this->_route['noheader']) && $this->_route['noheader']) @@ -987,7 +985,7 @@ protected function _verify_routes(): bool /** - * this method simply verifies a given route and makes sure its an actual route available for the loaded page + * this method simply verifies a given route and makes sure it's an actual route available for the loaded page * * @param string $route the route name we're verifying * @return bool we'll throw an exception if this isn't a valid route. @@ -1206,11 +1204,11 @@ protected function _reset_routing_properties(string $new_route) * $some_url, * true * ); - * It will produce a url in this structure: + * It will produce a URL in this structure: * http://{$some_url}/?page=espresso_registrations&action=resend_something * &wp_referer[action]=default&wp_referer[event_id]=20&wpreferer[ * month_range]=March%202015 - * @param bool $exclude_nonce If true, the the nonce will be excluded from the generated nonce. + * @param bool $exclude_nonce If true, the nonce will be excluded from the generated nonce. * @param int $context * @return string */ @@ -1281,7 +1279,7 @@ protected function _add_help_tabs() throw new EE_Error( sprintf( esc_html__( - 'The _page_config array has a callback set for the "help_sidebar" option. However the callback given (%s) is not a valid callback. Doublecheck the spelling and make sure this method exists for the class %s', + 'The _page_config array has a callback set for the "help_sidebar" option. However the callback given (%s) is not a valid callback. Double check the spelling and make sure this method exists for the class %s', 'event_espresso' ), $config['help_sidebar'], @@ -1329,7 +1327,7 @@ protected function _add_help_tabs() . '/help_tabs/' . $cfg['filename'] . '.help_tab.php' : $file_path; - // if file is STILL not readable then let's do a EE_Error so its more graceful than a fatal error. + // if file is STILL not readable then let's do an EE_Error so its more graceful than a fatal error. if (! isset($cfg['callback']) && ! is_readable($file_path)) { EE_Error::add_error( sprintf( @@ -1689,7 +1687,7 @@ public function admin_footer_global() * 'content' => esc_html__('localized content for popup', 'event_espresso') * ) * ); - * Then the EE_Admin_Parent will take care of making sure that is setup properly on the correct route. + * Then the EE_Admin_Parent will take care of making sure that is set up properly on the correct route. * * @param array $help_array * @param bool $display @@ -1703,7 +1701,7 @@ protected function _set_help_popup_content(array $help_array = [], bool $display $help_array = empty($help_array) ? $this->_get_help_content() : $help_array; // loop through the array and setup content foreach ($help_array as $trigger => $help) { - // make sure the array is setup properly + // make sure the array is set up properly if (! isset($help['title'], $help['content'])) { throw new EE_Error( esc_html__( @@ -1712,7 +1710,7 @@ protected function _set_help_popup_content(array $help_array = [], bool $display ) ); } - // we're good so let's setup the template vars and then assign parsed template content to our content. + // we're good so let's set up the template vars and then assign parsed template content to our content. $template_args = [ 'help_popup_id' => $trigger, 'help_popup_title' => $help['title'], @@ -1830,7 +1828,7 @@ private function _add_global_screen_options() * This particular method will implement feature pointers for ALL EE_Admin pages. * Note: this is just a placeholder for now. Implementation will come down the road * - * @see WP_Internal_Pointers class in wp-admin/includes/template.php for example (its a final class so can't be + * @see WP_Internal_Pointers class in wp-admin/includes/template.php for example (it's a final class so can't be * extended) also see: * @link http://eamann.com/tech/wordpress-portland/ * @abstract @@ -2212,7 +2210,7 @@ private function _add_registered_meta_boxes() /** * _add_screen_columns * This will check the _page_config array and if there is "columns" key index indicated, we'll set the template as - * the dynamic column template and we'll setup the column options for the page. + * the dynamic column template and we'll set up the column options for the page. * * @return void */ @@ -2242,7 +2240,7 @@ private function _add_screen_columns() $this->_column_template_path = EE_ADMIN_TEMPLATE . 'admin_details_metabox_column_wrapper.template.php'; // finally if we don't have has_metaboxes set in the route config - // let's make sure it IS set other wise the necessary hidden fields for this won't be loaded. + // let's make sure it IS set otherwise the necessary hidden fields for this won't be loaded. $this->_route_config['has_metaboxes'] = true; } } @@ -2752,7 +2750,7 @@ public function display_about_admin_page() * contains the code for actually displaying an admin page * * @param bool $sidebar true with sidebar, false without - * @param bool $about use the about admin wrapper instead of the default. + * @param bool $about use the About admin wrapper instead of the default. * @return void * @throws DomainException * @throws EE_Error @@ -2823,7 +2821,7 @@ private function _display_admin_page(bool $sidebar = false, bool $about = false) /** * This is used to display caf preview pages. * - * @param string $utm_campaign_source what is the key used for google analytics link + * @param string $utm_campaign_source what is the key used for Google Analytics link * @param bool $display_sidebar whether to use the sidebar template or the full template for the page. TRUE * = SHOW sidebar, FALSE = no sidebar. Default no sidebar. * @return void @@ -3248,7 +3246,7 @@ protected function _generate_admin_form_fields( * @param array $actions if included allows us to set the actions that each button will carry out (i.e. * via the "name" value in the button). We can also use this to just dump * default actions by submitting some other value. - * @param bool|string|null $referrer if false then we just do the default action on save and close. Other wise it + * @param bool|string|null $referrer if false then we just do the default action on save and close. Otherwise it * will use the $referrer string. IF null, then we don't do ANYTHING on save and * close (normal form handling). */ @@ -3760,7 +3758,7 @@ public function setAdminPageTitle(string $title) * * @param string $route the route that should receive the transient * @param array $data the data that gets sent - * @param bool $notices If this is for notices then we use this to indicate so, otherwise its just a + * @param bool $notices If this is for notices then we use this to indicate so, otherwise it's just a * normal route transient. * @param bool $skip_route_verify Used to indicate we want to skip route verification. This is usually ONLY used * when we are adding a transient before page_routes have been defined. @@ -4092,7 +4090,7 @@ protected function _previous_link(string $url, string $class = 'dashicons dashic /** - * This processes an request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller + * This processes a request to resend a registration and assumes we have a _REG_ID for doing so. So if the caller * knows that the _REG_ID isn't in the req_data array but CAN obtain it, the caller should ADD the _REG_ID to the * _req_data array. * diff --git a/core/admin/EE_Admin_Page_CPT.core.php b/core/admin/EE_Admin_Page_CPT.core.php index 777a092a754..3683bedd9f9 100644 --- a/core/admin/EE_Admin_Page_CPT.core.php +++ b/core/admin/EE_Admin_Page_CPT.core.php @@ -1158,7 +1158,7 @@ public function revision_redirect(string $location): string /** * Modify the edit post link generated by wp core function so that EE CPTs get setup differently. * - * @param null|string $link the original generated link + * @param string|null $link the original generated link * @param int $id post id * @return string the link */ @@ -1185,7 +1185,7 @@ public function modify_edit_post_link(?string $link, int $id): ?string * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on * our routes. * - * @param null|string $delete_link original delete link + * @param string|null $delete_link original delete link * @param int $post_id id of cpt object * @return null|string new delete link * @throws EE_Error diff --git a/core/db_classes/EE_Term.class.php b/core/db_classes/EE_Term.class.php index eab3392e845..6fc360e0d42 100644 --- a/core/db_classes/EE_Term.class.php +++ b/core/db_classes/EE_Term.class.php @@ -3,15 +3,14 @@ /** * EE_Term class * - * @package Event Espresso - * @subpackage includes/classes/EE_Term.class.php - * @author Mike Nelson - * - * ------------------------------------------------------------------------ + * @package Event Espresso + * @subpackage includes/classes/EE_Term.class.php + * @author Mike Nelson */ class EE_Term extends EE_Base_Class { - public $post_type; + public array $post_type = []; + /** * Sets some dynamic defaults @@ -19,8 +18,10 @@ class EE_Term extends EE_Base_Class * @param array $fieldValues * @param bool $bydb * @param string $timezone + * @throws EE_Error + * @throws ReflectionException */ - protected function __construct($fieldValues = array(), $bydb = false, $timezone = '') + protected function __construct($fieldValues = [], $bydb = false, $timezone = '') { if (! isset($fieldValues['slug'])) { $fieldValues['slug'] = $fieldValues['name']; @@ -31,20 +32,24 @@ protected function __construct($fieldValues = array(), $bydb = false, $timezone /** * @param array $props_n_values - * @return EE_Term|mixed + * @return EE_Term|null + * @throws EE_Error + * @throws ReflectionException */ - public static function new_instance($props_n_values = array()) + public static function new_instance(array $props_n_values = []): ?EE_Term { $has_object = parent::_check_for_object($props_n_values, __CLASS__); - return $has_object ? $has_object : new self($props_n_values); + return $has_object ?: new self($props_n_values); } /** * @param array $props_n_values - * @return EE_Term + * @return EE_Term|null + * @throws EE_Error + * @throws ReflectionException */ - public static function new_instance_from_db($props_n_values = array()) + public static function new_instance_from_db(array $props_n_values = []): ?EE_Term { return new self($props_n_values, true); } @@ -54,10 +59,12 @@ public static function new_instance_from_db($props_n_values = array()) * Gets name * * @return string + * @throws EE_Error + * @throws ReflectionException */ - public function name() + public function name(): string { - return $this->get('name'); + return (string) $this->get('name'); } @@ -65,9 +72,10 @@ public function name() * Sets name * * @param string $name - * @return boolean + * @throws EE_Error + * @throws ReflectionException */ - public function set_name($name) + public function set_name(string $name) { $this->set('name', $name); } @@ -77,10 +85,12 @@ public function set_name($name) * Gets slug * * @return string + * @throws EE_Error + * @throws ReflectionException */ - public function slug() + public function slug(): string { - return $this->get('slug'); + return (string) $this->get('slug'); } @@ -88,9 +98,10 @@ public function slug() * Sets slug * * @param string $slug - * @return boolean + * @throws EE_Error + * @throws ReflectionException */ - public function set_slug($slug) + public function set_slug(string $slug) { $this->set('slug', $slug); } diff --git a/core/db_models/EEM_Base.model.php b/core/db_models/EEM_Base.model.php index 55c054b8480..6114c5502bc 100644 --- a/core/db_models/EEM_Base.model.php +++ b/core/db_models/EEM_Base.model.php @@ -1,5 +1,6 @@ get_formats_for($field_name); // load EEH_DTT_Helper - $set_timezone = empty($timezone) - ? EEH_DTT_Helper::get_timezone() - : $timezone; - $incomingDateTime = date_create_from_format($incoming_format, $timestring, new DateTimeZone($set_timezone)); + $timezone_string = ! empty($timezone_string) ? $timezone_string : EEH_DTT_Helper::get_timezone(); + $incomingDateTime = date_create_from_format($incoming_format, $timestring, new DateTimeZone($timezone_string)); EEH_DTT_Helper::setTimezone($incomingDateTime, new DateTimeZone($this->_timezone)); - return \EventEspresso\core\domain\entities\DbSafeDateTime::createFromDateTime($incomingDateTime); + return DbSafeDateTime::createFromDateTime($incomingDateTime); } diff --git a/core/domain/entities/custom_post_types/CustomPostTypeDefinitions.php b/core/domain/entities/custom_post_types/CustomPostTypeDefinitions.php index bcb88985419..1290312d5ab 100644 --- a/core/domain/entities/custom_post_types/CustomPostTypeDefinitions.php +++ b/core/domain/entities/custom_post_types/CustomPostTypeDefinitions.php @@ -16,33 +16,18 @@ */ class CustomPostTypeDefinitions { - /** - * @var string $namespace The graphql namespace/prefix. - */ - protected $namespace = 'Espresso'; + public EE_Core_Config $core_config; - /** - * @var EE_Core_Config - */ - public $core_config; + private array $custom_post_types; - /** - * @var array $custom_post_types - */ - private $custom_post_types; + private LoaderInterface $loader; /** - * @var LoaderInterface $loader + * The graphql namespace/prefix. */ - private $loader; + protected string $namespace = 'Espresso'; - /** - * EspressoCustomPostTypeDefinitions constructor. - * - * @param EE_Core_Config $core_config - * @param LoaderInterface $loader - */ public function __construct(EE_Core_Config $core_config, LoaderInterface $loader) { $this->core_config = $core_config; @@ -184,31 +169,25 @@ private function setDefinitions() } - /** - * @return array - */ - public function getDefinitions() + public function getDefinitions(): array { return $this->custom_post_types; } - /** - * @return array - */ - public function getCustomPostTypeSlugs() + public function getCustomPostTypeSlugs(): array { return array_keys($this->getDefinitions()); } /** - * This basically goes through the CPT array and returns only CPT's + * This basically goes through the CPT array and returns only CPTs * that have the ['args']['public'] option set as false * * @return array */ - public function getPrivateCustomPostTypes() + public function getPrivateCustomPostTypes(): array { $private_CPTs = []; foreach ($this->getDefinitions() as $CPT => $details) { @@ -230,7 +209,7 @@ public function getPrivateCustomPostTypes() * @return array Empty array if no matching model names for the given slug * or an array of model names indexed by post type slug. */ - public function getCustomPostTypeModelNames($post_type_slug = '') + public function getCustomPostTypeModelNames(string $post_type_slug = ''): array { $cpts = $this->getDefinitions(); // first if slug passed in... @@ -260,12 +239,7 @@ public function getCustomPostTypeModelNames($post_type_slug = '') } - /** - * @param $post_type_slug - * @param array $cpt - * @return array - */ - private function getCustomPostTypeModelName($post_type_slug, array $cpt) + private function getCustomPostTypeModelName(string $post_type_slug, array $cpt): array { if (! empty($cpt['model_name'])) { return [$post_type_slug => $cpt['model_name']]; @@ -279,11 +253,7 @@ private function getCustomPostTypeModelName($post_type_slug, array $cpt) } - /** - * @param string $class_name - * @return string - */ - private function deriveCptModelNameFromClassName($class_name) + private function deriveCptModelNameFromClassName(string $class_name): string { return str_replace('EE', 'EEM', $class_name); } @@ -299,7 +269,7 @@ private function deriveCptModelNameFromClassName($class_name) * EEM models indexed by post slug. * @since 4.6.16.rc.000 */ - public function getCustomPostTypeModels($post_type_slug = '') + public function getCustomPostTypeModels(string $post_type_slug = ''): array { $cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug); $instantiated = []; diff --git a/core/domain/entities/custom_post_types/CustomTaxonomyDefinitions.php b/core/domain/entities/custom_post_types/CustomTaxonomyDefinitions.php index f82fc2f5db1..3024c42643a 100644 --- a/core/domain/entities/custom_post_types/CustomTaxonomyDefinitions.php +++ b/core/domain/entities/custom_post_types/CustomTaxonomyDefinitions.php @@ -14,97 +14,88 @@ */ class CustomTaxonomyDefinitions { - /** - * @var array $taxonomies - */ - private $taxonomies; + private array $taxonomies = []; - /** - * EspressoCustomPostTypeDefinitions constructor. - */ public function __construct() { $this->setTaxonomies(); - add_filter('pre_term_description', array($this, 'filterCustomTermDescription'), 1, 2); + add_filter('pre_term_description', [$this, 'filterCustomTermDescription'], 1, 2); } private function setTaxonomies() { - $this->taxonomies = array( - 'espresso_event_categories' => array( + $this->taxonomies = [ + 'espresso_event_categories' => [ 'singular_name' => esc_html__('Event Category', 'event_espresso'), 'plural_name' => esc_html__('Event Categories', 'event_espresso'), - 'args' => array( + 'args' => [ 'public' => true, 'show_in_nav_menus' => true, 'show_in_rest' => true, - 'capabilities' => array( + 'capabilities' => [ 'manage_terms' => 'ee_manage_event_categories', 'edit_terms' => 'ee_edit_event_category', 'delete_terms' => 'ee_delete_event_category', 'assign_terms' => 'ee_assign_event_category', - ), - 'rewrite' => array( + ], + 'rewrite' => [ 'slug' => EEH_URL::slugify( esc_html__('event-category', 'event_espresso'), 'event-category' - ) - ), - ), - ), - 'espresso_venue_categories' => array( + ), + ], + ], + ], + 'espresso_venue_categories' => [ 'singular_name' => esc_html__('Venue Category', 'event_espresso'), 'plural_name' => esc_html__('Venue Categories', 'event_espresso'), - 'args' => array( + 'args' => [ 'public' => true, 'show_in_nav_menus' => false, // by default this doesn't show for decaf 'show_in_rest' => true, - 'capabilities' => array( + 'capabilities' => [ 'manage_terms' => 'ee_manage_venue_categories', 'edit_terms' => 'ee_edit_venue_category', 'delete_terms' => 'ee_delete_venue_category', 'assign_terms' => 'ee_assign_venue_category', - ), - 'rewrite' => array( + ], + 'rewrite' => [ 'slug' => EEH_URL::slugify( esc_html__('venue-category', 'event_espresso'), 'venue-category' - ) - ), - ), - ), - 'espresso_event_type' => array( + ), + ], + ], + ], + 'espresso_event_type' => [ 'singular_name' => esc_html__('Event Type', 'event_espresso'), 'plural_name' => esc_html__('Event Types', 'event_espresso'), - 'args' => array( + 'args' => [ 'public' => true, 'show_ui' => false, 'show_in_rest' => true, - 'capabilities' => array( + 'capabilities' => [ 'manage_terms' => 'ee_read_event_type', 'edit_terms' => 'ee_edit_event_type', 'delete_terms' => 'ee_delete_event_type', 'assign_terms' => 'ee_assign_event_type', - ), - 'rewrite' => array( + ], + 'rewrite' => [ 'slug' => EEH_URL::slugify( esc_html__('event-type', 'event_espresso'), 'event-type' - ) - ), + ), + ], 'hierarchical' => true, - ), - ), - ); + ], + ], + ]; } - /** - * @return array - */ - public function getCustomTaxonomyDefinitions() + public function getCustomTaxonomyDefinitions(): array { return (array) apply_filters( 'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies', @@ -118,10 +109,7 @@ public function getCustomTaxonomyDefinitions() } - /** - * @return array - */ - public function getCustomTaxonomySlugs() + public function getCustomTaxonomySlugs(): array { return array_keys($this->getCustomTaxonomyDefinitions()); } @@ -142,7 +130,7 @@ public function getCustomTaxonomySlugs() * @param string $taxonomy The taxonomy name for the taxonomy being filtered. * @return string */ - public function filterCustomTermDescription($description, $taxonomy) + public function filterCustomTermDescription(string $description, string $taxonomy): string { // get a list of EE taxonomies $custom_taxonomies = $this->getCustomTaxonomySlugs(); diff --git a/core/domain/entities/custom_post_types/CustomTaxonomyTerm.php b/core/domain/entities/custom_post_types/CustomTaxonomyTerm.php index 56b3ea1b922..99a507afb15 100644 --- a/core/domain/entities/custom_post_types/CustomTaxonomyTerm.php +++ b/core/domain/entities/custom_post_types/CustomTaxonomyTerm.php @@ -12,59 +12,34 @@ */ class CustomTaxonomyTerm { - /** - * @var string $taxonomy_slug - */ - public $taxonomy_slug; + public string $taxonomy_slug; - /** - * @var string $term_slug - */ - public $term_slug; + public string $term_slug; - /** - * @var array $custom_post_type_slugs - */ - public $custom_post_type_slugs; + public array $custom_post_type_slugs; - /** - * CustomTaxonomyTerm constructor. - * - * @param string $taxonomy_slug - * @param string $term_slug - * @param array $custom_post_type_slugs - */ - public function __construct($taxonomy_slug, $term_slug, array $custom_post_type_slugs = array()) + public function __construct(string $taxonomy_slug, string $term_slug, array $custom_post_type_slugs = []) { - $this->taxonomy_slug = $taxonomy_slug; - $this->term_slug = $term_slug; + $this->taxonomy_slug = $taxonomy_slug; + $this->term_slug = $term_slug; $this->custom_post_type_slugs = $custom_post_type_slugs; } - /** - * @return string - */ - public function taxonomySlug() + public function taxonomySlug(): string { return $this->taxonomy_slug; } - /** - * @return string - */ - public function termSlug() + public function termSlug(): string { return $this->term_slug; } - /** - * @return array - */ - public function customPostTypeSlugs() + public function customPostTypeSlugs(): array { return $this->custom_post_type_slugs; } diff --git a/core/domain/services/admin/notices/status_change/StatusChangeNotice.php b/core/domain/services/admin/notices/status_change/StatusChangeNotice.php index 81378d9c3db..32ce6bfbd7c 100644 --- a/core/domain/services/admin/notices/status_change/StatusChangeNotice.php +++ b/core/domain/services/admin/notices/status_change/StatusChangeNotice.php @@ -18,7 +18,7 @@ class StatusChangeNotice extends WordPressOption { public function __construct() { - parent::__construct('ee_hide_status_change_notices_for_users', [], false); + parent::__construct('ee_hide_status_change_notices_for_users', []); } diff --git a/core/domain/services/admin/notices/status_change/status_change_notice.css b/core/domain/services/admin/notices/status_change/status_change_notice.css index d11ebe86f6e..1580d406dd3 100644 --- a/core/domain/services/admin/notices/status_change/status_change_notice.css +++ b/core/domain/services/admin/notices/status_change/status_change_notice.css @@ -74,6 +74,7 @@ margin: 0 .25rem 1rem; position: relative; transition: max-height 0.4s ease; + white-space: normal !important; } .espresso-events-page .ee-status-message, diff --git a/core/domain/services/admin/notices/status_change/status_change_notice.js b/core/domain/services/admin/notices/status_change/status_change_notice.js index 916189d74e0..b7b611962f0 100644 --- a/core/domain/services/admin/notices/status_change/status_change_notice.js +++ b/core/domain/services/admin/notices/status_change/status_change_notice.js @@ -81,6 +81,7 @@ jQuery(document).ready(function ($) { url: ajaxurl, data: { action: 'espresso_hide_status_change_notice', + page: 'espresso_maintenance_settings', ee_admin_ajax: 1 }, dataType: 'json', diff --git a/core/domain/services/admin/registrations/list_table/QueryBuilder.php b/core/domain/services/admin/registrations/list_table/QueryBuilder.php index 170baaf2c1c..5ed30036181 100644 --- a/core/domain/services/admin/registrations/list_table/QueryBuilder.php +++ b/core/domain/services/admin/registrations/list_table/QueryBuilder.php @@ -225,6 +225,7 @@ protected function addRegistrationStatusToWhereConditions() protected function addDateToWhereConditions() { $current_time = current_time('timestamp'); + $timezone_string = EEH_DTT_Helper::get_timezone(); if ($this->view === 'today') { $now = date('Y-m-d', $current_time); $this->where_params['REG_date'] = [ @@ -233,12 +234,14 @@ protected function addDateToWhereConditions() $this->registration_model->convert_datetime_for_query( 'REG_date', $now . ' 00:00:00', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), $this->registration_model->convert_datetime_for_query( 'REG_date', $now . ' 23:59:59', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), ], ]; @@ -252,12 +255,14 @@ protected function addDateToWhereConditions() $this->registration_model->convert_datetime_for_query( 'REG_date', $yesterday . ' 00:00:00', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), $this->registration_model->convert_datetime_for_query( 'REG_date', $yesterday . ' 23:59:59', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), ], ]; @@ -272,12 +277,14 @@ protected function addDateToWhereConditions() $this->registration_model->convert_datetime_for_query( 'REG_date', $current_year_and_month . '-01 00:00:00', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), $this->registration_model->convert_datetime_for_query( 'REG_date', $current_year_and_month . '-' . $days_this_month . ' 23:59:59', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), ], ]; @@ -303,12 +310,14 @@ protected function addDateToWhereConditions() $this->registration_model->convert_datetime_for_query( 'REG_date', $year_requested . '-' . $month_requested . '-01 00:00:00', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), $this->registration_model->convert_datetime_for_query( 'REG_date', $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59', - 'Y-m-d H:i:s' + 'Y-m-d H:i:s', + $timezone_string ), ], ]; diff --git a/core/helpers/EEH_Debug_Tools.helper.php b/core/helpers/EEH_Debug_Tools.helper.php index 458f6d94810..7333edbfa18 100644 --- a/core/helpers/EEH_Debug_Tools.helper.php +++ b/core/helpers/EEH_Debug_Tools.helper.php @@ -545,7 +545,9 @@ protected static function orange_span($content = '') */ protected static function pre_span($var) { - $var = var_export($var, true); + ob_start(); + var_dump($var); + $var = ob_get_clean(); if (EEH_Debug_Tools::plainOutput()) { return str_replace("\n", '', $var); } diff --git a/core/helpers/EEH_Event_View.helper.php b/core/helpers/EEH_Event_View.helper.php index 86560194869..20b87a9b99a 100644 --- a/core/helpers/EEH_Event_View.helper.php +++ b/core/helpers/EEH_Event_View.helper.php @@ -23,7 +23,7 @@ class EEH_Event_View extends EEH_Base * @throws EE_Error * @throws ReflectionException */ - public static function get_event($EVT_ID = 0) + public static function get_event($EVT_ID = 0): ?EE_Event { // international newspaper? global $post; @@ -58,6 +58,19 @@ public static function get_event($EVT_ID = 0) if (! EEH_Event_View::$_event instanceof EE_Event && $EVT_ID) { EEH_Event_View::$_event = EEM_Event::instance()->get_one_by_ID($EVT_ID); } + // no? ok let's try getting the event using the ID. + if (! EEH_Event_View::$_event instanceof EE_Event && $post->ID) { + $maybe_an_event = EEM_Event::instance()->get_one_by_ID($post->ID); + EEH_Event_View::$_event = $maybe_an_event instanceof EE_Event ? $maybe_an_event : EEH_Event_View::$_event; + } + // ensure Event object is added to WP post object + if ( + $post instanceof WP_Post + && $post->post_type === EspressoPostType::EVENTS + && EEH_Event_View::$_event instanceof EE_Event + ) { + $post->EE_Event = EEH_Event_View::$_event; + } return EEH_Event_View::$_event; } diff --git a/core/libraries/batch/JobHandlers/RegistrationsReport.php b/core/libraries/batch/JobHandlers/RegistrationsReport.php index f8d09b2a2b8..2e76d7c4c00 100644 --- a/core/libraries/batch/JobHandlers/RegistrationsReport.php +++ b/core/libraries/batch/JobHandlers/RegistrationsReport.php @@ -2,6 +2,8 @@ namespace EventEspresso\core\libraries\batch\JobHandlers; +use DateTimeZone; +use EEH_DTT_Helper; use EEH_Export; use EEH_File; use EEM_Base; @@ -19,6 +21,7 @@ use EE_Datetime; use EE_Error; use EE_Registry; +use EventEspresso\core\domain\entities\DbSafeDateTime; use EventEspresso\core\libraries\batch\Helpers\BatchRequestException; use EventEspresso\core\libraries\batch\Helpers\JobParameters; use EventEspresso\core\libraries\batch\Helpers\JobStepResponse; @@ -28,6 +31,7 @@ use EventEspresso\core\domain\services\admin\registrations\list_table\csv_reports\CheckinsCSV; use EventEspresso\core\domain\services\admin\registrations\list_table\csv_reports\PaymentsInfoCSV; use EventEspresso\core\domain\services\admin\registrations\list_table\csv_reports\RegistrationCSV; +use Exception; use ReflectionException; /** @@ -46,7 +50,7 @@ class RegistrationsReport extends JobHandlerFile // phpcs:disable PSR2.Methods.MethodDeclaration.Underscore /** * Performs any necessary setup for starting the job. This is also a good - * place to setup the $job_arguments which will be used for subsequent HTTP requests + * place to set up the $job_arguments which will be used for subsequent HTTP requests * when continue_job will be called * * @param JobParameters $job_parameters @@ -54,6 +58,7 @@ class RegistrationsReport extends JobHandlerFile * @throws BatchRequestException * @throws EE_Error * @throws ReflectionException + * @throws Exception */ public function create_job(JobParameters $job_parameters): JobStepResponse { @@ -110,7 +115,7 @@ public function create_job(JobParameters $job_parameters): JobStepResponse $return_url_args = []; parse_str( parse_url( - $job_parameters->request_datum('return_url', ''), + $job_parameters->request_datum('return_url'), PHP_URL_QUERY ), $return_url_args @@ -133,12 +138,16 @@ public function create_job(JobParameters $job_parameters): JobStepResponse $event_id ); + $utc_timezone = new DateTimeZone('UTC'); + $site_timezone = new DateTimeZone(EEH_DTT_Helper::get_timezone()); + $query_params = $this->convertDateStringsToObjects($query_params, $site_timezone, $utc_timezone); + $job_parameters->add_extra_data('query_params', $query_params); $question_labels = $this->_get_question_labels($query_params); $job_parameters->add_extra_data('question_labels', $question_labels); $job_parameters->set_job_size($this->count_units_to_process($query_params)); // we need to set the header columns - // but to do that we need to process one row so that we can extract ALL of the column headers + // but to do that we need to process one row so that we can extract ALL the column headers $csv_data_for_row = $this->get_csv_data_for( $event_id, 0, @@ -488,7 +497,7 @@ public function get_csv_data_for( $reg_csv_array = AnswersCSV::addAnswerColumns($reg_row, $reg_csv_array, $question_labels); // Include check-in data if ($event_id && $DTT_ID) { - // get whether or not the user has checked in + // get whether the user has checked in $reg_csv_array[ esc_html__('Datetime Check-ins #', 'event_espresso') ] = $reg_model->count_related( $reg_row['Registration.REG_ID'], @@ -519,7 +528,7 @@ public function get_csv_data_for( $datetime_name = CheckinsCSV::getDatetimeLabel($datetime); $reg_csv_array[ $datetime_name ] = implode(' --- ', $checkins); } elseif ($event_id) { - // get whether or not the user has checked in + // get whether the user has checked in $reg_csv_array[ esc_html__('Event Check-ins #', 'event_espresso') ] = $reg_model->count_related( $reg_row['Registration.REG_ID'], @@ -595,6 +604,35 @@ public function get_csv_data_for( } + /** + * recursively convert MySQL format date strings in query params array to Datetime objects + * + * @param array $query_params + * @param DateTimeZone $site_timezone + * @param DateTimeZone $utc_timezone + * @return array + * @throws Exception + * @since $VID:$ + */ + private function convertDateStringsToObjects( + array $query_params, + DateTimeZone $site_timezone, + DateTimeZone $utc_timezone + ): array { + foreach ($query_params as $key => $value) { + if (is_array($value)) { + $query_params[$key] = $this->convertDateStringsToObjects($value, $site_timezone, $utc_timezone); + continue; + } + if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) { + $query_params[$key] = DbSafeDateTime::createFromFormat('Y-m-d H:i:s', $value, $site_timezone); + $query_params[$key] = $query_params[$key]->setTimezone($utc_timezone); + } + } + return $query_params; + } + + /** * Counts total unit to process * diff --git a/core/templates/global_assets/css/espresso_default.css b/core/templates/global_assets/css/espresso_default.css index ac75144e90a..72543b879e0 100644 --- a/core/templates/global_assets/css/espresso_default.css +++ b/core/templates/global_assets/css/espresso_default.css @@ -285,31 +285,26 @@ .ee-icon-size-16, .ee-icon-size-16:before { font-size: 16px !important; - margin-right: -.002em; } .ee-icon-size-18, .ee-icon-size-18:before { font-size: 18px !important; - margin-right:-0.05em; } .ee-icon-size-20, .ee-icon-size-20:before { font-size: 20px !important; - margin-right: -0.1em; } .ee-icon-size-22, .ee-icon-size-22:before { font-size: 22px !important; - margin-right: -0.15em; } .ee-icon-size-24, .ee-icon-size-24:before { font-size: 24px !important; - margin-right: -0.2em; } diff --git a/espresso.php b/espresso.php index 70e628202d5..751e0ffb08d 100644 --- a/espresso.php +++ b/espresso.php @@ -3,7 +3,7 @@ Plugin Name:Event Espresso Plugin URI: https://eventespresso.com/pricing/?ee_ver=ee4&utm_source=ee4_plugin_admin&utm_medium=link&utm_campaign=wordpress_plugins_page&utm_content=support_link Description: Manage events, sell tickets, and receive payments from your WordPress website. Reduce event administration time, cut-out ticketing fees, and own your customer data. | Extensions | Sales | Support - Version: 5.0.19.rc.000 + Version: 5.0.19.rc.010 Author: Event Espresso Author URI: http://eventespresso.com/?ee_ver=ee4&utm_source=ee4_plugin_admin&utm_medium=link&utm_campaign=wordpress_plugins_page&utm_content=support_link License: GPLv3 @@ -104,7 +104,7 @@ function espresso_minimum_php_version_error() */ function espresso_version(): string { - return apply_filters('FHEE__espresso__espresso_version', '5.0.19.rc.000'); + return apply_filters('FHEE__espresso__espresso_version', '5.0.19.rc.010'); } /** diff --git a/modules/thank_you_page/EED_Thank_You_Page.module.php b/modules/thank_you_page/EED_Thank_You_Page.module.php index d95af61e9a0..6b3e0ce9630 100644 --- a/modules/thank_you_page/EED_Thank_You_Page.module.php +++ b/modules/thank_you_page/EED_Thank_You_Page.module.php @@ -331,15 +331,19 @@ protected function _translate_strings() */ public function load_js() { - wp_register_script( + wp_enqueue_script( 'thank_you_page', THANK_YOU_ASSETS_URL . 'thank_you_page.js', array('espresso_core', 'heartbeat'), EVENT_ESPRESSO_VERSION, true ); - wp_enqueue_script('thank_you_page'); - wp_enqueue_style('espresso_default'); + wp_enqueue_style( + 'thank_you_page_css', + THANK_YOU_ASSETS_URL . 'thank_you_page.css', + ['espresso_default'], + EVENT_ESPRESSO_VERSION + ); } diff --git a/modules/thank_you_page/assets/thank_you_page.css b/modules/thank_you_page/assets/thank_you_page.css new file mode 100644 index 00000000000..bd6add82047 --- /dev/null +++ b/modules/thank_you_page/assets/thank_you_page.css @@ -0,0 +1,39 @@ +.ee-table { + width: 100%; +} + +.ee-table th, +.ee-table td { + padding: .5rem; + text-align: start; +} +.ee-table.ee-registrations-list td { + padding-block-end: 1rem; +} +.ee-table th:first-child, +.ee-table td:first-child { + padding-inline-start: 0; +} +.ee-table th:last-child, +.ee-table td:last-child { + padding-inline-end: 0; +} + +.ee-registrations-list td > span{ + align-items: center; + display: inline-flex; + flex-flow: row nowrap; +} + +.ee-registrations-list td:first-child > span { + align-items: flex-start; + display: inline-flex; + flex-flow: column nowrap; + } + +.ee-registrations-list td > span span { + align-items: center; + display: inline-flex; + flex-flow: row nowrap; + white-space: nowrap; +} diff --git a/modules/thank_you_page/templates/thank-you-page-registration-details.template.php b/modules/thank_you_page/templates/thank-you-page-registration-details.template.php index c83e07d4bfe..38c0989981c 100644 --- a/modules/thank_you_page/templates/thank-you-page-registration-details.template.php +++ b/modules/thank_you_page/templates/thank-you-page-registration-details.template.php @@ -58,52 +58,56 @@ if ($is_primary || (! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?> - attendee() instanceof EE_Attendee) { - echo esc_html($registration->attendee()->full_name(true)); - } - ?> -

- count_question_groups()) { ?> - + attendee() instanceof EE_Attendee) { + echo '' . esc_html($registration->attendee()->full_name(true)) . ''; + } + ?> + + count_question_groups()) { ?> + + + + + + - - + + - - - - - -

+ + - e('REG_code') ?> + e('REG_code') ?> + e_pretty_status(true) ?> status_ID() === EEM_Registration::status_id_wait_list) { $wait_list = true; } ?> + ', - '

', - '


' + ' +
+ + ', + ' + +
+

', + ' +


' ) ); }