PluginProbe
Timetics – Appointment Booking Calendar & Scheduling / 1.0.64
Timetics – Appointment Booking Calendar & Scheduling v1.0.64
1.0.64 1.0.62 1.0.63 1.0.61 1.0.60 1.0.59 1.0.58 1.0.57 1.0.56 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 All 65 releases
← All changes | core/settings/api-settings.php +52 -0 1.0.62 → 1.0.64 View file →
@@ -153,9 +153,33 @@
153 153 */
154 154 public function update_settings( $request ) {
155 155 $options = json_decode( $request->get_body(), true );
156 156
157 + if ( ! is_array( $options ) ) {
158 + return new \WP_Error(
159 + 'timetics_invalid_settings',
160 + __( 'Settings must be sent as a JSON object.', 'timetics' ),
161 + [ 'status' => 400 ]
162 + );
163 + }
164 +
157 165 /**
166 + * Filter the settings payload before any of it is checked or saved.
167 + *
168 + * Runs before the checks below, so a listener's result passes through
169 + * them like the raw request does. Add-ons use it to clean their own
170 + * keys. It is an extension point, not the sanitization for core keys.
171 + *
172 + * @since 1.0.63
173 + *
174 + * @param array $options Settings payload from the request body.
175 + */
176 + $filtered = apply_filters( 'timetics_settings_update_params', $options );
177 +
178 + // A listener returning a non-array must not make the save below write nothing.
179 + $options = is_array( $filtered ) ? $filtered : $options;
180 +
181 + /**
158 182 * Added temporary for leagacy sass. It will remove in future.
159 183 */
160 184 $data = [
161 185 'status_code' => 200,
@@ -205,8 +229,12 @@
205 229 if ( ! empty( $options['zapier_webhook'] ) && $options['zapier_webhook'] && apply_filters( 'timetics/admin/settings/zapier_webhook', false ) ) {
206 230 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'zapier', timetics_get_settings() ) );
207 231 }
208 232
233 + if ( ! empty( $options['flowmattic_webhook'] ) && $options['flowmattic_webhook'] && apply_filters( 'timetics/admin/settings/flowmattic_webhook', false ) ) {
234 + return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'flowmattic', timetics_get_settings() ) );
235 + }
236 +
209 237 if (!empty($options['google_app_client_id']) && $options['google_app_client_id'] && apply_filters('timetics/admin/settings/google_calendar', false)) {
210 238 return rest_ensure_response(apply_filters('timetics/admin/settings/error_data', $data, 'google-calendar', timetics_get_settings()));
211 239 }
212 240
@@ -221,8 +249,12 @@
221 249 if ( ! empty( $options['apple_calendar'] ) && $options['apple_calendar'] && apply_filters( 'timetics/admin/settings/apple_calendar', false ) ) {
222 250 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'paypal', timetics_get_settings() ) );
223 251 }
224 252
253 + if ( ! empty( $options['uncanny_automator'] ) && $options['uncanny_automator'] && apply_filters( 'timetics/admin/settings/uncanny_automator', false ) ) {
254 + return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'uncanny_automator', timetics_get_settings() ) );
255 + }
256 +
225 257 if (!empty($options['twillo_message']) && $options['twillo_message'] && apply_filters('timetics/admin/settings/twillo_messaging', false)) {
226 258 return rest_ensure_response(apply_filters('timetics/admin/settings/error_data', $data, 'twillo_messaging', timetics_get_settings()));
227 259 }
228 260
@@ -227,8 +259,28 @@
227 259 }
228 260
229 261 if ( $options ) {
230 262 foreach ( $options as $key => $value ) {
263 + // Webhook URLs are pasted from FlowMattic, so keep them a URL.
264 + if ( 'flowmattic_webhook' === $key ) {
265 + $value = esc_url_raw( $value );
266 + }
267 +
268 + // Stored as the strings `yes`/`no`: this
269 + // option defaults to on, and timetics_get_option() treats an
270 + // empty value as "unset" and hands back the default, so a
271 + // boolean false could never switch it off.
272 + if ( 'uncanny_automator' === $key ) {
273 + $value = $value && 'no' !== $value ? 'yes' : 'no';
274 + }
275 +
276 + // Clamp: the cleanup cron only runs every 5 minutes, so a
277 + // lower value would silently do nothing and 0/negative would
278 + // expire bookings instantly.
279 + if ( 'unpaid_booking_expiry_minutes' === $key ) {
280 + $value = max( 5, absint( $value ) );
281 + }
282 +
231 283 timetics_update_option( $key, $value );
232 284 }
233 285 }
234 286