PluginProbe ʕ •ᴥ•ʔ
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.12.3
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.12.3
2.12.5 2.12.4 2.12.3 2.12.2 2.12.1 2.12.0 2.11.1 2.11.0 2.10.1 2.10.0 2.9.1 2.9.0 2.8.2 2.8.1 2.7.0 2.7.1 2.8.0 trunk 0.0.10 0.0.11 0.0.12 0.0.13 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 0.0.8 0.0.9 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.1.0 1.1.1 1.1.2 1.10.0 1.10.1 1.11.0 1.12.0 1.12.1 1.12.2 1.12.3 1.13.0 1.13.1 1.13.2 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.8.0 1.9.0 1.9.1 2.0.0 2.0.1 2.0.2 2.1.0 2.1.1 2.2.0 2.2.1 2.2.2 2.3.0 2.4.0 2.5.0 2.5.2 2.6.0
sureforms / inc / ai-form-builder / ai-form-builder.php
sureforms / inc / ai-form-builder Last commit date
ai-auth.php 5 months ago ai-form-builder.php 1 month ago ai-helper.php 3 months ago field-mapping.php 2 months ago
ai-form-builder.php
136 lines
1 <?php
2 /**
3 * SureForms - AI Form Builder.
4 *
5 * @package sureforms
6 * @since 0.0.8
7 */
8
9 namespace SRFM\Inc\AI_Form_Builder;
10
11 use SRFM\Inc\Traits\Get_Instance;
12
13 // Exit if accessed directly.
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit;
16 }
17
18 /**
19 * SureForms AI Form Builder Class.
20 */
21 class AI_Form_Builder {
22 use Get_Instance;
23
24 /**
25 * Fetches ai data from the middleware server
26 *
27 * @param \WP_REST_Request $request request object.
28 * @since 0.0.8
29 * @return void
30 */
31 public function generate_ai_form( $request ) {
32
33 // Get the params.
34 $params = $request->get_params();
35
36 // If the message array doesn't exist, abandon ship.
37 if ( empty( $params['message_array'] ) || ! is_array( $params['message_array'] ) ) {
38 wp_send_json_error( [ 'message' => __( 'The message array was not supplied', 'sureforms' ) ] );
39 }
40
41 // Set the token count to 0, and create messages array.
42 $messages = [];
43
44 // Start with the last message - going upwards until the token count hits 2000.
45 foreach ( array_reverse( $params['message_array'] ) as $current_message ) {
46 // If the message content doesn't exist, skip it.
47 if ( empty( $current_message['content'] ) ) {
48 continue;
49 }
50
51 // Add the message to the start of the messages to send to the SCS Middleware.
52 array_unshift( $messages, $current_message );
53 }
54
55 // Bail if no usable prompt remained after filtering empty messages.
56 if ( empty( $messages ) || empty( $messages[0]['content'] ) ) {
57 wp_send_json_error( [ 'message' => __( 'No prompt was supplied.', 'sureforms' ) ] );
58 }
59
60 // Server-side prompt-length cap. The UI enforces a 2000-char limit via maxlength, but that
61 // is client-side only and can be bypassed by a crafted request, so mirror it here. This is
62 // cost/resource hardening — output is always escaped, so this is not an XSS concern.
63 if ( mb_strlen( (string) $messages[0]['content'] ) > 2000 ) {
64 wp_send_json_error( [ 'message' => __( 'The prompt is too long. Please shorten it and try again.', 'sureforms' ) ] );
65 }
66
67 // Get the response from the endpoint.
68 $response = AI_Helper::get_chat_completions_response(
69 apply_filters(
70 'srfm_ai_form_generator_body',
71 [
72 'query' => $messages[0]['content'],
73 ],
74 $params
75 )
76 );
77
78 // check if response is an array if not then send error.
79 if ( ! is_array( $response ) ) {
80 wp_send_json_error( [ 'message' => __( 'The SureForms AI Middleware encountered an error.', 'sureforms' ) ] );
81 }
82
83 if ( ! empty( $response['error'] ) ) {
84 // If the response has an error, handle it and report it back.
85 // We sanitize before returning so OpenAI / middleware infra details
86 // (URLs, request IDs, model names, account IDs) do not leak to the
87 // client; the raw message is preserved in the debug log via
88 // AI_Helper::sanitize_ai_error_message() when WP_DEBUG[_LOG] is on.
89 $raw = '';
90 if ( is_array( $response['error'] ) && ! empty( $response['error']['message'] ) ) {
91 // If any error message received from OpenAI.
92 $raw = $response['error']['message'];
93 } elseif ( is_string( $response['error'] ) ) {
94 // If any error message received from the middleware server.
95 $raw = $response['error'];
96 }
97 $message = AI_Helper::sanitize_ai_error_message( $raw, 'generate/form' );
98 if ( '' === $message ) {
99 $message = __( 'The SureForms AI Middleware encountered an error.', 'sureforms' );
100 }
101 wp_send_json_error( [ 'message' => $message ] );
102 }
103
104 // Validate the expected form structure piece by piece so we can return specific errors.
105 if ( empty( $response['form'] ) || ! is_array( $response['form'] ) ) {
106 wp_send_json_error(
107 [
108 'message' => __( 'The AI did not return a form. Please refine your prompt and try again.', 'sureforms' ),
109 ]
110 );
111 }
112
113 if ( empty( $response['form']['formTitle'] ) ) {
114 wp_send_json_error(
115 [
116 'message' => __( 'The AI response is missing a form title. Please try again.', 'sureforms' ),
117 ]
118 );
119 }
120
121 if (
122 empty( $response['form']['formFields'] ) ||
123 ! is_array( $response['form']['formFields'] )
124 ) {
125 wp_send_json_error(
126 [
127 'message' => __( 'The AI was unable to generate form fields. Please try again.', 'sureforms' ),
128 ]
129 );
130 }
131
132 wp_send_json_success( $response );
133 }
134
135 }
136