getInputs(); $before = $this->approval_reward(); $name = (string) ( $before['name'] ?? 'Reward ID ' . ( $inputs['reward_id'] ?? '?' ) ); $changes = []; foreach ( self::FIELDS as $field ) { if ( array_key_exists( $field, $inputs ) ) { $from = $before[ $field ] ?? '(unset)'; $to = $inputs[ $field ]; $changes[] = sprintf( '%s: %s -> %s', $field, $this->display_value( $from ), $this->display_value( $to ) ); } } if ( [] === $changes ) { /* translators: %1$s reward name. */ $summary = sprintf( __( 'Update reward "%1$s"', 'aisentic' ), $name ); } else { /* translators: %1$s reward name, %2$s changed fields. */ $summary = sprintf( __( 'Update reward "%1$s": %2$s', 'aisentic' ), $name, implode( '; ', $changes ) ); } if ( isset( $inputs['redeem_method'] ) && (string) ( $before['redeem_method'] ?? '' ) !== (string) $inputs['redeem_method'] ) { $summary .= ' ' . __( 'Warning: Pointics may block this method change while open redemptions exist.', 'aisentic' ); } return $summary; } public function get_approval_inputs(): array { $inputs = $this->getInputs(); $before = $this->approval_reward(); if ( [] !== $before ) { $inputs['reward'] = sprintf( '%s (ID: %d)', (string) ( $before['name'] ?? 'Reward' ), (int) ( $before['id'] ?? $inputs['reward_id'] ?? 0 ) ); } return $inputs; } public function __invoke( int $reward_id, ?string $name = null, ?int $cost_points = null, ?float $value = null, ?string $redeem_method = null, ?string $redeem_type = null, ?array $conditions = null, ?array $user_roles = null, ?string $integration = null, ?string $description = null, ?array $redeem_params = null, ?string $currency = null, ?bool $is_active = null, ?int $sort_order = null, ?string $slug = null ): array { $guard = $this->guard( 'manage_pointics', 'manage_options' ); if ( null !== $guard ) { return $guard; } $ready = $this->pointics_tables_ready(); if ( null !== $ready ) { return $this->steer( $ready ); } try { $controller = pointics_container()->make( \Pointics\Api\Controllers\Rewards_Controller::class ); $current = $this->get_current( $controller, $reward_id ); if ( $this->is_error( $current ) ) { return $current; } $body = []; $values = compact( 'name', 'cost_points', 'value', 'redeem_method', 'redeem_type', 'conditions', 'user_roles', 'integration', 'description', 'redeem_params', 'currency', 'is_active', 'sort_order', 'slug' ); $wants_method = null !== $redeem_method && '' !== $redeem_method; $wants_type = null !== $redeem_type && '' !== $redeem_type; if ( $wants_method || $wants_type ) { $vocabulary = $this->load_vocabulary( $controller, $wants_method, $wants_type ); if ( $this->is_error( $vocabulary ) ) { return $vocabulary; } if ( $wants_method && ! in_array( $redeem_method, $vocabulary['methods'], true ) ) { return $this->steer( [ 'error' => __( 'Use pointics-list-redemption-methods to choose a live redeem method.', 'aisentic' ), 'code' => 'validation', 'status' => 422, ] ); } if ( $wants_type && ! in_array( $redeem_type, $vocabulary['types'], true ) ) { return $this->steer( [ 'error' => __( 'Use pointics-list-redemption-methods to choose a live redeem type.', 'aisentic' ), 'code' => 'validation', 'status' => 422, ] ); } } foreach ( $values as $key => $value_for_key ) { if ( null === $value_for_key || ! in_array( $key, self::FIELDS, true ) ) { continue; } if ( 'redeem_method' === $key && '' === $value_for_key ) { continue; } $body[ $key ] = match ( $key ) { 'slug' => sanitize_title( $value_for_key ), 'user_roles' => array_map( 'sanitize_key', (array) $value_for_key ), 'conditions' => is_array( $value_for_key ) ? $value_for_key : null, 'redeem_params' => is_array( $value_for_key ) ? $value_for_key : [], default => is_string( $value_for_key ) ? sanitize_text_field( $value_for_key ) : $value_for_key, }; } if ( [] === $body ) { return $this->steer( [ 'error' => __( 'No updatable Pointics reward fields were provided.', 'aisentic' ), 'code' => 'invalid_argument', 'status' => 400, ] ); } $request = new \WP_REST_Request( 'PUT', '/pointics/v1/rewards/' . $reward_id ); $request->set_header( 'content-type', 'application/json' ); $request->set_body( wp_json_encode( $body ) ); $request->set_url_params( [ 'id' => $reward_id ] ); foreach ( $body as $key => $value_for_key ) { $request->set_param( $key, $value_for_key ); } $data = $this->extract_response( $controller->update_reward( $request ), __( 'Failed to update the Pointics reward.', 'aisentic' ), 'pointics-update-reward' ); if ( $this->is_error( $data ) ) { return $data; } return [ 'success' => true, 'reward' => $this->shape_reward( $data ), 'message' => __( 'Pointics reward updated.', 'aisentic' ), ]; } catch ( \Throwable $e ) { Log::error( 'Pointics_Update_Reward_Tool error', [ 'error' => $e->getMessage() ] ); return $this->steer( [ 'error' => __( 'Failed to update the Pointics reward.', 'aisentic' ), 'code' => 'internal', 'status' => null, ] ); } } private function get_current( object $controller, int $reward_id ): array { $request = new \WP_REST_Request( 'GET', '/pointics/v1/rewards/' . $reward_id ); $request->set_url_params( [ 'id' => $reward_id ] ); return $this->extract_response( $controller->get_reward( $request ), __( 'Failed to retrieve the Pointics reward before updating it.', 'aisentic' ), 'pointics-get-reward' ); } private function approval_reward(): array { $id = (int) ( $this->getInputs()['reward_id'] ?? 0 ); return $this->entity_lookup( \Pointics\Api\Controllers\Rewards_Controller::class, 'get_reward', $id, 'pointics-get-reward', __( 'Failed to retrieve the Pointics reward.', 'aisentic' ) ); } private function display_value( mixed $value ): string { return is_scalar( $value ) ? (string) $value : (string) wp_json_encode( $value ); } private function load_vocabulary( object $controller, bool $needs_methods, bool $needs_types ): array { $methods = []; $types = []; if ( $needs_methods ) { $methods_request = new \WP_REST_Request( 'GET', '/pointics/v1/rewards/methods' ); $methods_data = $this->extract_response( $controller->list_methods( $methods_request ), __( 'Failed to load live Pointics redemption methods.', 'aisentic' ), 'pointics-list-redemption-methods' ); if ( $this->is_error( $methods_data ) ) { return $methods_data; } $methods = array_column( $methods_data['items'] ?? [], 'id' ); } if ( $needs_types ) { $types_request = new \WP_REST_Request( 'GET', '/pointics/v1/rewards/redeem-types' ); $types_data = $this->extract_response( $controller->list_redeem_types( $types_request ), __( 'Failed to load live Pointics redeem types.', 'aisentic' ), 'pointics-list-redemption-methods' ); if ( $this->is_error( $types_data ) ) { return $types_data; } $types = array_column( $types_data['items'] ?? [], 'id' ); } return [ 'methods' => $methods, 'types' => $types, ]; } }