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 / global-settings / global-settings-defaults.php
sureforms / inc / global-settings Last commit date
email-summary.php 7 months ago global-settings-defaults.php 3 months ago global-settings.php 1 month ago
global-settings-defaults.php
273 lines
1 <?php
2 /**
3 * Global Settings Defaults Handler.
4 *
5 * Applies global settings as defaults when creating new forms.
6 *
7 * @package sureforms.
8 * @since 2.9.0
9 */
10
11 namespace SRFM\Inc\Global_Settings;
12
13 use SRFM\Inc\Traits\Get_Instance;
14
15 if ( ! defined( 'ABSPATH' ) ) {
16 exit; // Exit if accessed directly.
17 }
18
19 /**
20 * Global Settings Defaults Class.
21 *
22 * Handles applying global settings as defaults to newly created forms.
23 *
24 * @since 2.9.0
25 */
26 class Global_Settings_Defaults {
27 use Get_Instance;
28
29 /**
30 * Constructor
31 *
32 * @since 2.9.0
33 */
34 public function __construct() {
35 // SF-2815 start: live inheritance via read-time filter.
36 // We hook default_post_metadata so get_post_meta() returns the
37 // current global value when no row exists in wp_postmeta. The
38 // moment a user edits a group, editPost writes a real row and the
39 // filter no longer fires for that key — the form is detached.
40 //
41 // Priority 20 (not 10) is deliberate: WordPress's own
42 // filter_default_metadata, which applies the hardcoded `default`
43 // from register_post_meta, runs at priority 10. We need to run
44 // after it so our global value overrides the static fallback.
45 add_filter( 'default_post_metadata', [ $this, 'inject_global_defaults' ], 20, 4 );
46 // SF-2815 end.
47 }
48
49 /**
50 * Return the current global value for one of the four group meta keys
51 * when the form has no stored value yet.
52 *
53 * Hooked to default_post_metadata, which fires only when no row exists
54 * for the requested key — so the moment a user edits a group, this
55 * filter no longer runs for that key and the form's stored value wins.
56 *
57 * Returns $value unchanged when (a) the meta is not on a sureforms_form
58 * post, (b) the key is not one of ours, or (c) the admin has not
59 * configured a global for that group — in (c) the existing
60 * register_post_meta hardcoded default still applies.
61 *
62 * @param mixed $value Default value (passed in by WP).
63 * @param int $object_id Post ID.
64 * @param string $meta_key Meta key.
65 * @param bool $single Whether single value is requested.
66 * @return mixed
67 * @since 2.9.0
68 */
69 public function inject_global_defaults( $value, $object_id, $meta_key, $single ) {
70 if ( SRFM_FORMS_POST_TYPE !== get_post_type( $object_id ) ) {
71 return $value;
72 }
73
74 switch ( $meta_key ) {
75 case '_srfm_email_notification':
76 $built = self::build_email_notification_meta();
77 break;
78
79 case '_srfm_form_confirmation':
80 $built = self::build_form_confirmation_meta();
81 break;
82
83 case '_srfm_compliance':
84 $built = self::build_compliance_meta();
85 break;
86
87 case '_srfm_form_restriction':
88 $built = self::build_form_restriction_meta();
89 $built = null === $built ? null : wp_json_encode( $built );
90 break;
91
92 default:
93 return $value;
94 }
95
96 if ( null === $built ) {
97 return $value;
98 }
99
100 // $single=false is what the REST API uses (it then takes $all_values[0]),
101 // so we have to wrap our return in an outer array when $single is false —
102 // otherwise REST sees a single object where the schema expects an array
103 // and the editor renders an empty list.
104 return $single ? $built : [ $built ];
105 }
106
107 /**
108 * Build the pre-transformed form meta array from all configured global settings.
109 *
110 * Returns an associative array of meta_key => meta_value in the exact shape
111 * the form post meta expects. Only includes keys where the admin has actually
112 * configured global settings — missing options are omitted so the form falls
113 * back to the hardcoded defaults from register_post_meta().
114 *
115 * Consumed by (a) the block editor localization to seed new-form defaults,
116 * and (b) the save_post hook to write defaults on first save.
117 *
118 * @return array<string, mixed> Map of meta_key => meta_value.
119 * @since 2.9.0
120 */
121 public static function get_global_defaults_as_form_meta() {
122 $meta = [];
123
124 $email_meta = self::build_email_notification_meta();
125 if ( null !== $email_meta ) {
126 $meta['_srfm_email_notification'] = $email_meta;
127 }
128
129 $confirmation_meta = self::build_form_confirmation_meta();
130 if ( null !== $confirmation_meta ) {
131 $meta['_srfm_form_confirmation'] = $confirmation_meta;
132 }
133
134 $compliance_meta = self::build_compliance_meta();
135 if ( null !== $compliance_meta ) {
136 $meta['_srfm_compliance'] = $compliance_meta;
137 }
138
139 $restriction_meta = self::build_form_restriction_meta();
140 if ( null !== $restriction_meta ) {
141 // Form restriction meta is stored as a JSON string (register_meta type 'string').
142 $meta['_srfm_form_restriction'] = wp_json_encode( $restriction_meta );
143 }
144
145 return $meta;
146 }
147
148 /**
149 * Build email notification form meta from global settings.
150 *
151 * @return array<int, array<string, mixed>>|null Form meta array or null if no global settings configured.
152 * @since 2.9.0
153 */
154 private static function build_email_notification_meta() {
155 $global_settings = get_option( 'srfm_email_notification_settings_options', [] );
156
157 if ( empty( $global_settings ) || ! is_array( $global_settings ) ) {
158 return null;
159 }
160
161 return [
162 [
163 'id' => 1,
164 'status' => true,
165 'is_raw_format' => false,
166 'name' => __( 'Admin Notification Email', 'sureforms' ),
167 'email_to' => ! empty( $global_settings['email_to'] ) ? $global_settings['email_to'] : '{admin_email}',
168 'email_reply_to' => ! empty( $global_settings['email_reply_to'] ) ? $global_settings['email_reply_to'] : '{admin_email}',
169 'from_name' => ! empty( $global_settings['from_name'] ) ? $global_settings['from_name'] : '{site_title}',
170 'from_email' => ! empty( $global_settings['from_email'] ) ? $global_settings['from_email'] : '{admin_email}',
171 'email_cc' => ! empty( $global_settings['email_cc'] ) ? $global_settings['email_cc'] : '{admin_email}',
172 'email_bcc' => ! empty( $global_settings['email_bcc'] ) ? $global_settings['email_bcc'] : '{admin_email}',
173 'subject' => ! empty( $global_settings['subject'] ) ? $global_settings['subject'] : sprintf( /* translators: %s: Form title smart tag */ __( 'New Form Submission - %s', 'sureforms' ), '{form_title}' ),
174 'email_body' => ! empty( $global_settings['email_body'] ) ? $global_settings['email_body'] : '{all_data}',
175 ],
176 ];
177 }
178
179 /**
180 * Build form confirmation form meta from global settings.
181 *
182 * @return array<int, array<string, mixed>>|null Form meta array or null if no global settings configured.
183 * @since 2.9.0
184 */
185 private static function build_form_confirmation_meta() {
186 $global_settings = get_option( 'srfm_form_confirmation_settings_options', [] );
187
188 if ( empty( $global_settings ) || ! is_array( $global_settings ) ) {
189 return null;
190 }
191
192 $default_confirmation_message = Global_Settings::get_default_confirmation_message();
193
194 return [
195 [
196 'id' => 1,
197 'confirmation_type' => ! empty( $global_settings['confirmation_type'] ) ? $global_settings['confirmation_type'] : 'same page',
198 'page_url' => ! empty( $global_settings['page_url'] ) ? $global_settings['page_url'] : '',
199 'custom_url' => ! empty( $global_settings['custom_url'] ) ? $global_settings['custom_url'] : '',
200 'message' => ! empty( $global_settings['message'] ) ? $global_settings['message'] : $default_confirmation_message,
201 'submission_action' => ! empty( $global_settings['submission_action'] ) ? $global_settings['submission_action'] : 'hide form',
202 'enable_query_params' => ! empty( $global_settings['enable_query_params'] ),
203 'query_params' => ! empty( $global_settings['query_params'] ) && is_array( $global_settings['query_params'] ) ? $global_settings['query_params'] : [],
204 ],
205 ];
206 }
207
208 /**
209 * Build compliance form meta from global settings.
210 *
211 * @return array<int, array<string, mixed>>|null Form meta array or null if no global settings configured.
212 * @since 2.9.0
213 */
214 private static function build_compliance_meta() {
215 $global_settings = get_option( 'srfm_compliance_settings_options', [] );
216
217 if ( empty( $global_settings ) || ! is_array( $global_settings ) ) {
218 return null;
219 }
220
221 return [
222 [
223 'id' => 'gdpr',
224 'gdpr' => ! empty( $global_settings['gdpr'] ) ? (bool) $global_settings['gdpr'] : false,
225 'do_not_store_entries' => ! empty( $global_settings['do_not_store_entries'] ) ? (bool) $global_settings['do_not_store_entries'] : false,
226 'auto_delete_entries' => ! empty( $global_settings['auto_delete_entries'] ) ? (bool) $global_settings['auto_delete_entries'] : false,
227 'auto_delete_days' => isset( $global_settings['auto_delete_days'] ) ? strval( $global_settings['auto_delete_days'] ) : '',
228 ],
229 ];
230 }
231
232 /**
233 * Build form restriction form meta from global settings.
234 *
235 * Global settings are organized by restriction type (max_entries, ip_restriction, etc.)
236 * while form-level settings are flat. Only max_entries is mapped — form-level meta
237 * has a simpler structure focused on entry limits and scheduling.
238 *
239 * @return array<string, mixed>|null Form meta array (unencoded) or null if no global settings configured.
240 * @since 2.9.0
241 */
242 private static function build_form_restriction_meta() {
243 $global_settings = get_option( 'srfm_form_restriction_settings_options', [] );
244
245 if ( empty( $global_settings ) || ! is_array( $global_settings ) ) {
246 return null;
247 }
248
249 $max_entries = isset( $global_settings['max_entries'] ) && is_array( $global_settings['max_entries'] )
250 ? $global_settings['max_entries']
251 : [];
252
253 return [
254 'status' => ! empty( $max_entries['status'] ) ? (bool) $max_entries['status'] : false,
255 'maxEntries' => isset( $max_entries['maxEntries'] ) ? absint( $max_entries['maxEntries'] ) : 0,
256 'date' => '',
257 'hours' => '12',
258 'minutes' => '00',
259 'meridiem' => 'AM',
260 'message' => ! empty( $max_entries['message'] ) ? $max_entries['message'] : __( "This form is now closed as we've received all the entries.", 'sureforms' ),
261 // Form Scheduling meta - not part of global settings, use defaults.
262 'schedulingStatus' => false,
263 'startDate' => '',
264 'startHours' => '12',
265 'startMinutes' => '00',
266 'startMeridiem' => 'AM',
267 'schedulingNotStartedMessage' => __( 'This form is not yet available. Please check back after the scheduled start time.', 'sureforms' ),
268 'schedulingEndedMessage' => __( 'This form is no longer accepting submissions. The submission period has ended.', 'sureforms' ),
269 ];
270 }
271
272 }
273