PluginProbe
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz / 2.10.1
SureForms – Contact Form Builder, AI Forms, Payment Form, Survey & Quiz v2.10.1
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 / form-restriction.php
form-restriction.php
283 lines 10.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Create new Form with Template and return the form ID.
4 *
5 * @package sureforms.
6 * @since 1.10.1
7 */
8
9 namespace SRFM\Inc;
10
11 use SRFM\Inc\Database\Tables\Entries;
12 use SRFM\Inc\Traits\Get_Instance;
13
14 if ( ! defined( 'ABSPATH' ) ) {
15 exit; // Exit if accessed directly.
16 }
17
18 /**
19 * Create New Form.
20 *
21 * @since 1.10.1
22 */
23 class Form_Restriction {
24 use Get_Instance;
25
26 /**
27 * Get the restriction settings for a given form.
28 *
29 * @param int $form_id The ID of the form.
30 * @since 1.10.1
31 * @return array Associative array of restriction settings or empty array if invalid.
32 */
33 public static function get_form_restriction_setting( $form_id ) {
34 // Validate the form ID. Must be numeric and non-empty.
35 if ( empty( $form_id ) || ! is_int( $form_id ) ) {
36 return [];
37 }
38
39 // Get the raw restriction meta.
40 $form_restriction_meta = get_post_meta( $form_id, '_srfm_form_restriction', true );
41
42 if ( empty( $form_restriction_meta ) || ! is_string( $form_restriction_meta ) ) {
43 return [];
44 }
45
46 // Decode the meta to an array.
47 $form_restriction = json_decode( $form_restriction_meta, true );
48
49 // Ensure it's a valid array.
50 return is_array( $form_restriction ) ? $form_restriction : [];
51 }
52
53 /**
54 * Check if the form has reached the entry limit.
55 *
56 * @param int $form_id The ID of the form.
57 * @since 1.10.1
58 * @return bool True if form is restricted, false otherwise.
59 */
60 public static function is_form_restricted( $form_id ) {
61
62 if ( empty( $form_id ) || ! is_int( $form_id ) ) {
63 return false; // Invalid form ID.
64 }
65
66 // Check for instant fom preview mode.
67 $srfm_live_mode_data = Helper::get_instant_form_live_data();
68
69 // Skip check in live mode.
70 if (
71 ! empty( $srfm_live_mode_data ) &&
72 is_array( $srfm_live_mode_data ) &&
73 isset( $srfm_live_mode_data['live_mode'] )
74 ) {
75 return false; // Skip check in live mode.
76 }
77
78 // Get parsed restriction settings.
79 $form_restriction = self::get_form_restriction_setting( $form_id );
80
81 // If the form restriction is empty or not an array, or if the status is not set, return false.
82 if ( empty( $form_restriction ) || ! is_array( $form_restriction ) || empty( $form_restriction['status'] ) ) {
83 // Check for form scheduling even if entry restriction is not enabled.
84 $is_outside_schedule = self::is_form_outside_schedule( $form_restriction );
85 return apply_filters( 'srfm_is_form_restricted', $is_outside_schedule, $form_id, $form_restriction, false, false, $is_outside_schedule );
86 }
87
88 $has_entries_limit_reached = self::has_entries_limit_reached( $form_id, $form_restriction );
89 $scheduling_state = self::get_form_scheduling_state( $form_restriction );
90 $is_outside_schedule = 'not_started' === $scheduling_state || 'ended' === $scheduling_state;
91
92 $conversational_form = get_post_meta( $form_id, '_srfm_conversational_form', true );
93 $is_conversational_form_enabled = is_array( $conversational_form ) && isset( $conversational_form['is_cf_enabled'] ) ? $conversational_form['is_cf_enabled'] : false;
94 if ( ( $has_entries_limit_reached || $is_outside_schedule ) && $is_conversational_form_enabled ) {
95 add_filter( 'srfm_show_conversational_form_footer', '__return_false' );
96 }
97
98 /**
99 * If the form has reached the entries limit or is outside schedule, return true.
100 *
101 * @since 1.10.1
102 */
103 return apply_filters(
104 'srfm_is_form_restricted',
105 $has_entries_limit_reached || $is_outside_schedule,
106 $form_id,
107 $form_restriction,
108 $has_entries_limit_reached,
109 false, // Deprecated: $has_time_limit_reached - now handled by scheduling.
110 $is_outside_schedule
111 );
112 }
113
114 /**
115 * Check if the entries limit has been reached for a given form.
116 *
117 * @param int $form_id The ID of the form.
118 * @param array<string, mixed> $form_restriction The form restriction settings.
119 * @since 1.10.1
120 * @return bool True if the entries limit is reached, false otherwise.
121 */
122 public static function has_entries_limit_reached( $form_id, $form_restriction = [] ) {
123
124 if ( ! isset( $form_restriction['maxEntries'] ) || ! is_int( $form_restriction['maxEntries'] ) ) {
125 return false; // Invalid form ID or restriction settings.
126 }
127
128 $max_entries = $form_restriction['maxEntries'];
129 $entries_count = Entries::get_total_entries_by_status( 'all', $form_id );
130
131 if ( ! is_int( $entries_count ) ) {
132 $entries_count = 0; // Ensure entries count is a non-negative integer.
133 }
134
135 /**
136 * Filter the count of entries used to evaluate the Maximum Number of Entries
137 * cap. Allows extensions (e.g. SureForms Pro's Recurring Entry Limit) to
138 * substitute a window-scoped count — entries since the start of today /
139 * the current week / month / year — in place of the lifetime count.
140 *
141 * Returning a value greater than `$entries_count` will trip the cap sooner;
142 * returning a smaller value will defer it. Non-integer return values are
143 * coerced back to a non-negative integer.
144 *
145 * @param int $entries_count Lifetime entry count for the form.
146 * @param int $form_id The ID of the form.
147 * @param array<string, mixed> $form_restriction The form restriction settings.
148 * @since 2.8.2
149 */
150 $entries_count = apply_filters( 'srfm_form_restriction_entries_count', $entries_count, $form_id, $form_restriction );
151
152 // Always coerce to a non-negative integer — covers both non-int returns
153 // from a misbehaving extension AND negative-int returns that would
154 // otherwise silently disable the cap (e.g. -5 >= 100 is false).
155 $entries_count = max( 0, (int) $entries_count );
156
157 return $entries_count >= $max_entries;
158 }
159
160 /**
161 * Check if the form is outside its scheduled time period.
162 *
163 * @param array<string, mixed> $form_restriction The form restriction settings.
164 * @since 2.4.0
165 * @return bool True if form is outside schedule, false otherwise.
166 */
167 public static function is_form_outside_schedule( $form_restriction ) {
168 $scheduling_state = self::get_form_scheduling_state( $form_restriction );
169 return 'not_started' === $scheduling_state || 'ended' === $scheduling_state;
170 }
171
172 /**
173 * Get the appropriate restriction message based on scheduling state.
174 *
175 * @param string $scheduling_state The scheduling state ('not_started', 'ended', 'active', or 'disabled').
176 * @param array<string, mixed> $form_restriction The form restriction settings.
177 * @since 2.4.0
178 * @return string The appropriate restriction message.
179 */
180 public static function get_restriction_message_by_state( $scheduling_state, $form_restriction ) {
181 if ( 'not_started' === $scheduling_state ) {
182 $message = $form_restriction['schedulingNotStartedMessage'] ?? __( 'This form is not yet available. Check back after the scheduled start time.', 'sureforms' );
183 return is_string( $message ) ? $message : __( 'This form is not yet available. Check back after the scheduled start time.', 'sureforms' );
184 }
185
186 if ( 'ended' === $scheduling_state ) {
187 $message = $form_restriction['schedulingEndedMessage'] ?? __( 'This form is no longer accepting submissions. The submission period has ended.', 'sureforms' );
188 return is_string( $message ) ? $message : __( 'This form is no longer accepting submissions. The submission period has ended.', 'sureforms' );
189 }
190
191 // Default to entry limit message.
192 $message = $form_restriction['message'] ?? Translatable::get_default_form_restriction_message();
193 return is_string( $message ) ? $message : Translatable::get_default_form_restriction_message();
194 }
195
196 /**
197 * Get the scheduling state for a form.
198 *
199 * @param array<string, mixed> $form_restriction The form restriction settings.
200 * @since 2.4.0
201 * @return string 'not_started', 'ended', 'active', or 'disabled'.
202 */
203 public static function get_form_scheduling_state( $form_restriction ) {
204 $scheduling_status = $form_restriction['schedulingStatus'] ?? false;
205
206 // Start date/time.
207 $start_date = $form_restriction['startDate'] ?? '';
208 $start_hours = Helper::get_string_value( $form_restriction['startHours'] ?? '12' );
209 $start_minutes = Helper::get_string_value( $form_restriction['startMinutes'] ?? '00' );
210 $start_meridiem = Helper::get_string_value( $form_restriction['startMeridiem'] ?? 'AM' );
211
212 // End date/time.
213 $end_date = $form_restriction['date'] ?? '';
214 $end_hours = Helper::get_string_value( $form_restriction['hours'] ?? '12' );
215 $end_minutes = Helper::get_string_value( $form_restriction['minutes'] ?? '00' );
216 $end_meridiem = Helper::get_string_value( $form_restriction['meridiem'] ?? 'PM' );
217
218 $dt = new \DateTime( 'now', wp_timezone() );
219 $current_timestamp = $dt->getTimestamp();
220
221 // Check if before start time (only if scheduling is enabled).
222 if ( $scheduling_status && ! empty( $start_date ) && is_string( $start_date ) ) {
223 $start_timestamp = Helper::get_timestamp_from_string( $start_date, $start_hours, $start_minutes, $start_meridiem );
224
225 if ( false !== $start_timestamp && is_int( $start_timestamp ) && $current_timestamp < $start_timestamp ) {
226 return 'not_started';
227 }
228 }
229
230 // Check if after end time (works for both scheduling and simple time limit).
231 if ( $scheduling_status && ! empty( $end_date ) && is_string( $end_date ) ) {
232 $end_timestamp = Helper::get_timestamp_from_string( $end_date, $end_hours, $end_minutes, $end_meridiem );
233
234 if ( false !== $end_timestamp && is_int( $end_timestamp ) && $current_timestamp > $end_timestamp ) {
235 return 'ended';
236 }
237 }
238
239 // If scheduling is disabled but we haven't passed the end date, return 'disabled'.
240 // If scheduling is enabled and we're within the window, return 'active'.
241 return $scheduling_status ? 'active' : 'disabled';
242 }
243
244 /**
245 * Display the form restriction message.
246 *
247 * @param int $form_id The ID of the form.
248 * @since 1.10.1
249 * @return string|false The HTML markup for the restriction message or false if no restriction is set.
250 */
251 public static function display_form_restriction_message( $form_id ) {
252 // Get parsed restriction settings.
253 $form_restriction = self::get_form_restriction_setting( $form_id );
254
255 // Get the scheduling state and appropriate message.
256 $scheduling_state = self::get_form_scheduling_state( $form_restriction );
257 $form_restriction_message = self::get_restriction_message_by_state( $scheduling_state, $form_restriction );
258
259 $form_restriction_message = apply_filters( 'srfm_form_restriction_message', $form_restriction_message, $form_id, $form_restriction );
260
261 ob_start();
262 ?>
263 <div class="srfm-form-container srfm-form-restriction-wrapper">
264 <div class="srfm-form-restriction-message" role="alert" aria-live="assertive">
265 <span class="srfm-form-restriction-icon" aria-hidden="true">
266 <?php
267 echo wp_kses(
268 Helper::fetch_svg( 'instant-form-warning', 'srfm-form-restriction-icon', 'aria-hidden="true"' ),
269 Helper::$allowed_tags_svg
270 );
271 ?>
272 </span>
273 <p class="srfm-form-restriction-text">
274 <?php echo esc_html( $form_restriction_message ); ?>
275 </p>
276 </div>
277 </div>
278 <?php
279 return ob_get_clean();
280 }
281
282 }
283