PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.8.2
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.8.2
2.12.6 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 All 96 releases
sureforms / inc / forms-data.php

forms-data.php in SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz 2.8.2, at inc/forms-data.php

259 lines 7.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Sureforms get forms title and Ids.
4 *
5 * @package sureforms.
6 * @since 0.0.1
7 */
8
9 namespace SRFM\Inc;
10
11 use SRFM\Inc\Database\Tables\Entries;
12 use SRFM\Inc\Traits\Get_Instance;
13 use WP_Error;
14 use WP_REST_Response;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit; // Exit if accessed directly.
18 }
19
20 /**
21 * Load Defaults Class.
22 *
23 * @since 0.0.1
24 */
25 class Forms_Data {
26 use Get_Instance;
27
28 /**
29 * Constructor
30 *
31 * @since 0.0.1
32 */
33 public function __construct() {
34 add_action( 'rest_api_init', [ $this, 'register_custom_endpoint' ] );
35 }
36
37 /**
38 * Add custom API Route load-form-defaults
39 *
40 * @return void
41 * @since 0.0.1
42 */
43 public function register_custom_endpoint() {
44 register_rest_route(
45 'sureforms/v1',
46 '/forms-data',
47 [
48 'methods' => 'GET',
49 'callback' => [ $this, 'load_forms' ],
50 'permission_callback' => [ $this, 'get_form_permissions_check' ],
51 ]
52 );
53 }
54
55 /**
56 * Checks whether a given request has permission to read the form.
57 *
58 * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
59 * @since 0.0.1
60 */
61 public function get_form_permissions_check() {
62 if ( Helper::current_user_can( 'edit_posts' ) ) {
63 return true;
64 }
65
66 return new \WP_Error(
67 'rest_cannot_view',
68 __( 'Sorry, you are not allowed to view the form.', 'sureforms' ),
69 [ 'status' => \rest_authorization_required_code() ]
70 );
71 }
72
73 /**
74 * Handle Form status
75 *
76 * @param \WP_REST_Request $request Full details about the request.
77 *
78 * @return WP_REST_Response
79 * @since 0.0.1
80 */
81 public function load_forms( $request ) {
82
83 $nonce = Helper::get_string_value( $request->get_header( 'X-WP-Nonce' ) );
84
85 if ( ! wp_verify_nonce( sanitize_text_field( $nonce ), 'wp_rest' ) ) {
86 wp_send_json_error(
87 [
88 'data' => __( 'Nonce verification failed.', 'sureforms' ),
89 'status' => false,
90 ]
91 );
92 }
93
94 $args = [
95 'post_type' => 'sureforms_form',
96 'post_status' => 'publish',
97 'posts_per_page' => -1, // Retrieve all posts.
98 ];
99
100 $form_posts = get_posts( $args );
101
102 $data = [];
103
104 foreach ( $form_posts as $post ) {
105 $data[] = [
106 'id' => $post->ID,
107 'title' => $post->post_title,
108 'content' => $post->post_content,
109 ];
110 }
111
112 return new WP_REST_Response( $data );
113 }
114
115 /**
116 * Get forms list for the forms listing page.
117 *
118 * @param \WP_REST_Request $request Full details about the request.
119 * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
120 * @since 2.0.0
121 */
122 public function get_forms_list( $request ) {
123 $nonce = sanitize_text_field( Helper::get_string_value( $request->get_header( 'X-WP-Nonce' ) ) );
124
125 Helper::verify_nonce_and_capabilities( 'rest', $nonce, 'wp_rest' );
126
127 // Get and validate request parameters.
128 $page = max( 1, Helper::get_integer_value( $request->get_param( 'page' ) ) );
129 $status = sanitize_text_field( $request->get_param( 'status' ) );
130
131 // Get per_page from option first, then request parameter, with fallback to 10.
132 $saved_per_page = Helper::get_srfm_option( 'forms_per_page', 10 );
133 $request_per_page = $request->get_param( 'per_page' );
134 $per_page = $request_per_page ? min( 100, max( 1, Helper::get_integer_value( $request_per_page ) ) ) : $saved_per_page;
135
136 // Save per_page to option if it came from request.
137 if ( $request_per_page && 'trash' !== $status && 1 < $request_per_page ) {
138 Helper::update_srfm_option( 'forms_per_page', $per_page );
139 }
140
141 $search = sanitize_text_field( $request->get_param( 'search' ) );
142 $orderby = sanitize_text_field( $request->get_param( 'orderby' ) );
143 $order = sanitize_text_field( $request->get_param( 'order' ) );
144 $date_from = sanitize_text_field( $request->get_param( 'after' ) );
145 $date_to = sanitize_text_field( $request->get_param( 'before' ) );
146
147 // Build query arguments.
148 $args = [
149 'post_type' => SRFM_FORMS_POST_TYPE,
150 'post_status' => 'any' === $status ? [ 'publish', 'draft' ] : $status,
151 'posts_per_page' => $per_page,
152 'paged' => $page,
153 'orderby' => $orderby,
154 'order' => $order,
155 ];
156
157 // Add date range filtering.
158 if ( ! empty( $date_from ) || ! empty( $date_to ) ) {
159 $date_query = [];
160 // Handle 'after' date.
161 if ( ! empty( $date_from ) ) {
162 $date_query['after'] = $date_from;
163 }
164
165 // Handle 'before' date - add 1 day to include the full end date.
166 if ( ! empty( $date_to ) ) {
167 $end_date = new \DateTime( $date_to );
168 $end_date->add( new \DateInterval( 'P1D' ) ); // Add 1 day.
169 $date_query['before'] = $end_date->format( 'Y-m-d' );
170 }
171
172 $date_query['inclusive'] = true;
173 $args['date_query'] = [ $date_query ];
174 }
175
176 // Add search parameter.
177 if ( ! empty( $search ) ) {
178 if ( is_numeric( $search ) ) {
179 // Numeric search: match by form ID and title (e.g., "2024 Survey").
180 $numeric_search = $search;
181 $where_filter = static function ( $where, $query ) use ( $numeric_search ) {
182 if ( ! $query->get( 'srfm_numeric_search' ) ) {
183 return $where;
184 }
185 global $wpdb;
186 $where .= $wpdb->prepare(
187 " AND ({$wpdb->posts}.ID = %d OR {$wpdb->posts}.post_title LIKE %s)",
188 absint( $numeric_search ),
189 '%' . $wpdb->esc_like( $numeric_search ) . '%'
190 );
191 return $where;
192 };
193
194 add_filter( 'posts_where', $where_filter, 10, 2 );
195 $args['srfm_numeric_search'] = true;
196 } else {
197 // Text search: match by title only.
198 $args['s'] = $search;
199 $args['search_columns'] = [ 'post_title' ];
200 }
201 }
202
203 // Execute query — use try/finally to guarantee filter cleanup.
204 try {
205 $query = new \WP_Query( $args );
206 } finally {
207 if ( ! empty( $search ) && is_numeric( $search ) && isset( $where_filter ) ) {
208 remove_filter( 'posts_where', $where_filter, 10 );
209 }
210 }
211
212 $forms = [];
213 /**
214 * Post object from the query.
215 *
216 * @var \WP_Post $post */
217 foreach ( $query->posts as $post ) {
218 $forms[] = $this->prepare_form_for_listing( $post );
219 }
220
221 // Prepare response.
222 $response_data = [
223 'forms' => $forms,
224 'total' => Helper::get_integer_value( $query->found_posts ),
225 'total_pages' => Helper::get_integer_value( $query->max_num_pages ),
226 'current_page' => $page,
227 'per_page' => $per_page,
228 ];
229
230 return new WP_REST_Response( $response_data, 200 );
231 }
232
233 /**
234 * Prepare a single form for the listing response.
235 *
236 * @param \WP_Post $post Post object.
237 * @return array<mixed> Prepared form data for listing.
238 * @since 2.0.0
239 */
240 private function prepare_form_for_listing( $post ) {
241 $form_id = $post->ID;
242
243 // Get entries count.
244 $entries_count = Helper::get_integer_value( Entries::get_total_entries_by_status( 'all', $form_id ) );
245
246 return [
247 'id' => $form_id,
248 'title' => $post->post_title,
249 'status' => $post->post_status,
250 'date_created' => mysql_to_rfc3339( $post->post_date ),
251 'date_modified' => mysql_to_rfc3339( $post->post_modified ),
252 'entries_count' => $entries_count,
253 'shortcode' => "[sureforms id='{$form_id}']",
254 'edit_url' => admin_url( "post.php?post={$form_id}&action=edit" ),
255 'frontend_url' => get_permalink( $form_id ),
256 ];
257 }
258 }
259