PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.2.11
LatePoint – Calendar Booking Plugin for Appointments and Events v5.2.11
5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / helpers / settings_helper.php
latepoint / lib / helpers Last commit date
activities_helper.php 3 months ago agent_helper.php 3 months ago analytics_helper.php 4 months ago auth_helper.php 3 months ago blocks_helper.php 3 months ago booking_helper.php 3 months ago bricks_helper.php 3 months ago bundles_helper.php 3 months ago calendar_helper.php 3 months ago carts_helper.php 3 months ago connector_helper.php 3 months ago csv_helper.php 3 months ago customer_helper.php 3 months ago customer_import_helper.php 3 months ago database_helper.php 3 months ago debug_helper.php 3 months ago defaults_helper.php 3 months ago elementor_helper.php 3 months ago email_helper.php 3 months ago encrypt_helper.php 3 months ago events_helper.php 3 months ago form_helper.php 3 months ago icalendar_helper.php 3 months ago image_helper.php 3 months ago invoices_helper.php 3 months ago license_helper.php 3 months ago location_helper.php 3 months ago marketing_systems_helper.php 3 months ago meeting_systems_helper.php 3 months ago menu_helper.php 3 months ago meta_helper.php 3 months ago migrations_helper.php 3 months ago money_helper.php 3 months ago notifications_helper.php 3 months ago nps_survey_helper.php 3 months ago order_intent_helper.php 3 months ago orders_helper.php 3 months ago otp_helper.php 3 months ago pages_helper.php 3 months ago params_helper.php 3 months ago payments_helper.php 3 months ago price_breakdown_helper.php 3 months ago process_jobs_helper.php 3 months ago processes_helper.php 3 months ago replacer_helper.php 3 months ago resource_helper.php 3 months ago roles_helper.php 3 months ago router_helper.php 3 months ago service_helper.php 3 months ago sessions_helper.php 3 months ago settings_helper.php 3 months ago short_links_systems_helper.php 3 months ago shortcodes_helper.php 3 months ago sms_helper.php 3 months ago steps_helper.php 3 months ago stripe_connect_helper.php 3 months ago styles_helper.php 3 months ago support_topics_helper.php 3 months ago time_helper.php 3 months ago timeline_helper.php 3 months ago transaction_helper.php 3 months ago transaction_intent_helper.php 3 months ago util_helper.php 3 months ago version_specific_updates_helper.php 3 months ago whatsapp_helper.php 3 months ago work_periods_helper.php 3 months ago wp_datetime.php 3 months ago wp_user_helper.php 3 months ago
settings_helper.php
813 lines
1 <?php
2
3 class OsSettingsHelper {
4
5 public static $loaded_values;
6
7
8 private static $encrypted_settings = [
9 'license',
10 'google_calendar_client_secret',
11 'facebook_app_secret',
12 'google_client_secret',
13 'braintree_secret_key',
14 'braintree_merchant_id',
15 'paypal_client_secret',
16 ];
17
18 private static $settings_to_autoload = [
19 'enable_google_login',
20 'time_system',
21 'date_format',
22 'currency_symbol_before',
23 'currency_symbol_after',
24 'phone_format',
25 'steps_show_timezone_selector',
26 'show_booking_end_time',
27 'stripe_publishable_key',
28 'enable_facebook_login',
29 'earliest_possible_booking',
30 'enable_payments_local',
31 'color_scheme_for_booking_form',
32 'latest_possible_booking',
33 'facebook_app_id',
34 'google_client_id',
35 'paypal_client_id',
36 'paypal_currency_iso_code',
37 'paypal_use_braintree_api',
38 'stripe_secret_key',
39 'steps_hide_agent_info',
40 'booking_hash',
41 'payments_environment',
42 'list_of_phone_countries',
43 'included_phone_countries',
44 'wp_users_as_customers',
45 'thousand_separator',
46 'decimal_separator',
47 'number_of_decimals',
48 'default_phone_country',
49 ];
50
51 private static $defaults = [
52 'date_format' => LATEPOINT_DEFAULT_DATE_FORMAT,
53 'time_system' => LATEPOINT_DEFAULT_TIME_SYSTEM,
54 'currency_symbol_before' => '$',
55 ];
56
57 public static function get_business_logo_url() {
58 $default_logo_url = LATEPOINT_IMAGES_URL . 'logo.png';
59
60 return OsImageHelper::get_image_url_by_id( OsSettingsHelper::get_settings_value( 'business_logo' ), 'thumbnail', $default_logo_url );
61 }
62
63 public static function get_business_logo_image( $height = '50px' ) {
64 $url = self::get_business_logo_url();
65
66 return '<img src="' . $url . '" style="height: ' . $height . '; width: auto"/>';
67 }
68
69 public static function get_encrypted_settings() {
70 $encrypted_settings = apply_filters( 'latepoint_encrypted_settings', self::$encrypted_settings );
71
72 return $encrypted_settings;
73 }
74
75
76 public static function get_active_addons(): array {
77 return json_decode( OsSettingsHelper::get_settings_value( 'active_addons', '' ) ) ?? [];
78 }
79
80 public static function get_earliest_possible_booking_restriction( $service_id = 0 ) {
81 if ( ! empty( $service_id ) ) {
82 $service = new OsServiceModel( $service_id );
83 if ( ! $service->is_new_record() && ! empty( $service->earliest_possible_booking ) && OsTimeHelper::is_valid_date( $service->earliest_possible_booking ) ) {
84 return $service->earliest_possible_booking;
85 }
86 }
87 $restriction_from_general_settings = OsSettingsHelper::get_settings_value( 'earliest_possible_booking', '' );
88 if ( OsTimeHelper::is_valid_date( $restriction_from_general_settings ) ) {
89 return $restriction_from_general_settings;
90 } else {
91 return '';
92 }
93 }
94
95 public static function get_latest_possible_booking_restriction( $service_id = 0 ) {
96 if ( ! empty( $service_id ) ) {
97 $service = new OsServiceModel( $service_id );
98 if ( ! $service->is_new_record() && ! empty( $service->latest_possible_booking ) && OsTimeHelper::is_valid_date( $service->latest_possible_booking ) ) {
99 return $service->latest_possible_booking;
100 }
101 }
102 $restriction_from_general_settings = OsSettingsHelper::get_settings_value( 'latest_possible_booking', '' );
103 if ( OsTimeHelper::is_valid_date( $restriction_from_general_settings ) ) {
104 return $restriction_from_general_settings;
105 } else {
106 return '';
107 }
108 }
109
110 /**
111 * @param array $tables
112 *
113 * @return string
114 */
115 public static function export_data( array $tables = [] ): string {
116
117 if ( empty( $tables ) ) {
118 $tables = OsDatabaseHelper::get_all_latepoint_tables();
119 }
120
121 global $wpdb;
122
123 $output = [];
124
125 foreach ( $tables as $table ) {
126 // Check if table exists
127 $table_exists = $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" );
128
129 if ( ! $table_exists ) {
130 continue; // Skip this table if it doesn't exist
131 }
132 // Get all rows from the table
133 $rows = $wpdb->get_results( "SELECT * FROM {$table}", ARRAY_A );
134
135 if ( $rows ) {
136 // Get table create statement
137 $create_table = $wpdb->get_row( "SHOW CREATE TABLE {$table}", ARRAY_N );
138 $var_table = str_replace( $wpdb->prefix, '{{TABLE_PREFIX}}', $table );
139 $create_table = str_replace( $table, $var_table, $create_table );
140
141 $output[ $var_table ] = [
142 'create' => $create_table[1],
143 'prefix' => $wpdb->prefix,
144 'data' => $rows,
145 ];
146 }
147 }
148
149 // Generate filename
150 $filename = 'latepoint_backup_' . date( 'Y-m-d_H-i-s' ) . '.json';
151
152 $json = wp_json_encode( $output, JSON_PRETTY_PRINT );
153
154 // Send headers for file download
155 header( 'Content-Type: application/json' );
156 header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
157 header( 'Content-Length: ' . strlen( $json ) );
158 header( 'Pragma: no-cache' );
159
160 return $json;
161 }
162
163 /**
164 * @param string $data
165 *
166 * @return bool
167 * @throws Exception
168 */
169 public static function import_data( string $data ): bool {
170 global $wpdb;
171
172 if ( empty( $data ) ) {
173 throw new Exception( __( 'Error reading uploaded file', 'latepoint' ) );
174 }
175
176 // update table name from original to new prefix
177 $data = str_replace( '{{TABLE_PREFIX}}', $wpdb->prefix, $data );
178
179 $data = json_decode( $data, true );
180 if ( json_last_error() !== JSON_ERROR_NONE ) {
181 throw new Exception( __( 'Invalid JSON file format', 'latepoint' ) );
182 }
183
184 // Get whitelist of allowed LatePoint tables.
185 $allowed_tables = OsDatabaseHelper::get_all_latepoint_tables();
186
187 // Validate all tables before processing to ensure security.
188 foreach ( $data as $table => $table_data ) {
189 // Security check: Ensure table is in whitelist.
190 if ( ! in_array( $table, $allowed_tables, true ) ) {
191 throw new Exception( sprintf( __( 'Security: Table "%s" is not allowed for import', 'latepoint' ), esc_html( $table ) ) );
192 }
193
194 // Security check: Validate required fields exist.
195 if ( ! isset( $table_data['create'] ) || ! isset( $table_data['data'] ) ) {
196 throw new Exception( sprintf( __( 'Invalid data structure for table "%s"', 'latepoint' ), esc_html( $table ) ) );
197 }
198
199 // Security check: Validate CREATE statement only creates the expected table.
200 $create_statement = $table_data['create'];
201 if ( ! preg_match( '/^\s*CREATE\s+TABLE\s+/i', $create_statement ) ) {
202 throw new Exception( sprintf( __( 'Security: Invalid CREATE statement for table "%s"', 'latepoint' ), esc_html( $table ) ) );
203 }
204
205 // Extract table name from CREATE statement and validate it matches.
206 if ( ! preg_match( '/CREATE\s+TABLE\s+(?:IF\s+NOT\s+EXISTS\s+)?[`\'"]?(' . preg_quote( $table, '/' ) . ')[`\'"]?\s+/i', $create_statement ) ) {
207 throw new Exception( sprintf( __( 'Security: CREATE statement table name mismatch for "%s"', 'latepoint' ), esc_html( $table ) ) );
208 }
209
210 // Security check: Ensure no dangerous SQL keywords in CREATE statement (whole-word match to avoid false positives on column names like "selection_image_id").
211 $dangerous_keywords = array( 'SELECT', 'UNION', 'EXEC', 'EXECUTE', 'CALL', 'LOAD_FILE', 'INTO\s+OUTFILE', 'INTO\s+DUMPFILE' );
212 foreach ( $dangerous_keywords as $keyword ) {
213 if ( preg_match( '/\b' . $keyword . '\b/i', $create_statement ) ) {
214 $display_keyword = str_replace( '\s+', ' ', $keyword );
215 throw new Exception( sprintf( __( 'Security: Dangerous SQL keyword "%s" detected in CREATE statement', 'latepoint' ), esc_html( $display_keyword ) ) );
216 }
217 }
218 }
219
220 // Process each table after validation.
221 foreach ( $data as $table => $table_data ) {
222 // Drop table if exists
223 $wpdb->query( $wpdb->prepare( 'DROP TABLE IF EXISTS %i', $table ) );
224
225 // Create table
226 $result = $wpdb->query( $table_data['create'] );
227 if ( $result === false ) {
228 throw new Exception( sprintf( __( 'Error creating table "%s": %s', 'latepoint' ), esc_html( $table ), $wpdb->last_error ) );
229 }
230
231 // Insert data
232 if ( is_array( $table_data['data'] ) ) {
233 foreach ( $table_data['data'] as $row ) {
234 if ( is_array( $row ) ) {
235 // Security fix: Prevent mass assignment of wordpress_user_id during import.
236 if ( $table === $wpdb->prefix . 'latepoint_customers' ) {
237 unset( $row['wordpress_user_id'] );
238 }
239
240 $insert_result = $wpdb->insert( $table, $row );
241 if ( $insert_result === false ) {
242 // Log error but continue with other rows.
243 error_log( sprintf( 'LatePoint Import: Error inserting data into %s: %s', $table, $wpdb->last_error ) );
244 }
245 }
246 }
247 }
248
249 // Find auto-increment columns and their max values
250 $columns = $wpdb->get_results( $wpdb->prepare( "SHOW COLUMNS FROM %i WHERE Extra = 'auto_increment'", $table ) );
251 if ( is_array( $columns ) ) {
252 foreach ( $columns as $column ) {
253 if ( isset( $column->Field ) ) {
254 // Sanitize column name to prevent SQL injection.
255 $column_name = preg_replace( '/[^a-zA-Z0-9_]/', '', $column->Field );
256
257 // Get the maximum value for this column.
258 $max_id = $wpdb->get_var( $wpdb->prepare( 'SELECT MAX(%i) FROM %i', $column_name, $table ) );
259
260 // Set the auto_increment value to max + 1.
261 if ( $max_id ) {
262 $next_id = intval( $max_id ) + 1;
263 $wpdb->query( $wpdb->prepare( 'ALTER TABLE %i AUTO_INCREMENT = %d', $table, $next_id ) );
264 }
265 }
266 }
267 }
268 }
269
270 return true;
271 }
272
273 public static function run_autoload() {
274 /**
275 * Default settings to be used in SettingsHelper when no value exists in DB
276 *
277 * @param {array} $default_settings Array of key => value pairs of setting names and their default values
278 * @returns {array} The filtered array of default settings
279 *
280 * @since 4.7.2
281 * @hook latepoint_settings_defaults
282 *
283 */
284 self::$defaults = apply_filters( 'latepoint_settings_defaults', self::$defaults );
285 foreach ( self::$defaults as $name => $default ) {
286 self::$loaded_values[ $name ] = $default;
287 }
288
289 $settings_model = new OsSettingsModel();
290
291 /**
292 * Settings to autoload in SettingsHelper on every page load, this is done to reduce the number of queries to DB
293 *
294 * @param {array} $settings Array of setting names to autoload
295 * @returns {array} The filtered array of setting names
296 *
297 * @since 4.7.2
298 * @hook latepoint_settings_to_autoload
299 *
300 */
301 self::$settings_to_autoload = apply_filters( 'latepoint_settings_to_autoload', self::$settings_to_autoload );
302 $settings_arr = $settings_model->select( 'name, value' )->where( array( 'name' => self::$settings_to_autoload ) )->get_results();
303
304
305 if ( $settings_arr && is_array( $settings_arr ) ) {
306 foreach ( $settings_arr as $setting ) {
307 if ( in_array( $setting->name, self::get_encrypted_settings() ) ) {
308 self::$loaded_values[ $setting->name ] = OsEncryptHelper::decrypt_value( $setting->value );
309 } else {
310 self::$loaded_values[ $setting->name ] = $setting->value;
311 }
312 }
313 }
314 }
315
316
317 // ENVIRONMENT SETTINGS
318
319 // BASE ENVIRONMENT
320 public static function is_env_live() {
321 return ( LATEPOINT_ENV == LATEPOINT_ENV_LIVE );
322 }
323
324 public static function is_env_dev() {
325 return ( LATEPOINT_ENV == LATEPOINT_ENV_DEV );
326 }
327
328 public static function is_env_demo() {
329 return ( LATEPOINT_ENV == LATEPOINT_ENV_DEMO );
330 }
331
332 // SMS, EMAILS
333
334 public static function is_sms_allowed() {
335 return LATEPOINT_ALLOW_SMS;
336 }
337
338 public static function is_whatsapp_allowed() {
339 return LATEPOINT_ALLOW_WHATSAPP;
340 }
341
342 public static function is_email_allowed() {
343 return LATEPOINT_ALLOW_EMAILS;
344 }
345
346 // PAYMENTS ENVIRONMENT
347 public static function is_env_payments_live() {
348 return ( self::get_payments_environment() == LATEPOINT_PAYMENTS_ENV_LIVE );
349 }
350
351 public static function is_env_payments_dev() {
352 return ( self::get_payments_environment() == LATEPOINT_PAYMENTS_ENV_DEV );
353 }
354
355 public static function is_env_payments_demo() {
356 return ( self::get_payments_environment() == LATEPOINT_PAYMENTS_ENV_DEMO );
357 }
358
359 public static function get_payments_environment() {
360 return self::get_settings_value( 'payments_environment', LATEPOINT_PAYMENTS_ENV_LIVE );
361 }
362
363
364 public static function append_payment_env_key( string $string, string $force_env = '' ): string {
365 if ( $force_env ) {
366 if ( $force_env == LATEPOINT_PAYMENTS_ENV_DEV ) {
367 $string .= LATEPOINT_PAYMENTS_DEV_SUFFIX;
368 }
369 } else {
370 if ( self::is_env_payments_dev() ) {
371 $string .= LATEPOINT_PAYMENTS_DEV_SUFFIX;
372 }
373 }
374
375 return $string;
376 }
377
378 public static function set_menu_layout_style( $layout ) {
379 $layout = in_array( $layout, [ 'compact', 'full' ] ) ? $layout : 'full';
380 update_user_meta( get_current_user_id(), 'latepoint_admin_menu_style', $layout );
381 }
382
383 public static function get_menu_layout_style(): string {
384 $menu_style = get_user_meta( get_current_user_id(), 'latepoint_admin_menu_style', true );
385
386 // Set default if not set
387 if ( empty( $menu_style ) ) {
388 $menu_style = 'full'; // default value
389 }
390 return $menu_style;
391 }
392
393 public static function get_time_system() {
394 return self::get_settings_value( 'time_system', LATEPOINT_DEFAULT_TIME_SYSTEM );
395 }
396
397 public static function get_date_format() {
398 return self::get_settings_value( 'date_format', LATEPOINT_DEFAULT_DATE_FORMAT );
399 }
400
401 public static function get_date_format_for_js() {
402 $format = strtolower( self::get_date_format() );
403
404 return str_replace( [ 'd', 'm', 'y' ], [ 'dd', 'mm', 'yyyy' ], $format );
405 }
406
407 public static function get_readable_datetime_format( $no_year = false, $no_seconds = true ) {
408 return self::get_readable_date_format( $no_year ) . ', ' . self::get_readable_time_format( $no_seconds );
409 }
410
411 public static function get_order_types_list_for_any_agent_logic(): array {
412 $order_types = [
413 LATEPOINT_ANY_AGENT_ORDER_RANDOM => __( 'Randomly picked agent', 'latepoint' ),
414 LATEPOINT_ANY_AGENT_ORDER_PRICE_HIGH => __( 'Most expensive agent', 'latepoint' ),
415 LATEPOINT_ANY_AGENT_ORDER_PRICE_LOW => __( 'Least expensive agent', 'latepoint' ),
416 LATEPOINT_ANY_AGENT_ORDER_BUSY_HIGH => __( 'Agent with the most bookings on that day', 'latepoint' ),
417 LATEPOINT_ANY_AGENT_ORDER_BUSY_LOW => __( 'Agent with the least bookings on that day', 'latepoint' ),
418 ];
419
420 /**
421 * Get the list of order types for agent selection logic when "ANY" agent is pre-selected in the booking form
422 *
423 * @param {array} $order_types Array of order types
424 *
425 * @returns {array} Filtered array of order types
426 * @since 4.7.6
427 * @hook latepoint_get_order_types_list_for_any_agent_logic
428 *
429 */
430 return apply_filters( 'latepoint_get_order_types_list_for_any_agent_logic', $order_types );
431 }
432
433 public static function get_readable_time_format( $no_seconds = true ) {
434 $seconds = $no_seconds ? '' : ':s';
435 $format = ( self::get_time_system() == '12' ) ? "g:i$seconds a" : "G:i$seconds";
436
437 return $format;
438 }
439
440 public static function get_readable_date_format( $no_year = false, $short_month = false ) {
441 if ( OsSettingsHelper::is_on( 'disable_verbose_date_output' ) ) {
442 return self::get_date_format();
443 }
444 $format = ( $no_year ) ? 'F j' : 'M j, Y';
445 switch ( self::get_date_format() ) {
446 case 'm/d/Y':
447 case 'm.d.Y':
448 $format = ( $no_year ) ? 'F j' : 'M j, Y';
449 break;
450 case 'd.m.Y':
451 case 'd/m/Y':
452 $format = ( $no_year ) ? 'j F' : 'j M, Y';
453 break;
454 case 'Y-m-d':
455 $format = ( $no_year ) ? 'F j' : 'Y, M j';
456 break;
457 }
458 if ( $short_month ) {
459 // if short month is requested - use month shorthand;
460 $format = str_replace( 'F', 'M', $format );
461 }
462
463 return $format;
464 }
465
466
467 public static function get_booking_template_for_calendar() {
468 return OsSettingsHelper::get_settings_value( 'booking_template_for_calendar', '{{service_name}}' );
469 }
470
471
472 public static function get_selected_columns_for_bookings_table() {
473 return OsSettingsHelper::get_settings_value( 'bookings_table_columns', [] );
474 }
475
476 public static function get_available_columns_for_bookings_table() {
477 $available_columns = [];
478
479 $available_columns['customer'] = [
480 'email' => __( 'Email', 'latepoint' ),
481 'phone' => __( 'Phone', 'latepoint' ),
482 ];
483
484 $available_columns['booking'] = [
485 'booking_code' => __( 'Code', 'latepoint' ),
486 'duration' => __( 'Duration', 'latepoint' ),
487 'source_id' => __( 'Source ID', 'latepoint' ),
488 'payment_method' => __( 'Payment Method', 'latepoint' ),
489 'payment_portion' => __( 'Payment Portion', 'latepoint' ),
490 'formatted_price' => __( 'Price', 'latepoint' ),
491 ];
492
493 $available_columns = apply_filters( 'latepoint_bookings_table_columns', $available_columns );
494
495 return $available_columns;
496 }
497
498 public static function force_bite( $request ) {
499 }
500
501 public static function read_encoded( $str ) {
502 return base64_decode( $str );
503 }
504
505 public static function get_db_version() {
506 return get_option( 'latepoint_db_version' );
507 }
508
509 public static function force_release( $request ) {
510 }
511
512 public static function is_enabled_show_dial_code_with_flag() {
513 return ( self::get_settings_value( 'show_dial_code_with_flag', LATEPOINT_VALUE_ON ) == LATEPOINT_VALUE_ON );
514 }
515
516 public static function is_using_google_login() {
517 return self::is_on( 'enable_google_login' );
518 }
519
520 public static function is_using_facebook_login() {
521 return self::is_on( 'enable_facebook_login' );
522 }
523
524 public static function is_using_social_login() {
525 return ( self::is_using_google_login() || self::is_using_facebook_login() );
526 }
527
528 public static function get_steps_support_text() {
529 $default = '<h5>Questions?</h5><p>Call (858) 939-3746 for help</p>';
530
531 return self::get_settings_value( 'steps_support_text', $default );
532 }
533
534 public static function get_default_fields_for_customer() {
535 $default_fields = [
536 'first_name' => [
537 'label' => __( 'First Name', 'latepoint' ),
538 'required' => true,
539 'width' => 'os-col-6',
540 'active' => true,
541 ],
542 'last_name' => [
543 'label' => __( 'Last Name', 'latepoint' ),
544 'required' => true,
545 'width' => 'os-col-6',
546 'active' => true,
547 ],
548 'email' => [
549 'label' => __( 'Email Address', 'latepoint' ),
550 'required' => true,
551 'width' => 'os-col-6',
552 'active' => true,
553 ],
554 'phone' => [
555 'label' => __( 'Phone Number', 'latepoint' ),
556 'required' => false,
557 'width' => 'os-col-6',
558 'active' => true,
559 ],
560 'notes' => [
561 'label' => __( 'Comments', 'latepoint' ),
562 'required' => false,
563 'width' => 'os-col-12',
564 'active' => true,
565 ],
566 ];
567
568 $fields_from_db = OsSettingsHelper::get_settings_value( 'default_fields_for_customer', '' );
569 $fields_from_db_arr = json_decode( $fields_from_db, true );
570 if ( $fields_from_db_arr ) {
571 foreach ( $fields_from_db_arr as $name => $field_from_db ) {
572 if ( isset( $default_fields[ $name ] ) ) {
573 $default_fields[ $name ] = $field_from_db;
574 }
575 }
576 }
577 $default_fields = apply_filters( 'latepoint_default_fields_for_customer', $default_fields );
578
579 return $default_fields;
580 }
581
582 public static function remove_setting_by_name( $name ) {
583 $settings_model = new OsSettingsModel();
584 $settings_model = $settings_model->delete_where( array( 'name' => $name ) );
585 self::reset_loaded_value( $name );
586 }
587
588 public static function save_setting_by_name( $name, $value ) {
589 $settings_model = new OsSettingsModel();
590 $settings_model = $settings_model->where( array( 'name' => $name ) )->set_limit( 1 )->get_results_as_models();
591 if ( $settings_model ) {
592 $settings_model->value = self::prepare_value( $name, $value );
593 } else {
594 $settings_model = new OsSettingsModel();
595 $settings_model->name = $name;
596 $settings_model->value = self::prepare_value( $name, $value );
597 }
598 self::reset_loaded_value( $name );
599
600 return $settings_model->save();
601 }
602
603 public static function reset_loaded_value( $name ) {
604 unset( self::$loaded_values[ $name ] );
605 }
606
607 public static function prepare_value( $name, $value ) {
608 if ( in_array( $name, self::get_encrypted_settings() ) ) {
609 $value = OsEncryptHelper::encrypt_value( $value );
610 }
611 if ( is_array( $value ) ) {
612 $value = maybe_serialize( $value );
613 }
614
615 return $value;
616 }
617
618 public static function get_settings_value( $name, $default = false ) {
619 if ( isset( self::$loaded_values[ $name ] ) ) {
620 return self::$loaded_values[ $name ];
621 }
622 $settings_model = new OsSettingsModel();
623 $settings_model = $settings_model->where( array( 'name' => $name ) )->set_limit( 1 )->get_results_as_models();
624 if ( $settings_model ) {
625 if ( in_array( $name, self::get_encrypted_settings() ) ) {
626 $value = OsEncryptHelper::decrypt_value( $settings_model->value );
627 } else {
628 $value = maybe_unserialize( $settings_model->value );
629 }
630 } else {
631 $value = $default;
632 }
633 self::$loaded_values[ $name ] = $value;
634
635 return self::$loaded_values[ $name ];
636 }
637
638
639 public static function get_any_agent_order() {
640 return self::get_settings_value( 'any_agent_order', LATEPOINT_ANY_AGENT_ORDER_RANDOM );
641 }
642
643 public static function get_day_calendar_min_height() {
644 $height = preg_replace( '/\D/', '', self::get_settings_value( 'day_calendar_min_height', 700 ) );
645 if ( ! $height ) {
646 $height = 700;
647 }
648
649 return $height;
650 }
651
652 public static function get_default_timeblock_interval() {
653 $timeblock_interval = self::get_settings_value( 'timeblock_interval', LATEPOINT_DEFAULT_TIMEBLOCK_INTERVAL );
654 if ( empty( $timeblock_interval ) ) {
655 $timeblock_interval = LATEPOINT_DEFAULT_TIMEBLOCK_INTERVAL;
656 }
657
658 return intval( $timeblock_interval );
659 }
660
661 public static function get_customer_dashboard_url( $include_site_url = true ) {
662 $path = self::get_settings_value( 'page_url_customer_dashboard', '/customer-dashboard' );
663
664 return ( $include_site_url ) ? site_url( $path ) : $path;
665 }
666
667 public static function get_customer_login_url( $include_site_url = true ) {
668 $path = self::get_settings_value( 'page_url_customer_login', '/customer-login' );
669
670 return ( $include_site_url ) ? site_url( $path ) : $path;
671 }
672
673
674 // BOOKING STEPS
675
676 public static function steps_show_service_categories() {
677 return ( self::get_settings_value( 'steps_show_service_categories', 'on' ) == 'on' );
678 }
679
680 public static function steps_show_location_categories() {
681 return ( self::get_settings_value( 'steps_show_location_categories', 'on' ) == 'on' );
682 }
683
684 public static function steps_show_agent_bio() {
685 return ( self::get_settings_value( 'steps_show_agent_bio' ) == 'on' );
686 }
687
688 public static function get_booking_form_color_scheme() {
689 return self::get_settings_value( 'color_scheme_for_booking_form', 'blue' );
690 }
691
692 public static function get_booking_form_border_radius() {
693 return self::get_settings_value( 'border_radius', 'flat' );
694 }
695
696 public static function get_default_phone_country() {
697 return OsSettingsHelper::get_settings_value( 'default_phone_country', 'us' );
698 }
699
700 public static function get_included_phone_countries(): array {
701 if ( OsSettingsHelper::get_settings_value( 'list_of_phone_countries', LATEPOINT_ALL ) == LATEPOINT_ALL ) {
702 return [];
703 } else {
704 return array_map( 'trim', explode( ',', OsSettingsHelper::get_settings_value( 'included_phone_countries', '' ) ) );
705 }
706 }
707
708
709 public static function is_on( string $setting, $default = false ): bool {
710 return ( self::get_settings_value( $setting, $default ) == LATEPOINT_VALUE_ON );
711 }
712
713 public static function is_off( string $setting, $default = false ): bool {
714 return ( self::get_settings_value( $setting, $default ) != LATEPOINT_VALUE_ON );
715 }
716
717 public static function generate_default_form_fields( array $default_fields ) {
718 ?>
719 <div class="os-default-fields" data-route="<?php echo esc_attr( OsRouterHelper::build_route_name( 'form_fields', 'update_default_fields' ) ); ?>">
720 <form>
721 <?php foreach ( $default_fields as $name => $default_field ) {
722 $atts = [];
723 ?>
724 <div class="os-default-field <?php echo $default_field['active'] ? '' : 'is-disabled'; ?>">
725 <?php
726 $active = $default_field['active'] ? 'on' : 'off';
727 $field_name = 'default_fields[' . $name . '][active]';
728 echo '<div class="os-toggler ' . esc_attr( $active ) . '" data-for="' . esc_attr( OsFormHelper::name_to_id( $field_name ) ) . '"><div class="toggler-rail"><div class="toggler-pill"></div></div></div>';
729 echo OsFormHelper::hidden_field( $field_name, $default_field['active'] );
730 ?>
731 <div class="os-field-name"><?php echo esc_html( $default_field['label'] ); ?></div>
732 <div class="os-field-setting">
733 <?php echo OsFormHelper::checkbox_field( 'default_fields[' . $name . '][required]', __( 'Required?', 'latepoint' ), 'on', $default_field['required'], $atts ); ?>
734 </div>
735 <div class="os-field-setting">
736 <?php echo OsFormHelper::select_field(
737 'default_fields[' . $name . '][width]',
738 false,
739 array(
740 'os-col-12' => __( 'Full Width', 'latepoint' ),
741 'os-col-6' => __( 'Half Width', 'latepoint' ),
742 ),
743 $default_field['width']
744 ); ?>
745 </div>
746 </div>
747 <?php } ?>
748 </form>
749 </div>
750 <?php
751 }
752
753
754 /**
755 * Get value set for start of week in WordPress, can be from 1-7 (representing Monday-Sunday)
756 * @return mixed
757 */
758 public static function get_start_of_week(): int {
759 $wp_value = intval( get_option( 'start_of_week', 0 ) );
760
761 return $wp_value ? $wp_value : 7; // in WordPress they start count on sunday and it's 0, we are using PHP Date library that starts week on Monday and it's 1-7
762 }
763
764 public static function get_number_of_records_per_page(): int {
765 return intval( OsSettingsHelper::get_settings_value( 'number_of_records_per_page', 20 ) );
766 }
767
768 public static function can_download_records_as_csv(): bool {
769 return OsAuthHelper::is_admin_logged_in() || self::is_on( 'allow_non_admins_download_csv' );
770 }
771
772 public static function get_link_attributes_for_premium_features(): string {
773 return ' data-os-action="' . OsRouterHelper::build_route_name( 'settings', 'premium_modal' ) . '" data-os-lightbox-classes="width-600" data-os-output-target="lightbox" ';
774 }
775
776 public static function generate_instant_booking_page_url( array $url_settings ): string {
777 $url_settings['latepoint'] = 'instant';
778 return OsUtilHelper::get_site_url() . '/?' . http_build_query( $url_settings );
779 }
780
781 public static function instant_page_background_patterns(): array {
782 return [
783 'pattern_1' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);',
784 'pattern_2' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%);',
785 'pattern_3' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);',
786 'pattern_4' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(120deg, #f6d365 0%, #fda085 100%);',
787 'pattern_5' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(180deg, #2af598 0%, #009efd 100%);',
788 'pattern_6' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);',
789 'pattern_7' => 'background-color: transparent; background-size: auto; background-color: #DCD9D4; background-image: linear-gradient(to bottom, rgba(255,255,255,0.50) 0%, rgba(0,0,0,0.50) 100%), radial-gradient(at 50% 0%, rgba(255,255,255,0.10) 0%, rgba(0,0,0,0.50) 50%); background-blend-mode: soft-light,screen;',
790 'pattern_8' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #f77062 0%, #fe5196 100%);',
791 'pattern_9' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #00c6fb 0%, #005bea 100%);',
792 'pattern_10' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #09203f 0%, #537895 100%);',
793 'pattern_11' => 'background-color: transparent; background-size: auto; background-image: radial-gradient(73% 147%, #EADFDF 59%, #ECE2DF 100%), radial-gradient(91% 146%, rgba(255,255,255,0.50) 47%, rgba(0,0,0,0.50) 100%); background-blend-mode: screen;',
794 'pattern_12' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, lightgrey 0%, lightgrey 1%, #e0e0e0 26%, #efefef 48%, #d9d9d9 75%, #bcbcbc 100%);',
795 'pattern_13' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #fddb92 0%, #d1fdff 100%);',
796 'pattern_14' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #dfe9f3 0%, white 100%);',
797 'pattern_15' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(-225deg, #5271C4 0%, #B19FFF 48%, #ECA1FE 100%);',
798 'pattern_16' => 'background-color: transparent; background-size: auto; background: linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;background-blend-mode: multiply,multiply;',
799 'pattern_17' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #f43b47 0%, #453a94 100%);',
800 'pattern_18' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to right, #222 0%, #111 100%);',
801 'pattern_19' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(-20deg, #d558c8 0%, #24d292 100%);',
802 ];
803 }
804
805 public static function get_default_wp_role_for_new_customers(): string {
806 if ( ! wp_roles()->is_role( LATEPOINT_WP_CUSTOMER_ROLE ) ) {
807 OsRolesHelper::register_customer_role();
808 }
809 return OsSettingsHelper::get_settings_value( 'default_wp_role_for_customer', LATEPOINT_WP_CUSTOMER_ROLE );
810 }
811 }
812
813 ?>