db = new Booktics_Database(); $this->carts_table = booktics_get_table_name( 'booktics_carts' ); $this->cart_items_table = booktics_get_table_name( 'booktics_cart_items' ); } /** * Add item to the cart for guest users * * @param array $item * * @return array */ public function add_to_cart_guest( array $item ): array { return Cart_Session::add_item( $item ); } /** * Add item to the cart for both guest and registered users * * @param array $params Cart item parameters * * @return array Added cart item */ public function add_to_cart( array $params ): array { $user_id = get_current_user_id(); $params['uuid'] = wp_generate_uuid4(); if ( $user_id ) { return $this->add_to_cart_user( $user_id, $params ); } return $this->add_to_cart_guest( $params ); } /** * Add item to the cart for registered users * * @param int $user_id * @param array $item * * @return array */ public function add_to_cart_user( int $user_id, array $item ): array { $carts = $this->db->select( $this->carts_table, array( 'user_id' => $user_id, ) ); if ( ! count( $carts ) ) { $uuid = wp_generate_uuid4(); $this->db->insert_batch( $this->carts_table, array( array( 'uuid' => $uuid, 'user_id' => $user_id, 'total' => 0, 'created_at' => current_time( 'mysql' ), 'updated_at' => current_time( 'mysql' ), ), ) ); $carts = $this->db->select( $this->carts_table, array( 'user_id' => $user_id, ) ); } // Check if the service_id already exists in the cart items for this cart if ( count( $carts ) ) { $cart = $carts[0]; $existing_items = $this->db->select( $this->cart_items_table, array( 'cart_id' => $cart->id, 'service_id' => $item['service_id'], ) ); if ( ! empty( $existing_items ) ) { // Delete existing items with the same service_id for this cart foreach ( $existing_items as $existing_item ) { $this->db->delete( $this->cart_items_table, array( 'id' => $existing_item->id, ) ); } } } $cart = count( $carts ) ? $carts[0] : array(); $cart_item_data = array( 'uuid' => $item['uuid'], 'cart_id' => $cart->id, 'team_member_id' => $item['team_member_id'], 'service_id' => $item['service_id'], 'date' => $item['date'], 'start_time' => $item['start_time'], 'end_time' => $item['end_time'], 'price' => $item['price'] ?? 0, 'subtotal' => $item['subtotal'] ?? $item['price'], 'total' => $item['total'] ?? $item['subtotal'], 'additional_duration_id' => $item['additional_duration_id'] ?? '', 'created_at' => current_time( 'mysql' ), 'updated_at' => current_time( 'mysql' ), ); $cart_item_data = apply_filters( 'booktics_pro_cart_db', $cart_item_data, $item ); $this->db->insert_batch( $this->cart_items_table, array( $cart_item_data ) ); if ( isset( $cart->id ) ) { $this->update_cart_total( $cart->id ); } if ( isset( $cart_item_data['extra_services'] ) ) { $cart_item_data['extra_services'] = json_decode( $cart_item_data['extra_services'], true ); } return $cart_item_data; } /** * Synchronize session cart items to a database * * @param int $user_id */ public function sync_session_to_db( int $user_id ): void { $session_cart = Cart_Session::get(); if ( empty( $session_cart['items'] ) ) { return; } foreach ( $session_cart['items'] as $item ) { $this->add_to_cart_user( $user_id, $item ); } Cart_Session::clear(); } /** * Update cart total based on items * * @param int $cart_id */ protected function update_cart_total( int $cart_id ): void { $items = $this->db->select( $this->cart_items_table, array( 'cart_id' => $cart_id, ) ); if ( empty( $items ) ) { $this->db->delete( $this->carts_table, array( 'id' => $cart_id ) ); return; } $total = 0; foreach ( $items as $item ) { $total += (float) ( $item->total ?? $item->subtotal ?? 0 ); } $this->db->update( $this->carts_table, array( 'total' => $total, 'updated_at' => current_time( 'mysql' ), ), array( 'id' => $cart_id ) ); } /** * Get a cart and its items for a user * * @return array */ public function get_cart(): array { $user_id = get_current_user_id(); if ( ! $user_id ) { return Cart_Session::get(); } $carts = $this->db->select( $this->carts_table, array( 'user_id' => $user_id, ) ); $cart = count( $carts ) ? $carts[0] : null; if ( ! $cart ) { return array( 'items' => array() ); } $items = $this->db->select( $this->cart_items_table, array( 'cart_id' => $cart->id, ) ); foreach ( $items as $i => $item ) { if ( isset( $item->extra_services ) ) { $item->extra_services = json_decode( $item->extra_services, true ); } } return array_merge( (array) $cart, array( 'items' => $items ) ); } /** * Remove item from the cart * * @param string|null $id */ public function remove_cart_item( $id = null ): void { $user_id = get_current_user_id(); if ( ! $user_id ) { if ( ! $id ) { Cart_Session::clear(); } else { Cart_Session::delete_item( $id ); } } $carts = $this->db->select( $this->carts_table, array( 'user_id' => $user_id, ) ); $cart = count( $carts ) ? $carts[0] : null; if ( ! $cart ) { return; } $conditions = array( 'cart_id' => $cart->id ); if ( ! empty( $id ) ) { $conditions['uuid'] = $id; } $this->db->delete( $this->cart_items_table, $conditions ); $this->update_cart_total( $cart->id ); } /** * Edit item in the cart * * @param string $uuid * @param array $new_data * * @return array Updated item data or empty array if item not found */ public function edit_cart_item( string $uuid, array $new_data ): array { if ( ! is_user_logged_in() ) { Cart_Session::edit_item( $uuid, $new_data ); $cart = Cart_Session::get(); foreach ( $cart['items'] as $item ) { if ( $item['uuid'] === $uuid ) { return $item; } } return array(); } $user_id = get_current_user_id(); $carts = $this->db->select( $this->carts_table, array( 'user_id' => $user_id, ) ); $cart = count( $carts ) ? $carts[0] : null; if ( ! $cart ) { return array(); } $cart_item_data = array_merge( $new_data, array( 'updated_at' => current_time( 'mysql' ) ) ); $cart_item_data = apply_filters( 'booktics_pro_cart_db', $cart_item_data, $new_data ); $this->db->update( $this->cart_items_table, $cart_item_data, array( 'cart_id' => $cart->id, 'uuid' => $uuid, ) ); $this->update_cart_total( $cart->id ); $updated_item = $this->db->select( $this->cart_items_table, array( 'cart_id' => $cart->id, 'uuid' => $uuid, ) ); foreach ( $updated_item as $i => $item ) { if ( isset( $item->extra_services ) ) { $item->extra_services = json_decode( $item->extra_services, true ); } } return count( $updated_item ) ? (array) $updated_item[0] : array(); } }