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
timetics / core / settings / api-settings.php

api-settings.php in Timetics – Appointment Booking Calendar & Scheduling 1.0.64, at core/settings/api-settings.php

339 lines 13.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class Api Settings
4 *
5 * @package Timetics
6 */
7 namespace Timetics\Core\Settings;
8
9 defined( 'ABSPATH' ) || exit;
10
11 use Timetics\Base\Api;
12 use Timetics\Core\Admin\Hooks;
13 use Timetics\Utils\Singleton;
14
15 class Api_Settings extends Api {
16 use Singleton;
17
18 /**
19 * Store api namespace
20 *
21 * @var string
22 */
23 protected $namespace = 'timetics/v1';
24
25 /**
26 * Store rest base
27 *
28 * @var string
29 */
30 protected $rest_base = 'settings';
31
32 /**
33 * Register rest route
34 *
35 * @return void
36 */
37 public function register_routes() {
38 register_rest_route(
39 $this->namespace, $this->rest_base, [
40 [
41 'methods' => \WP_REST_Server::READABLE,
42 'callback' => [$this, 'get_settings'],
43 'permission_callback' => function () {
44 // The public booking app needs a small, explicitly safe
45 // settings payload. get_settings() filters it by role.
46 return true;
47 },
48 ],
49 [
50 'methods' => \WP_REST_Server::EDITABLE,
51 'callback' => [$this, 'update_settings'],
52 'permission_callback' => function () {
53 return current_user_can( 'manage_options' );
54 },
55 ],
56 ]
57 );
58
59 register_rest_route(
60 $this->namespace, $this->rest_base . '/business', [
61 [
62 'methods' => \WP_REST_Server::CREATABLE,
63 'callback' => [$this, 'setup_business'],
64 'permission_callback' => function () {
65 return current_user_can( 'manage_options' );
66 },
67 ],
68 ]
69 );
70
71 register_rest_route(
72 $this->namespace, $this->rest_base . '/business/categories', [
73 [
74 'methods' => \WP_REST_Server::READABLE,
75 'callback' => [$this, 'get_busyness_categories'],
76 'permission_callback' => function () {
77 return current_user_can( 'manage_options' );
78 },
79 ],
80 ]
81 );
82 }
83
84 /**
85 * Get settings
86 *
87 * @return JSON
88 */
89 public function get_settings() {
90 $settings = apply_filters( 'timetics_settings', timetics_get_settings() );
91
92 // The booking and staff interfaces need non-sensitive display and scheduling
93 // settings. Never send credentials or webhook URLs to non-administrators.
94 if ( ! current_user_can( 'manage_options' ) ) {
95 $settings = $this->get_staff_safe_settings( $settings );
96 }
97
98 $data = [
99 'status_code' => 200,
100 'success' => 1,
101 'message' => esc_html__( 'Get all settings', 'timetics' ),
102 'data' => $settings,
103 ];
104
105 return rest_ensure_response( $settings );
106 }
107
108 /**
109 * Return only settings that staff need to use the admin interface.
110 *
111 * This is deliberately an allow-list. New settings remain private until they
112 * have been reviewed and explicitly added here.
113 *
114 * @param array $settings Plugin settings.
115 *
116 * @return array
117 */
118 private function get_staff_safe_settings( $settings ) {
119 $safe_keys = [
120 'availability',
121 'apple_calendar',
122 'blocked_days',
123 'busyness_category',
124 'calendar_locale',
125 'currency',
126 'custom_fields',
127 'default_booking_status',
128 'guest_enabled',
129 'guest_limit',
130 'google_calendar',
131 'locale_timezone',
132 'paypal_status',
133 'primary_color',
134 'remainder_time',
135 'secondary_color',
136 'slot_interval',
137 'stripe_status',
138 'outlook_calendar',
139 'wc_integration',
140 'wc_checkout_url',
141 'zoom_connection_type',
142 ];
143
144 return array_intersect_key( (array) $settings, array_flip( $safe_keys ) );
145 }
146
147 /**
148 * Update settings
149 *
150 * @param WP_Rest_Request $request
151 *
152 * @return JSON
153 */
154 public function update_settings( $request ) {
155 $options = json_decode( $request->get_body(), true );
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
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 /**
182 * Added temporary for leagacy sass. It will remove in future.
183 */
184 $data = [
185 'status_code' => 200,
186 'success' => 1,
187 'message' => esc_html__( 'Settings successfully updated', 'timetics' ),
188 'data' => timetics_get_settings(),
189 ];
190
191 // custom domain
192 if (!empty($options['custom_domain_url']) && isset($options['custom_domain_url'])) {
193 $custom_domain_data = [
194 'custom_domain_url' => $options['custom_domain_url'],
195 'network_slug' => $options['network_slug'],
196 ];
197 do_action('timetics_custom_domain_data', $custom_domain_data);
198 }
199
200
201 if ( !empty($options['schedule']) && $options['schedule'] && apply_filters('timetics/staff/member/availability', false)) {
202 return rest_ensure_response( apply_filters( 'timetics/admin/staff/error_data', $data, 'availability_update' ) );
203 }
204
205 if ( !empty($options['availability']) && $options['availability'] && apply_filters('timetics/staff/meeting/availability', false)) {
206 return rest_ensure_response( apply_filters( 'timetics/admin/appointment/error_data', $data, 'availability_update' ) );
207 }
208
209 if ( ! empty( $options['custom_fields'] ) && apply_filters( 'timetics/admin/settings/custom_fields', false, $options['custom_fields'] ) ) {
210 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'custom_fields', timetics_get_settings() ) );
211 }
212
213 if ( ! empty( $options['paypal_status'] ) && $options['paypal_status'] && apply_filters( 'timetics/admin/settings/paypal', false ) ) {
214 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'paypal', timetics_get_settings() ) );
215 }
216
217 if ( ! empty( $options['zoom_client_secret'] ) && $options['zoom_client_secret'] && apply_filters( 'timetics/admin/settings/zoom', false ) ) {
218 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'zoom', timetics_get_settings() ) );
219 }
220
221 if ( ! empty( $options['fluentcrm_webhook'] ) && $options['fluentcrm_webhook'] && apply_filters( 'timetics/admin/settings/fluentcrm_webhook', false ) ) {
222 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'fluent_crm', timetics_get_settings() ) );
223 }
224
225 if ( ! empty( $options['pabbly_webhook'] ) && $options['pabbly_webhook'] && apply_filters( 'timetics/admin/settings/pabbly_webhook', false ) ) {
226 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'pablly', timetics_get_settings() ) );
227 }
228
229 if ( ! empty( $options['zapier_webhook'] ) && $options['zapier_webhook'] && apply_filters( 'timetics/admin/settings/zapier_webhook', false ) ) {
230 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'zapier', timetics_get_settings() ) );
231 }
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
237 if (!empty($options['google_app_client_id']) && $options['google_app_client_id'] && apply_filters('timetics/admin/settings/google_calendar', false)) {
238 return rest_ensure_response(apply_filters('timetics/admin/settings/error_data', $data, 'google-calendar', timetics_get_settings()));
239 }
240
241 if ( ! empty( $options['google_app_client_secret'] ) && $options['google_app_client_secret'] && apply_filters( 'timetics/admin/settings/google-calendar', false ) ) {
242 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'google-calendar', timetics_get_settings() ) );
243 }
244
245 if ( ! empty( $options['outlook_calendar'] ) && $options['outlook_calendar'] && apply_filters( 'timetics/admin/settings/outlook_calendar', false ) ) {
246 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'outlook', timetics_get_settings() ) );
247 }
248
249 if ( ! empty( $options['apple_calendar'] ) && $options['apple_calendar'] && apply_filters( 'timetics/admin/settings/apple_calendar', false ) ) {
250 return rest_ensure_response( apply_filters( 'timetics/admin/settings/error_data', $data, 'paypal', timetics_get_settings() ) );
251 }
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
257 if (!empty($options['twillo_message']) && $options['twillo_message'] && apply_filters('timetics/admin/settings/twillo_messaging', false)) {
258 return rest_ensure_response(apply_filters('timetics/admin/settings/error_data', $data, 'twillo_messaging', timetics_get_settings()));
259 }
260
261 if ( $options ) {
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
283 timetics_update_option( $key, $value );
284 }
285 }
286
287 $data['data'] = timetics_get_settings();
288
289 return rest_ensure_response( $data );
290 }
291
292 /**
293 * Business setup
294 *
295 * @param WP_Rest_Request $request
296 *
297 * @return void
298 */
299 public function setup_business( $request ) {
300 $data = json_decode( $request->get_body(), true );
301
302 $email = ! empty( $data['email'] ) ? $data['email'] : '';
303
304 $body = array(
305 'email' => $email,
306 );
307
308 $response_user = wp_remote_post( 'https://arraytics.com/?fluentcrm=1&route=contact&hash=0d9cd3d1-514d-4e1a-9147-09dfd5f9e997', ['body' => $body] );
309
310 $response = [
311 'status' => 200,
312 'success' => 1,
313 'message' => __( 'Successfully updated business', 'timetics' ),
314 ];
315
316 return rest_ensure_response( $response );
317 }
318
319 /**
320 * Get busyness categories
321 *
322 * @param WP_Rest_Request $request
323 *
324 * @return JSON
325 */
326 public function get_busyness_categories( $request ) {
327 $busyness_categories = timetics_get_busyness_categories();
328
329 $response = [
330 'success' => 1,
331 'status_code' => 200,
332 'data' => $busyness_categories,
333 ];
334
335 return rest_ensure_response( $response );
336 }
337
338 }
339