diff --git a/changelog/feature-ET-2268-update-modifier-queries b/changelog/feature-ET-2268-update-modifier-queries new file mode 100644 index 0000000000..9acb656672 --- /dev/null +++ b/changelog/feature-ET-2268-update-modifier-queries @@ -0,0 +1,4 @@ +Significance: minor +Type: performance + +Enhance the performance of order modifier database queries [ET-2268] diff --git a/src/Tickets/Commerce/Order_Modifiers/API/Fees.php b/src/Tickets/Commerce/Order_Modifiers/API/Fees.php index df810fda45..c60802aa43 100644 --- a/src/Tickets/Commerce/Order_Modifiers/API/Fees.php +++ b/src/Tickets/Commerce/Order_Modifiers/API/Fees.php @@ -13,7 +13,6 @@ use TEC\Tickets\Commerce\Module; use TEC\Tickets\Commerce\Order_Modifiers\Modifiers\Fee_Modifier_Manager as Manager; use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifier_Relationship as Relationships; -use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Fees as Fee_Repository; use TEC\Tickets\Commerce\Order_Modifiers\Traits\Fee_Types; use WP_Error; use TEC\Common\Contracts\Container; @@ -50,21 +49,18 @@ class Fees extends Base_API { /** * Fees constructor. * - * @param Container $container The DI container. - * @param Fee_Repository $fee_repository The repository for interacting with the order modifiers. - * @param Relationships $relationships The repository for interacting with the order modifiers relationships. - * @param Manager $manager The manager for the order modifiers. + * @param Container $container The DI container. + * @param Relationships $relationships The repository for interacting with the order modifiers relationships. + * @param Manager $manager The manager for the order modifiers. */ public function __construct( Container $container, - Fee_Repository $fee_repository, Relationships $relationships, Manager $manager ) { parent::__construct( $container ); - $this->modifiers_repository = $fee_repository; - $this->relationships = $relationships; - $this->manager = $manager; + $this->relationships = $relationships; + $this->manager = $manager; } /** diff --git a/src/Tickets/Commerce/Order_Modifiers/Admin/Order_Modifier_Fee_Metabox.php b/src/Tickets/Commerce/Order_Modifiers/Admin/Order_Modifier_Fee_Metabox.php index 7967e3e135..ef11743cc6 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Admin/Order_Modifier_Fee_Metabox.php +++ b/src/Tickets/Commerce/Order_Modifiers/Admin/Order_Modifier_Fee_Metabox.php @@ -102,7 +102,6 @@ public function __construct( $this->manager = $manager; // Set up the order modifiers repository for accessing fee data. - $this->modifiers_repository = $fees_repository; $this->order_modifiers_relationship_repository = $order_modifier_relationship; } diff --git a/src/Tickets/Commerce/Order_Modifiers/Models/Order_Modifier.php b/src/Tickets/Commerce/Order_Modifiers/Models/Order_Modifier.php index d2b2e3a1a1..2b6e8f5d2d 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Models/Order_Modifier.php +++ b/src/Tickets/Commerce/Order_Modifiers/Models/Order_Modifier.php @@ -16,7 +16,7 @@ use TEC\Common\StellarWP\Models\Model; use TEC\Common\StellarWP\Models\ModelQueryBuilder; use TEC\Tickets\Commerce\Order_Modifiers\Data_Transfer_Objects\Order_Modifier_DTO; -use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifiers as Repository; +use TEC\Tickets\Commerce\Order_Modifiers\Factory; use TEC\Tickets\Commerce\Order_Modifiers\Values\Float_Value; use TEC\Tickets\Commerce\Order_Modifiers\Values\Percent_Value; use TEC\Tickets\Commerce\Order_Modifiers\Values\Positive_Integer_Value; @@ -84,7 +84,7 @@ public static function find( $id ): ?self { return null; } - return ( new Repository( static::$order_modifier_type ) )->find_by_id( $id ); + return Factory::get_repository_for_type( static::$order_modifier_type )->find_by_id( $id ); } /** @@ -116,7 +116,7 @@ public static function create( array $attributes ): self { * @return static */ public function save(): self { - $repository = new Repository( $this->modifier_type ); + $repository = Factory::get_repository_for_type( $this->modifier_type ); if ( $this->id ) { $repository->update( $this ); @@ -136,7 +136,7 @@ public function save(): self { * @return bool Whether the model was deleted. */ public function delete(): bool { - return ( new Repository( $this->modifier_type ) )->delete( $this ); + return Factory::get_repository_for_type( $this->modifier_type )->delete( $this ); } /** @@ -147,7 +147,7 @@ public function delete(): bool { * @return ModelQueryBuilder The query builder instance. */ public static function query(): ModelQueryBuilder { - return tribe( Repository::class )->query(); + return Factory::get_repository_for_type( static::$order_modifier_type )->prepareQuery(); } /** diff --git a/src/Tickets/Commerce/Order_Modifiers/Modifier_Admin_Handler.php b/src/Tickets/Commerce/Order_Modifiers/Modifier_Admin_Handler.php index 9adf6c9d28..298fcdaab6 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Modifier_Admin_Handler.php +++ b/src/Tickets/Commerce/Order_Modifiers/Modifier_Admin_Handler.php @@ -257,7 +257,7 @@ public function render_tec_order_modifiers_page(): void { */ protected function get_modifier_data_by_id( int $modifier_id ): ?array { // Get the modifier type from the request or use the default. - $modifier_type = tribe_get_request_var( 'modifier', $this->get_default_type() ); + $modifier_type = tec_get_request_var( 'modifier', $this->get_default_type() ); // Get the appropriate strategy for the selected modifier type. $modifier_strategy = tribe( Controller::class )->get_modifier( $modifier_type ); @@ -464,10 +464,10 @@ protected function render_error_message( string $message ): void { */ public function handle_delete_modifier(): void { // Check if the action is 'delete_modifier' and nonce is set. - $action = tribe_get_request_var( 'action', '' ); - $modifier_id = absint( tribe_get_request_var( 'modifier_id', '' ) ); - $nonce = tribe_get_request_var( '_wpnonce', '' ); - $modifier_type = sanitize_key( tribe_get_request_var( 'modifier', '' ) ); + $action = tec_get_request_var( 'action', '' ); + $modifier_id = absint( tec_get_request_var( 'modifier_id', '' ) ); + $nonce = tec_get_request_var( '_wpnonce', '' ); + $modifier_type = sanitize_key( tec_get_request_var( 'modifier', '' ) ); // Early bail if the action is not 'delete_modifier'. if ( 'delete_modifier' !== $action ) { diff --git a/src/Tickets/Commerce/Order_Modifiers/Modifiers/Coupon.php b/src/Tickets/Commerce/Order_Modifiers/Modifiers/Coupon.php index 70250f2a38..4940ff1720 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Modifiers/Coupon.php +++ b/src/Tickets/Commerce/Order_Modifiers/Modifiers/Coupon.php @@ -88,7 +88,7 @@ public function insert_modifier( array $data ): Model { [ 'meta_key' => 'coupons_available', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value - 'meta_value' => tribe_get_request_var( 'order_modifier_coupon_limit', '' ), + 'meta_value' => tec_get_request_var( 'order_modifier_coupon_limit', '' ), ] ); @@ -114,7 +114,7 @@ public function update_modifier( array $data ): Model { [ 'meta_key' => 'coupons_available', // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_value - 'meta_value' => tribe_get_request_var( 'order_modifier_coupon_limit', '' ), + 'meta_value' => tec_get_request_var( 'order_modifier_coupon_limit', '' ), ] ); @@ -173,14 +173,14 @@ public function render_edit( array $context ): void { * @return array The context data ready for rendering the form. */ public function map_context_to_template( array $context ): array { - $order_modifier_coupon_limit_meta_value = $this->order_modifiers_meta_repository->find_by_order_modifier_id_and_meta_key( $context['modifier_id'], 'coupons_available' )->meta_value ?? ''; + $limit_value = $this->meta_repository->find_by_order_modifier_id_and_meta_key( $context['modifier_id'], 'coupons_available' )->meta_value ?? ''; return [ 'order_modifier_display_name' => $context['display_name'] ?? '', 'order_modifier_slug' => $context['slug'] ?? $this->generate_unique_slug(), 'order_modifier_sub_type' => $context['sub_type'] ?? '', 'order_modifier_fee_amount_cents' => $this->convert_from_raw_amount( $context['raw_amount'] ?? 0 ), 'order_modifier_status' => $context['status'] ?? '', - 'order_modifier_coupon_limit' => $order_modifier_coupon_limit_meta_value ?? '', + 'order_modifier_coupon_limit' => $limit_value ?? '', ]; } diff --git a/src/Tickets/Commerce/Order_Modifiers/Modifiers/Fee.php b/src/Tickets/Commerce/Order_Modifiers/Modifiers/Fee.php index b358b9fea9..a22a8edaeb 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Modifiers/Fee.php +++ b/src/Tickets/Commerce/Order_Modifiers/Modifiers/Fee.php @@ -83,7 +83,7 @@ public function insert_modifier( array $data ): Model { $modifier = parent::insert_modifier( $data ); // Handle metadata (e.g., order_modifier_apply_to). - $apply_fee_to = tribe_get_request_var( 'order_modifier_apply_to', '' ); + $apply_fee_to = tec_get_request_var( 'order_modifier_apply_to', '' ); // Handle metadata (e.g., order_modifier_apply_to). $this->handle_meta_data( @@ -100,10 +100,10 @@ public function insert_modifier( array $data ): Model { switch ( $apply_fee_to ) { case 'venue': - $apply_to_post_id = tribe_get_request_var( 'venue_list', null ); + $apply_to_post_id = tec_get_request_var( 'venue_list', null ); break; case 'organizer': - $apply_to_post_id = tribe_get_request_var( 'organizer_list', null ); + $apply_to_post_id = tec_get_request_var( 'organizer_list', null ); break; } @@ -132,7 +132,7 @@ public function update_modifier( array $data ): Model { } // Handle metadata (e.g., order_modifier_apply_to). - $apply_fee_to = tribe_get_request_var( 'order_modifier_apply_to', '' ); + $apply_fee_to = tec_get_request_var( 'order_modifier_apply_to', '' ); $this->maybe_clear_relationships( $modifier->id, $apply_fee_to ); @@ -150,10 +150,10 @@ public function update_modifier( array $data ): Model { switch ( $apply_fee_to ) { case 'venue': - $apply_to_post_ids = tribe_get_request_var( 'venue_list', [] ); + $apply_to_post_ids = tec_get_request_var( 'venue_list', [] ); break; case 'organizer': - $apply_to_post_ids = tribe_get_request_var( 'organizer_list', [] ); + $apply_to_post_ids = tec_get_request_var( 'organizer_list', [] ); break; } @@ -269,7 +269,7 @@ public function render_edit( array $context ): void { * @return array The context data ready for rendering the form. */ public function map_context_to_template( array $context ): array { - $order_modifier_fee_applied_to = $this->order_modifiers_meta_repository->find_by_order_modifier_id_and_meta_key( $context['modifier_id'], 'fee_applied_to' )->meta_value ?? ''; + $order_modifier_fee_applied_to = $this->meta_repository->find_by_order_modifier_id_and_meta_key( $context['modifier_id'], 'fee_applied_to' )->meta_value ?? ''; return [ 'order_modifier_display_name' => $context['display_name'] ?? '', 'order_modifier_slug' => $context['slug'] ?? $this->generate_unique_slug(), @@ -295,6 +295,6 @@ public function map_context_to_template( array $context ): array { * @return array The list of posts related to the modifier. */ public function get_active_on( $modifier_id ) { - return $this->order_modifiers_relationship_repository->find_by_modifier_id( $modifier_id ); + return $this->relationship_repository->find_by_modifier_id( $modifier_id ); } } diff --git a/src/Tickets/Commerce/Order_Modifiers/Modifiers/Modifier_Abstract.php b/src/Tickets/Commerce/Order_Modifiers/Modifiers/Modifier_Abstract.php index 04587164f1..33cf446a9b 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Modifiers/Modifier_Abstract.php +++ b/src/Tickets/Commerce/Order_Modifiers/Modifiers/Modifier_Abstract.php @@ -22,22 +22,25 @@ use Exception; use InvalidArgumentException; +use RuntimeException; use TEC\Common\StellarWP\Models\Contracts\Model; -use TEC\Tickets\Commerce\Order_Modifiers\Traits\Valid_Types; -use TEC\Tickets\Commerce\Utils\Value; -use TEC\Tickets\Exceptions\Not_Found_Exception; +use TEC\Tickets\Commerce\Order_Modifiers\Factory; use TEC\Tickets\Commerce\Order_Modifiers\Models\Order_Modifier; use TEC\Tickets\Commerce\Order_Modifiers\Models\Order_Modifier_Meta; use TEC\Tickets\Commerce\Order_Modifiers\Models\Order_Modifier_Relationships; use TEC\Tickets\Commerce\Order_Modifiers\Modifier_Admin_Handler; -use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifiers as Order_Modifiers_Repository; -use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifiers_Meta as Order_Modifiers_Meta_Repository; -use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifier_Relationship as Order_Modifier_Relationship_Repository; +use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifier_Relationship as Relationship_Repo; +use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifiers as Modifiers_Repo; +use TEC\Tickets\Commerce\Order_Modifiers\Repositories\Order_Modifiers_Meta as Meta_Repo; +use TEC\Tickets\Commerce\Order_Modifiers\Traits\Status; +use TEC\Tickets\Commerce\Order_Modifiers\Traits\Valid_Types; use TEC\Tickets\Commerce\Order_Modifiers\Values\Currency_Value; use TEC\Tickets\Commerce\Order_Modifiers\Values\Float_Value; use TEC\Tickets\Commerce\Order_Modifiers\Values\Percent_Value; use TEC\Tickets\Commerce\Order_Modifiers\Values\Positive_Integer_Value; use TEC\Tickets\Commerce\Order_Modifiers\Values\Precision_Value; +use TEC\Tickets\Commerce\Utils\Value; +use TEC\Tickets\Exceptions\Not_Found_Exception; /** * Class Modifier_Abstract @@ -47,6 +50,8 @@ * @since 5.18.0 */ abstract class Modifier_Abstract implements Modifier_Strategy_Interface { + + use Status; use Valid_Types; /** @@ -61,25 +66,25 @@ abstract class Modifier_Abstract implements Modifier_Strategy_Interface { * The repository for interacting with the order modifiers table. * * @since 5.18.0 - * @var Order_Modifiers_Repository + * @var Modifiers_Repo */ - protected Order_Modifiers_Repository $repository; + protected Modifiers_Repo $repository; /** * The repository for interacting with the order modifiers meta table. * * @since 5.18.0 - * @var Order_Modifiers_Meta_Repository Repository + * @var Meta_Repo Repository */ - protected Order_Modifiers_Meta_Repository $order_modifiers_meta_repository; + protected Meta_Repo $meta_repository; /** * The repository for interacting with the order modifier relationship table. * * @since 5.18.0 - * @var Order_Modifier_Relationship_Repository Repository + * @var Relationship_Repo Repository */ - protected Order_Modifier_Relationship_Repository $order_modifiers_relationship_repository; + protected Relationship_Repo $relationship_repository; /** * Fields required by this modifier. @@ -96,9 +101,9 @@ abstract class Modifier_Abstract implements Modifier_Strategy_Interface { * @since 5.18.0 */ public function __construct() { - $this->repository = new Order_Modifiers_Repository( $this->modifier_type ); - $this->order_modifiers_meta_repository = new Order_Modifiers_Meta_Repository(); - $this->order_modifiers_relationship_repository = new Order_Modifier_Relationship_Repository(); + $this->repository = Factory::get_repository_for_type( $this->modifier_type ); + $this->meta_repository = new Meta_Repo(); + $this->relationship_repository = new Relationship_Repo(); } /** @@ -150,14 +155,14 @@ public function update_modifier( array $data ): Model { * * @since 5.18.0 * - * @param int $modifier_id The modifier ID. + * @param int $modifier_id The modifier ID. * + * @return array The modifier data as an array. * - * @return array|null The modifier data or null if not found. + * @throws RuntimeException If the modifier is not found. */ public function get_modifier_by_id( int $modifier_id ): ?array { - $modifier_data = $this->repository->find_by_id( $modifier_id ); - return $modifier_data ? $modifier_data->to_array() : null; + return $this->repository->find_by_id( $modifier_id )->to_array(); } /** @@ -173,6 +178,19 @@ public function find_by_search( array $search ): array { return $this->repository->search_modifiers( $search ); } + /** + * Finds a modifier by the given search criteria and returns the count. + * + * @since TBD + * + * @param array $search Parameters to search Order Modifiers by. + * + * @return int The count of the modifiers found. + */ + public function find_count_by_search( array $search ): int { + return $this->repository->get_search_count( $search ); + } + /** * Validates the required fields for the modifier. * @@ -193,27 +211,41 @@ public function validate_data( array $data ): bool { $missing_fields = array_diff_key( $this->required_fields, $data ); if ( ! empty( $missing_fields ) ) { $errors[] = sprintf( - /* translators: %s: List of missing fields. */ + /* translators: %s: List of missing fields. */ __( 'The following required fields are missing: %s', 'event-tickets' ), implode( ', ', array_keys( $missing_fields ) ) ); } // Validate required fields are not empty. - foreach ( $this->required_fields as $field => $required ) { - if ( $required && ( ! isset( $data[ $field ] ) || ( is_string( $data[ $field ] ) && trim( $data[ $field ] ) === '' ) ) ) { - $errors[] = sprintf( - /* translators: %s: Field name. */ - __( 'The field "%s" is required and cannot be empty.', 'event-tickets' ), - $field - ); + foreach ( $this->required_fields as $field => $r ) { + switch ( $field ) { + case 'raw_amount': + if ( ! is_float( $data[ $field ] ) ) { + $errors[] = sprintf( + /* translators: %s: Field name. */ + __( 'The field "%s" must be a valid number.', 'event-tickets' ), + $field + ); + } + break; + + default: + if ( ! is_string( $data[ $field ] ) || trim( $data[ $field ] ) === '' ) { + $errors[] = sprintf( + /* translators: %s: Field name. */ + __( 'The field "%s" is required and cannot be empty.', 'event-tickets' ), + $field + ); + } + break; } } // Validate the sub_type field, if present. if ( ! empty( $data['sub_type'] ) && ! $this->is_valid_subtype( $data['sub_type'] ) ) { $errors[] = sprintf( - /* translators: %s: Invalid sub-type value. */ + /* translators: %s: Invalid sub-type value. */ __( 'The provided sub-type "%s" is invalid. Please use a valid sub-type.', 'event-tickets' ), $data['sub_type'] ); @@ -222,7 +254,7 @@ public function validate_data( array $data ): bool { // Validate the status field, if present. if ( ! empty( $data['status'] ) && ! $this->is_valid_status( $data['status'] ) ) { $errors[] = sprintf( - /* translators: %s: Invalid status value. */ + /* translators: %s: Invalid status value. */ __( 'The provided status "%s" is invalid. Please use a valid status.', 'event-tickets' ), $data['status'] ); @@ -232,7 +264,7 @@ public function validate_data( array $data ): bool { if ( ! empty( $errors ) ) { throw new InvalidArgumentException( sprintf( - /* translators: %s: Validation error messages. */ + /* translators: %s: Validation error messages. */ __( 'Validation failed: %s', 'event-tickets' ), implode( '; ', $errors ) ) @@ -382,43 +414,6 @@ protected function is_slug_unique( string $slug ): bool { } } - /** - * Convert the status to a human-readable format. - * - * This method converts the internal status values ('active', 'inactive', 'draft') - * into human-readable strings ('Active', 'Inactive', 'Draft'). - * It also provides a filter to allow for customizing the status labels if necessary. - * - * @since 5.18.0 - * - * @param string $status The raw status from the database. - * - * @return string The human-readable status. - */ - public function get_status_display( string $status ): string { - // Default conversion. - $statuses = [ - 'active' => _x( 'Active', 'Order modifier status', 'event-tickets' ), - 'inactive' => _x( 'Inactive', 'Order modifier status', 'event-tickets' ), - 'draft' => _x( 'Draft', 'Order modifier status', 'event-tickets' ), - ]; - - /** - * Filters the human-readable status label for an order modifier. - * - * This allows developers to modify the status labels (e.g., changing 'Draft' to 'Pending'). - * - * @since 5.18.0 - * - * @param string[] $statuses The array of default status labels. - * @param string $raw_status The raw status from the database (e.g., 'active', 'draft'). - * @param string $modifier_type The type of the modifier (e.g., 'coupon', 'fee'). - */ - $statuses = apply_filters( 'tec_tickets_commerce_order_modifier_status_display', $statuses, $status, $this->modifier_type ); - - return $statuses[ $status ] ?? $status; - } - /** * Retrieves the page slug for the current modifier context. * @@ -470,7 +465,7 @@ protected function handle_meta_data( int $modifier_id, array $args = [] ): Model } // Upsert the metadata using the repository. - return $this->order_modifiers_meta_repository->upsert_meta( new Order_Modifier_Meta( $meta_data ) ); + return $this->meta_repository->upsert_meta( new Order_Modifier_Meta( $meta_data ) ); } @@ -493,7 +488,7 @@ protected function add_relationship( int $modifier_id, int $post_id ): void { 'post_id' => $post_id, 'post_type' => get_post_type( $post_id ), ]; - $this->order_modifiers_relationship_repository->insert( new Order_Modifier_Relationships( $data ) ); + $this->relationship_repository->insert( new Order_Modifier_Relationships( $data ) ); } /** @@ -509,7 +504,7 @@ protected function add_relationship( int $modifier_id, int $post_id ): void { * @return void */ public function delete_relationship_by_modifier( int $modifier_id ): void { - $this->order_modifiers_relationship_repository->clear_relationships_by_modifier_id( $modifier_id ); + $this->relationship_repository->clear_relationships_by_modifier_id( $modifier_id ); } /** @@ -529,7 +524,7 @@ public function delete_relationship_by_post( int $post_id ): void { 'post_id' => $post_id, 'post_type' => get_post_type( $post_id ), ]; - $this->order_modifiers_relationship_repository->clear_relationships_by_post_id( new Order_Modifier_Relationships( $data ) ); + $this->relationship_repository->clear_relationships_by_post_id( new Order_Modifier_Relationships( $data ) ); } /** @@ -586,12 +581,12 @@ abstract protected function get_plural_name(): string; */ public function maybe_clear_relationships( int $modifier_id, string $new_apply_type ): void { // Retrieve the current apply_type from the metadata. - $current_apply_type = $this->order_modifiers_meta_repository->find_by_order_modifier_id_and_meta_key( $modifier_id, 'fee_applied_to' )->meta_value ?? null; + $current_apply_type = $this->meta_repository->find_by_order_modifier_id_and_meta_key( $modifier_id, 'fee_applied_to' )->meta_value ?? null; // If the apply_type has changed, clear all relationships. if ( $current_apply_type !== $new_apply_type ) { // Clear the relationships for this modifier. - $this->order_modifiers_relationship_repository->clear_relationships_by_modifier_id( $modifier_id ); + $this->relationship_repository->clear_relationships_by_modifier_id( $modifier_id ); } } @@ -620,7 +615,7 @@ public function delete_modifier( int $modifier_id ): bool { $this->delete_relationship_by_modifier( $modifier_id ); // Delete associated meta data. - $this->order_modifiers_meta_repository->delete( new Order_Modifier_Meta( [ 'id' => $modifier_id ] ) ); + $this->meta_repository->delete( new Order_Modifier_Meta( [ 'id' => $modifier_id ] ) ); // Delete the modifier itself (mandatory). $delete_modifier = $this->repository->delete( @@ -654,7 +649,7 @@ public function delete_modifier( int $modifier_id ): bool { * @return mixed|null The meta data found, or null if no matching record is found. */ public function get_order_modifier_meta_by_key( int $order_modifier_id, string $meta_key ) { - return $this->order_modifiers_meta_repository->find_by_order_modifier_id_and_meta_key( $order_modifier_id, $meta_key ); + return $this->meta_repository->find_by_order_modifier_id_and_meta_key( $order_modifier_id, $meta_key ); } /** diff --git a/src/Tickets/Commerce/Order_Modifiers/Repositories/Fees.php b/src/Tickets/Commerce/Order_Modifiers/Repositories/Fees.php index e35d937e45..42a157ae8e 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Repositories/Fees.php +++ b/src/Tickets/Commerce/Order_Modifiers/Repositories/Fees.php @@ -35,11 +35,6 @@ public function __construct() { * @return stdClass[] The array of fee objects from the database. */ public function get_all_automatic_fees() { - return $this->find_by_modifier_type_and_meta( - 'fee_applied_to', - [ 'all' ], - 'fee_applied_to', - 'all' - ); + return $this->get_modifier_by_applied_to( [ 'all' ] ); } } diff --git a/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifier_Relationship.php b/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifier_Relationship.php index d564e14399..fa3745a5c9 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifier_Relationship.php +++ b/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifier_Relationship.php @@ -214,13 +214,16 @@ public function find_by_post_id( int $post_id ): ?array { * @return ModelQueryBuilder The query builder with the necessary joins. */ protected function build_base_query(): ModelQueryBuilder { - $posts_table = 'posts'; - $order_modifiers_table = Order_Modifiers::base_table_name(); - return $this->prepareQuery() - ->select( 'r.id,m.id as modifier_id', 'p.ID as post_id', 'p.post_type', 'p.post_title' ) - ->innerJoin( "$order_modifiers_table as m", 'r.modifier_id', 'm.id' ) - ->innerJoin( "$posts_table as p", 'r.post_id', 'p.ID' ); + ->select( + 'r.id', + [ 'm.id', 'modifier_id' ], + [ 'p.ID', 'post_id' ], + 'p.post_type', + 'p.post_title' + ) + ->innerJoin( Order_Modifiers::base_table_name(), 'r.modifier_id', 'm.id', 'm' ) + ->innerJoin( 'posts', 'r.post_id', 'p.ID', 'p' ); } /** @@ -233,6 +236,6 @@ protected function build_base_query(): ModelQueryBuilder { public function prepareQuery(): ModelQueryBuilder { $builder = new ModelQueryBuilder( Relationship_Model::class ); - return $builder->from( Table::table_name( false ) . ' as r' ); + return $builder->from( Table::table_name( false ), 'r' ); } } diff --git a/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers.php b/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers.php index 8a5742dfca..f69ca1b3d4 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers.php +++ b/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers.php @@ -11,18 +11,20 @@ use RuntimeException; use TEC\Common\StellarWP\DB\DB; +use TEC\Common\StellarWP\DB\QueryBuilder\QueryBuilder; use TEC\Common\StellarWP\Models\Contracts\Model; use TEC\Common\StellarWP\Models\ModelQueryBuilder; use TEC\Common\StellarWP\Models\Repositories\Contracts\Deletable; use TEC\Common\StellarWP\Models\Repositories\Contracts\Insertable; use TEC\Common\StellarWP\Models\Repositories\Contracts\Updatable; use TEC\Common\StellarWP\Models\Repositories\Repository; -use TEC\Tickets\Exceptions\Not_Found_Exception; -use TEC\Tickets\Commerce\Order_Modifiers\Custom_Tables\Order_Modifiers as Table; use TEC\Tickets\Commerce\Order_Modifiers\Custom_Tables\Order_Modifier_Relationships as Relationship_Table; -use TEC\Tickets\Commerce\Order_Modifiers\Models\Order_Modifier; +use TEC\Tickets\Commerce\Order_Modifiers\Custom_Tables\Order_Modifiers as Table; use TEC\Tickets\Commerce\Order_Modifiers\Custom_Tables\Order_Modifiers_Meta; +use TEC\Tickets\Commerce\Order_Modifiers\Models\Order_Modifier; +use TEC\Tickets\Commerce\Order_Modifiers\Traits\Status; use TEC\Tickets\Commerce\Order_Modifiers\Traits\Valid_Types; +use TEC\Tickets\Exceptions\Not_Found_Exception; /** * Class Order_Modifiers. @@ -33,6 +35,7 @@ */ class Order_Modifiers extends Repository implements Insertable, Updatable, Deletable { + use Status; use Valid_Types; /** @@ -70,7 +73,7 @@ public function delete( Model $model ): bool { $this->validate_model_type( $model ); return (bool) DB::delete( - Table::table_name(), + $this->get_table_name(), [ 'id' => $model->id ], [ '%d' ] ); @@ -90,7 +93,7 @@ public function insert( Model $model ): Model { $this->validate_model_type( $model ); DB::insert( - Table::table_name(), + $this->get_table_name(), [ 'modifier_type' => $model->modifier_type, 'sub_type' => $model->sub_type, @@ -134,7 +137,7 @@ public function update( Model $model ): Model { $this->validate_model_type( $model ); DB::update( - Table::table_name(), + $this->get_table_name(), [ 'modifier_type' => $model->modifier_type, 'sub_type' => $model->sub_type, @@ -174,7 +177,7 @@ public function update( Model $model ): Model { * @throws RuntimeException If we didn't get an Order_Modifier object. */ public function find_by_id( int $id ): Order_Modifier { - $result = $this->prepareQuery() + $result = $this->get_query_builder_with_from() ->where( 'id', $id ) ->get(); @@ -195,36 +198,32 @@ public function find_by_id( int $id ): Order_Modifier { * @return Order_Modifier[] An array of Order_Modifiers or an empty array if none found. */ public function search_modifiers( array $args = [] ): array { - // Define default arguments. - $defaults = [ - 'search_term' => '', - 'orderby' => 'display_name', - 'order' => 'asc', - ]; - // Merge passed arguments with defaults. - $args = array_merge( $defaults, $args ); + $args = wp_parse_args( $args, $this->get_default_query_params() ); + $valid_args = $this->get_valid_params( $args ); // Start building the query. - $query = $this->prepareQuery(); + $query = $this->get_query_builder_with_from(); // Add search functionality (search in display_name or slug). - if ( ! empty( $args['search_term'] ) ) { - $query = $query->whereLike( 'display_name', DB::esc_like( $args['search_term'] ) ); + if ( ! empty( $valid_args['search_term'] ) ) { + $query->whereLike( 'display_name', $valid_args['search_term'] ); } - // Add ordering. - $valid_orderby = [ - 'display_name' => 1, - 'slug' => 1, - 'raw_amount' => 1, - 'used' => 1, - 'remaining' => 1, - 'status' => 1, - ]; + // Set the order and orderby parameters. + if ( ! empty( $valid_args['order'] ) ) { + $orderby = array_key_exists( 'orderby', $valid_args ) ? $valid_args['orderby'] : 'display_name'; + $query->orderBy( $orderby, $valid_args['order'] ); + } - if ( ! empty( $args['orderby'] ) && array_key_exists( $args['orderby'], $valid_orderby ) ) { - $query = $query->orderBy( $args['orderby'], $args['order'] ); + // Add the query limit. + if ( ! empty( $valid_args['limit'] ) ) { + $query->limit( $valid_args['limit'] ); + } + + // Add the query offset. + if ( ! empty( $valid_args['offset'] ) ) { + $query->offset( $valid_args['offset'] ); } // Set the modifier type. @@ -233,6 +232,34 @@ public function search_modifiers( array $args = [] ): array { return $query->getAll() ?? []; } + /** + * Get the count of Order Modifiers based on the given criteria. + * + * @since TBD + * + * @param array $args Arguments for the query. + * + * @return int Number of Order Modifiers found. + */ + public function get_search_count( array $args = [] ): int { + // Merge passed arguments with defaults. + $args = wp_parse_args( $args, $this->get_default_query_params() ); + $valid_args = $this->get_valid_params( $args ); + + // Start building the query. + $query = $this->get_query_builder_with_from(); + + // Add search functionality (search in display_name or slug). + if ( ! empty( $valid_args['search_term'] ) ) { + $query->whereLike( 'display_name', $valid_args['search_term'] ); + } + + // Set the modifier type. + $query = $query->where( 'modifier_type', $this->modifier_type ); + + return $query->count() ?? 0; + } + /** * Finds all active Order Modifiers of the current type. * @@ -241,7 +268,7 @@ public function search_modifiers( array $args = [] ): array { * @return Order_Modifier[] Array of active Order Modifier model instances, or null if not found. */ public function find_active(): array { - $result = $this->prepareQuery() + $result = $this->get_query_builder_with_from() ->where( 'modifier_type', $this->modifier_type ) ->where( 'status', 'active' ) ->getAll(); @@ -260,7 +287,7 @@ public function find_active(): array { * @throws Not_Found_Exception If the Order Modifier is not found. */ public function find_by_slug( string $slug ): Order_Modifier { - $result = $this->prepareQuery() + $result = $this->get_query_builder_with_from() ->where( 'modifier_type', $this->modifier_type ) ->where( 'slug', $slug ) ->where( 'status', 'active' ) @@ -277,7 +304,7 @@ public function find_by_slug( string $slug ): Order_Modifier { * @return Order_Modifier[] Array of Order Modifier model instances. */ public function get_all(): array { - $results = $this->prepareQuery() + $results = $this->get_query_builder_with_from() ->where( 'modifier_type', $this->modifier_type ) ->getAll(); @@ -302,15 +329,24 @@ public function get_all(): array { public function find_relationship_by_post_ids( array $post_ids, string $modifier_type, string $status = 'active' ): array { $this->validate_type( $modifier_type ); - $order_modifiers_table = Relationship_Table::base_table_name(); - $builder = new ModelQueryBuilder( $this->get_valid_types()[ $modifier_type ] ); - - $results = $builder->from( Table::table_name( false ) . ' as m' ) - ->select( 'm.*' ) - ->innerJoin( "{$order_modifiers_table} as r", 'm.id', 'r.modifier_id' ) - ->whereIn( 'r.post_id', $post_ids ) - ->where( 'm.modifier_type', $modifier_type ) - ->where( 'm.status', $status ) + $builder = $this->prepareQuery(); + + // Table aliases for the query. + $modifiers = 'm'; + $relationships = 'r'; + + $results = $builder + ->from( $this->get_table_name( false ), $modifiers ) + ->select( "{$modifiers}.*" ) + ->innerJoin( + Relationship_Table::base_table_name(), + "{$modifiers}.id", + "{$relationships}.modifier_id", + $relationships + ) + ->whereIn( "{$relationships}.post_id", $post_ids ) + ->where( "{$modifiers}.modifier_type", $modifier_type ) + ->where( "{$modifiers}.status", $status ) ->getAll(); return $results ?? []; @@ -361,50 +397,136 @@ public function find_by_modifier_type_and_meta( return $cached_results; } - // Get the table names dynamically. - $order_modifiers_table = Table::table_name(); - $order_modifiers_meta_table = Order_Modifiers_Meta::table_name(); + // Aliases for the tables. + $modifiers = 'o'; + $meta = 'm'; // Initialize the SQL query with the base WHERE clause for modifier_type. - $sql = []; - $sql[] = <<modifier_type ]; + $builder = new QueryBuilder(); + $builder + ->select( "{$modifiers}.*", "{$meta}.meta_value" ) + ->from( $this->get_table_name( false ), $modifiers ) + ->leftJoin( + $this->get_meta_table_name( false ), + "{$modifiers}.id", + "{$meta}.order_modifier_id", + $meta + ) + ->where( "{$modifiers}.modifier_type", $this->modifier_type ) + ->where( "{$modifiers}.status", 'active' ); // Handle the meta_key condition: Use IFNULL if a default_meta_key is provided, otherwise check for meta_key directly. if ( $default_meta_key ) { - $sql[] = 'AND (IFNULL(m.meta_key, %s) = %s)'; - $params[] = $default_meta_key; + $builder->whereRaw( + "IFNULL({$meta}.meta_key, %s) = %s", + $default_meta_key, + $meta_key + ); } else { - $sql[] = 'AND m.meta_key = %s'; + $builder->where( "{$meta}.meta_key", $meta_key ); } - // Add the meta key to the params. - $params[] = $meta_key; - // Handle the meta_value condition: Use IFNULL if a default_meta_value is provided, otherwise check directly. - $meta_params_string = implode( ',', array_fill( 0, count( $meta_values ), '%s' ) ); if ( $default_meta_value ) { - $sql[] = "AND (IFNULL(m.meta_value, %s) IN ({$meta_params_string}))"; - $params[] = $default_meta_value; + $meta_params_string = implode( ',', array_fill( 0, count( $meta_values ), '%s' ) ); + $builder->whereRaw( + "IFNULL({$meta}.meta_value, %s) IN ({$meta_params_string})", + $default_meta_value, + ...$meta_values + ); } else { - $sql[] = "AND m.meta_value IN ({$meta_params_string})"; + $builder->whereIn( "{$meta}.meta_value", $meta_values ); } - $params = array_merge( $params, $meta_values ); - // Prepare and execute the query. - $results = DB::get_results( - DB::prepare( implode( ' ', $sql ), ...$params ) + $results = $builder->getAll() ?? []; + + // Cache the results for future use. + $tribe_cache[ $cache_key ] = $results; + + return $results; + } + + /** + * Finds Order Modifiers by applied_to value. + * + * @since TBD + * + * @param string[] $applied_to The value(s) to filter the query by. + * @param array $params { Optional. Parameters to filter the query. + * @type string[] $status The status of the modifiers to filter by. Default 'active'. + * @type int $limit The number of results to return. Default 10. + * @type string $order The order of the results. Default 'DESC'. + * } + * + * @return array + */ + public function get_modifier_by_applied_to( array $applied_to, array $params = [] ): array { + // Set up default query parameters. + $params = wp_parse_args( $params, $this->get_default_query_params() ); + + // Validate the parameters before using them in the query. + $valid_params = $this->get_valid_params( $params ); + + // Filter out empty and duplicate values. + $applied_to = array_unique( array_filter( array_map( 'trim', $applied_to ) ) ); + + // Generate a cache key based on the arguments. + $cache_key = 'modifier_type_applied_to_' . md5( + wp_json_encode( + [ + $this->modifier_type, + $applied_to, + $valid_params, + ] + ) ); + $tribe_cache = tribe( 'cache' ); + + // Try to get the results from the cache. + $cached_results = $tribe_cache[ $cache_key ] ?? false; + if ( $cached_results && is_array( $cached_results ) ) { + return $cached_results; + } + + // Table aliases for the query. + $modifiers = 'o'; + $meta = 'm'; + + // Initialize the query builder and construct the query. + $builder = new QueryBuilder(); + $builder + ->from( $this->get_table_name( false ), $modifiers ) + ->select( "{$modifiers}.*", "{$meta}.meta_value" ) + ->innerJoin( + $this->get_meta_table_name( false ), + "{$modifiers}.id", + "{$meta}.order_modifier_id", + $meta + ) + ->where( "{$modifiers}.modifier_type", $this->modifier_type ) + ->where( "{$meta}.meta_key", $this->get_applied_to_key() ) + ->whereIn( "{$meta}.meta_value", $applied_to ); + + // Add the status params to the pieces. + if ( array_key_exists( 'status', $valid_params ) ) { + $builder->whereIn( "{$modifiers}.status", $valid_params['status'] ); + } + + // Add the order param to the pieces. + if ( array_key_exists( 'order', $valid_params ) ) { + $orderby = array_key_exists( 'orderby', $valid_params ) ? $valid_params['orderby'] : 'id'; + $builder->orderBy( "{$modifiers}.{$orderby}", $valid_params['order'] ); + } + + // Add the limit param to the pieces. + if ( array_key_exists( 'limit', $valid_params ) ) { + $builder->limit( $valid_params['limit'] ); + } + + $results = $builder->getAll() ?? []; + // Cache the results for future use. $tribe_cache[ $cache_key ] = $results; @@ -416,16 +538,167 @@ public function find_by_modifier_type_and_meta( * * @since 5.18.0 * - * @return ModelQueryBuilder + * @return ModelQueryBuilder The query builder object. */ public function prepareQuery(): ModelQueryBuilder { // Determine the model class based on the modifier type. $this->validate_type( $this->modifier_type ); $class = $this->get_valid_types()[ $this->modifier_type ]; - $builder = new ModelQueryBuilder( $class ); + return new ModelQueryBuilder( $class ); + } + + /** + * Wrapper for getting the query builder with table name as the FROM clause. + * + * This will call ->from() on the query builder with the table name before + * the object is returned. + * + * @since TBD + * + * @return ModelQueryBuilder The query builder object. + */ + protected function get_query_builder_with_from(): ModelQueryBuilder { + $builder = $this->prepareQuery(); + + return $builder->from( $this->get_table_name( false ) ); + } + + /** + * Wrapper for getting the table name. + * + * This allows for easy interpolation in strings. + * + * @since TBD + * + * @param bool $with_prefix Whether to include the table prefix. Default is true. + * + * @return string The table name. + */ + protected function get_table_name( bool $with_prefix = true ): string { + return Table::table_name( $with_prefix ); + } + + /** + * Wrapper for getting the meta table name. + * + * This allows for easy interpolation in strings. + * + * @since TBD + * + * @param bool $with_prefix Whether to include the table prefix. Default is true. + * + * @return string The meta table name. + */ + protected function get_meta_table_name( bool $with_prefix = true ): string { + return Order_Modifiers_Meta::table_name( $with_prefix ); + } + + /** + * Get the default query parameters. + * + * @since TBD + * + * @return array The default query parameters. + */ + protected function get_default_query_params(): array { + return [ + 'limit' => 10, + 'order' => 'ASC', + 'orderby' => 'id', + 'page' => 1, + 'search_term' => '', + 'status' => [ 'active' ], + ]; + } - return $builder->from( Table::table_name( false ) ); + /** + * Get the valid parameters for the query. + * + * This will remove any parameters that we don't handle from the query and do basic + * validation of the value of each query parameter. + * + * @since TBD + * + * @param array $params The parameters to validate. + * + * @return array The valid parameters. + */ + protected function get_valid_params( array $params ): array { + $valid_params = []; + foreach ( $params as $key => $value ) { + switch ( $key ) { + case 'limit': + case 'offset': + case 'page': + $valid_params[ $key ] = absint( $value ); + break; + + case 'order': + $value = strtoupper( $value ); + $valid_params[ $key ] = 'ASC' === $value ? 'ASC' : 'DESC'; + break; + + case 'orderby': + $valid_orderby = [ + 'display_name' => 1, + 'slug' => 1, + 'raw_amount' => 1, + 'used' => 1, + 'remaining' => 1, + 'status' => 1, + ]; + if ( array_key_exists( $value, $valid_orderby ) ) { + $valid_params[ $key ] = $value; + } + break; + + case 'search_term': + $valid_params[ $key ] = DB::esc_like( $value ); + break; + + case 'status': + $valid_params[ $key ] = array_filter( + (array) $value, + fn( $status ) => $this->is_valid_status( $status ) + ); + break; + + // Default is to skip adding the parameter. + default: + break; + } + } + + // If the page parameter is passed, set the offset based on the page and limit. + if ( array_key_exists( 'page', $valid_params ) && array_key_exists( 'limit', $valid_params ) ) { + $valid_params['offset'] = ( $valid_params['page'] - 1 ) * $valid_params['limit']; + } + + return $valid_params; + } + + /** + * Get the key used to store the applied to value in the meta table. + * + * @since TBD + * + * @return string The key used to store the applied to value in the meta table. + */ + protected function get_applied_to_key(): string { + $default_key = "{$this->modifier_type}_applied_to"; + + /** + * Filters the key used to store the applied to value in the meta table. + * + * @since TBD + * + * @param string $result The key used to store the applied to value in the meta table. + * @param string $modifier_type The type of the modifier (e.g., 'coupon', 'fee'). + */ + $result = (string) apply_filters( 'tec_tickets_commerce_order_modifier_applied_to_key', $default_key, $this->modifier_type ); + + return ( ! empty( $result ) ) ? $result : $default_key; } /** diff --git a/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers_Meta.php b/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers_Meta.php index bc4b822d17..ce6d2b10d7 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers_Meta.php +++ b/src/Tickets/Commerce/Order_Modifiers/Repositories/Order_Modifiers_Meta.php @@ -137,13 +137,10 @@ public function upsert_meta( Order_Modifier_Meta $meta_data ): Model { $meta_data->meta_key ); - if ( $existing_meta ) { - // If the record exists, update it with the new data. - return $this->update( $meta_data ); - } - - // If no existing record is found, insert a new one. - return $this->insert( $meta_data ); + // If the record exists, update it with the new data, otherwise insert a new one. + return $existing_meta + ? $this->update( $meta_data ) + : $this->insert( $meta_data ); } /** @@ -157,8 +154,8 @@ public function upsert_meta( Order_Modifier_Meta $meta_data ): Model { */ public function find_by_order_modifier_id( int $order_modifier_id ): Model { return $this->prepareQuery() - ->where( 'order_modifier_id', $order_modifier_id ) - ->get(); + ->where( 'order_modifier_id', $order_modifier_id ) + ->get(); } /** @@ -173,9 +170,9 @@ public function find_by_order_modifier_id( int $order_modifier_id ): Model { */ public function find_by_order_modifier_id_and_meta_key( int $order_modifier_id, string $meta_key ): ?Order_Modifier_Meta { return $this->prepareQuery() - ->where( 'order_modifier_id', $order_modifier_id ) - ->where( 'meta_key', $meta_key ) - ->limit( 1 ) - ->get(); + ->where( 'order_modifier_id', $order_modifier_id ) + ->where( 'meta_key', $meta_key ) + ->limit( 1 ) + ->get(); } } diff --git a/src/Tickets/Commerce/Order_Modifiers/Table_Views/Order_Modifier_Table.php b/src/Tickets/Commerce/Order_Modifiers/Table_Views/Order_Modifier_Table.php index b85d67a8f6..26a02fef76 100644 --- a/src/Tickets/Commerce/Order_Modifiers/Table_Views/Order_Modifier_Table.php +++ b/src/Tickets/Commerce/Order_Modifiers/Table_Views/Order_Modifier_Table.php @@ -104,39 +104,38 @@ public function __construct( * @since 5.18.0 */ public function prepare_items() { - $columns = $this->get_columns(); - $hidden = []; - $sortable = $this->get_sortable_columns(); - $this->_column_headers = [ $columns, $hidden, $sortable ]; + $this->_column_headers = [ + $this->get_columns(), + $this->get_hidden_columns(), + $this->get_sortable_columns(), + ]; // Handle search. - $search = tribe_get_request_var( 's', '' ); + $search = tec_get_request_var( 's', '' ); - // Capture sorting parameters. - - $orderby = sanitize_text_field( tribe_get_request_var( 'orderby', 'display_name' ) ); - $order = sanitize_text_field( tribe_get_request_var( 'order', 'asc' ) ); + // Pagination parameters. + $per_page = $this->get_items_per_page( "{$this->modifier->get_modifier_type()}_per_page", 10 ); + $current_page = $this->get_pagenum(); // Fetch the data from the modifier class, including sorting. - $data = $this->modifier->find_by_search( + $this->items = $this->modifier->find_by_search( [ - 'search_term' => $search, - 'orderby' => $orderby, - 'order' => $order, - 'modifier_type' => $this->modifier->get_modifier_type(), + 'search_term' => $search, + 'orderby' => tec_get_request_var( 'orderby', 'display_name' ), + 'order' => tec_get_request_var( 'order', 'asc' ), + 'limit' => $per_page, + 'page' => $current_page, ] ); - // Pagination. - $per_page = $this->get_items_per_page( $this->modifier->get_modifier_type() . '_per_page', 10 ); - $current_page = $this->get_pagenum(); - $total_items = count( $data ); - - $data = array_slice( $data, ( $current_page - 1 ) * $per_page, $per_page ); - - // Set the items for the table. - $this->items = $data; + // Get the total number of items. + if ( count( $this->items ) < $per_page && $current_page === 1 ) { + $total_items = count( $this->items ); + } else { + $total_items = $this->modifier->find_count_by_search( [ 'search_term' => $search ] ); + } + // Set the pagination args. $this->set_pagination_args( [ 'total_items' => $total_items, @@ -222,10 +221,10 @@ protected function render_actions( string $label, array $actions ): string { * @return void */ public function search_box( $text, $input_id, $placeholder = '' ) { - $search_value = sanitize_text_field( tribe_get_request_var( 's', '' ) ); + $search_value = tec_get_request_var( 's', '' ); // Set the input ID. - $input_id = $input_id . '-search-input'; + $input_id = "{$input_id}-search-input"; // If no placeholder is provided, default to the display_name column. if ( empty( $placeholder ) ) { @@ -257,7 +256,7 @@ public function render_tabs(): void { } // Determine the current modifier, falling back to the default. - $current_modifier = tribe_get_request_var( 'modifier', $this->get_default_type() ); + $current_modifier = tec_get_request_var( 'modifier', $this->get_default_type() ); echo '