PluginProbe ʕ •ᴥ•ʔ
LatePoint – Calendar Booking Plugin for Appointments and Events / 5.2.9
LatePoint – Calendar Booking Plugin for Appointments and Events v5.2.9
5.6.7 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 1 year ago agent_helper.php 1 year ago auth_helper.php 9 months ago blocks_helper.php 1 year ago booking_helper.php 1 year ago bricks_helper.php 1 year ago bundles_helper.php 1 year ago calendar_helper.php 9 months ago carts_helper.php 1 year ago connector_helper.php 9 months ago csv_helper.php 9 months ago customer_helper.php 9 months ago customer_import_helper.php 4 months ago database_helper.php 9 months ago debug_helper.php 1 year ago defaults_helper.php 1 year ago elementor_helper.php 1 year ago email_helper.php 9 months ago encrypt_helper.php 1 year ago events_helper.php 9 months ago form_helper.php 9 months ago icalendar_helper.php 1 year ago image_helper.php 1 year ago invoices_helper.php 9 months ago license_helper.php 1 year ago location_helper.php 1 year ago marketing_systems_helper.php 1 year ago meeting_systems_helper.php 1 year ago menu_helper.php 9 months ago meta_helper.php 1 year ago migrations_helper.php 1 year ago money_helper.php 1 year ago notifications_helper.php 9 months ago order_intent_helper.php 9 months ago orders_helper.php 1 year ago otp_helper.php 9 months ago pages_helper.php 1 year ago params_helper.php 1 year ago payments_helper.php 1 year ago price_breakdown_helper.php 1 year ago process_jobs_helper.php 1 year ago processes_helper.php 1 year ago replacer_helper.php 1 year ago resource_helper.php 1 year ago roles_helper.php 7 months ago router_helper.php 1 year ago service_helper.php 1 year ago sessions_helper.php 1 year ago settings_helper.php 4 months ago short_links_systems_helper.php 9 months ago shortcodes_helper.php 9 months ago sms_helper.php 1 year ago steps_helper.php 5 months ago stripe_connect_helper.php 9 months ago styles_helper.php 9 months ago support_topics_helper.php 1 year ago time_helper.php 9 months ago timeline_helper.php 9 months ago transaction_helper.php 1 year ago transaction_intent_helper.php 1 year ago util_helper.php 7 months ago version_specific_updates_helper.php 9 months ago whatsapp_helper.php 1 year ago work_periods_helper.php 5 months ago wp_datetime.php 1 year ago wp_user_helper.php 1 year ago
settings_helper.php
784 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' => [ 'label' => __( 'First Name', 'latepoint' ), 'required' => true, 'width' => 'os-col-6', 'active' => true ],
537 'last_name' => [ 'label' => __( 'Last Name', 'latepoint' ), 'required' => true, 'width' => 'os-col-6', 'active' => true ],
538 'email' => [ 'label' => __( 'Email Address', 'latepoint' ), 'required' => true, 'width' => 'os-col-6', 'active' => true ],
539 'phone' => [ 'label' => __( 'Phone Number', 'latepoint' ), 'required' => false, 'width' => 'os-col-6', 'active' => true ],
540 'notes' => [ 'label' => __( 'Comments', 'latepoint' ), 'required' => false, 'width' => 'os-col-12', 'active' => true ]
541 ];
542
543 $fields_from_db = OsSettingsHelper::get_settings_value( 'default_fields_for_customer', '' );
544 $fields_from_db_arr = json_decode( $fields_from_db, true );
545 if ( $fields_from_db_arr ) {
546 foreach ( $fields_from_db_arr as $name => $field_from_db ) {
547 if ( isset( $default_fields[ $name ] ) ) {
548 $default_fields[ $name ] = $field_from_db;
549 }
550 }
551 }
552 $default_fields = apply_filters( 'latepoint_default_fields_for_customer', $default_fields );
553
554 return $default_fields;
555 }
556
557 public static function remove_setting_by_name( $name ) {
558 $settings_model = new OsSettingsModel();
559 $settings_model = $settings_model->delete_where( array( 'name' => $name ) );
560 self::reset_loaded_value( $name );
561 }
562
563 public static function save_setting_by_name( $name, $value ) {
564 $settings_model = new OsSettingsModel();
565 $settings_model = $settings_model->where( array( 'name' => $name ) )->set_limit( 1 )->get_results_as_models();
566 if ( $settings_model ) {
567 $settings_model->value = self::prepare_value( $name, $value );
568 } else {
569 $settings_model = new OsSettingsModel();
570 $settings_model->name = $name;
571 $settings_model->value = self::prepare_value( $name, $value );
572 }
573 self::reset_loaded_value( $name );
574
575 return $settings_model->save();
576 }
577
578 public static function reset_loaded_value( $name ) {
579 unset( self::$loaded_values[ $name ] );
580 }
581
582 public static function prepare_value( $name, $value ) {
583 if ( in_array( $name, self::get_encrypted_settings() ) ) {
584 $value = OsEncryptHelper::encrypt_value( $value );
585 }
586 if ( is_array( $value ) ) {
587 $value = maybe_serialize( $value );
588 }
589
590 return $value;
591 }
592
593 public static function get_settings_value( $name, $default = false ) {
594 if ( isset( self::$loaded_values[ $name ] ) ) {
595 return self::$loaded_values[ $name ];
596 }
597 $settings_model = new OsSettingsModel();
598 $settings_model = $settings_model->where( array( 'name' => $name ) )->set_limit( 1 )->get_results_as_models();
599 if ( $settings_model ) {
600 if ( in_array( $name, self::get_encrypted_settings() ) ) {
601 $value = OsEncryptHelper::decrypt_value( $settings_model->value );
602 } else {
603 $value = maybe_unserialize( $settings_model->value );
604 }
605 } else {
606 $value = $default;
607 }
608 self::$loaded_values[ $name ] = $value;
609
610 return self::$loaded_values[ $name ];
611 }
612
613
614 public static function get_any_agent_order() {
615 return self::get_settings_value( 'any_agent_order', LATEPOINT_ANY_AGENT_ORDER_RANDOM );
616 }
617
618 public static function get_day_calendar_min_height() {
619 $height = preg_replace( '/\D/', '', self::get_settings_value( 'day_calendar_min_height', 700 ) );
620 if ( ! $height ) {
621 $height = 700;
622 }
623
624 return $height;
625 }
626
627 public static function get_default_timeblock_interval() {
628 $timeblock_interval = self::get_settings_value( 'timeblock_interval', LATEPOINT_DEFAULT_TIMEBLOCK_INTERVAL );
629 if ( empty( $timeblock_interval ) ) {
630 $timeblock_interval = LATEPOINT_DEFAULT_TIMEBLOCK_INTERVAL;
631 }
632
633 return intval( $timeblock_interval );
634 }
635
636 public static function get_customer_dashboard_url( $include_site_url = true ) {
637 $path = self::get_settings_value( 'page_url_customer_dashboard', '/customer-dashboard' );
638
639 return ( $include_site_url ) ? site_url( $path ) : $path;
640 }
641
642 public static function get_customer_login_url( $include_site_url = true ) {
643 $path = self::get_settings_value( 'page_url_customer_login', '/customer-login' );
644
645 return ( $include_site_url ) ? site_url( $path ) : $path;
646 }
647
648
649 // BOOKING STEPS
650
651 public static function steps_show_service_categories() {
652 return ( self::get_settings_value( 'steps_show_service_categories', 'on' ) == 'on' );
653 }
654
655 public static function steps_show_location_categories() {
656 return ( self::get_settings_value( 'steps_show_location_categories', 'on' ) == 'on' );
657 }
658
659 public static function steps_show_agent_bio() {
660 return ( self::get_settings_value( 'steps_show_agent_bio' ) == 'on' );
661 }
662
663 public static function get_booking_form_color_scheme() {
664 return self::get_settings_value( 'color_scheme_for_booking_form', 'blue' );
665 }
666
667 public static function get_booking_form_border_radius() {
668 return self::get_settings_value( 'border_radius', 'flat' );
669 }
670
671 public static function get_default_phone_country() {
672 return OsSettingsHelper::get_settings_value( 'default_phone_country', 'us' );
673 }
674
675 public static function get_included_phone_countries(): array {
676 if ( OsSettingsHelper::get_settings_value( 'list_of_phone_countries', LATEPOINT_ALL ) == LATEPOINT_ALL ) {
677 return [];
678 } else {
679 return array_map( 'trim', explode( ',', OsSettingsHelper::get_settings_value( 'included_phone_countries', '' ) ) );
680 }
681 }
682
683
684 public static function is_on( string $setting, $default = false ): bool {
685 return ( self::get_settings_value( $setting, $default ) == LATEPOINT_VALUE_ON );
686 }
687
688 public static function is_off( string $setting, $default = false ): bool {
689 return ( self::get_settings_value( $setting, $default ) != LATEPOINT_VALUE_ON );
690 }
691
692 public static function generate_default_form_fields( array $default_fields ) {
693 ?>
694 <div class="os-default-fields" data-route="<?php echo esc_attr( OsRouterHelper::build_route_name( 'form_fields', 'update_default_fields' ) ); ?>">
695 <form>
696 <?php foreach ( $default_fields as $name => $default_field ) {
697 $atts = [];
698 ?>
699 <div class="os-default-field <?php echo $default_field['active'] ? '' : 'is-disabled'; ?>">
700 <?php
701 $active = $default_field['active'] ? 'on' : 'off';
702 $field_name = 'default_fields[' . $name . '][active]';
703 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>';
704 echo OsFormHelper::hidden_field( $field_name, $default_field['active'] );
705 ?>
706 <div class="os-field-name"><?php echo esc_html( $default_field['label'] ); ?></div>
707 <div class="os-field-setting">
708 <?php echo OsFormHelper::checkbox_field( 'default_fields[' . $name . '][required]', __( 'Required?', 'latepoint' ), 'on', $default_field['required'], $atts ); ?>
709 </div>
710 <div class="os-field-setting">
711 <?php echo OsFormHelper::select_field( 'default_fields[' . $name . '][width]', false, array(
712 'os-col-12' => __( 'Full Width', 'latepoint' ),
713 'os-col-6' => __( 'Half Width', 'latepoint' )
714 ), $default_field['width'] ); ?>
715 </div>
716 </div>
717 <?php } ?>
718 </form>
719 </div>
720 <?php
721 }
722
723
724 /**
725 * Get value set for start of week in WordPress, can be from 1-7 (representing Monday-Sunday)
726 * @return mixed
727 */
728 public static function get_start_of_week(): int {
729 $wp_value = intval( get_option( 'start_of_week', 0 ) );
730
731 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
732 }
733
734 public static function get_number_of_records_per_page(): int {
735 return intval( OsSettingsHelper::get_settings_value( 'number_of_records_per_page', 20 ) );
736 }
737
738 public static function can_download_records_as_csv(): bool {
739 return OsAuthHelper::is_admin_logged_in() || self::is_on( 'allow_non_admins_download_csv' );
740 }
741
742 public static function get_link_attributes_for_premium_features() : string {
743 return ' data-os-action="'.OsRouterHelper::build_route_name('settings', 'premium_modal').'" data-os-lightbox-classes="width-600" data-os-output-target="lightbox" ';
744 }
745
746 public static function generate_instant_booking_page_url( array $url_settings ) : string {
747 $url_settings['latepoint'] = 'instant';
748 return OsUtilHelper::get_site_url().'/?'.http_build_query($url_settings);
749 }
750
751 public static function instant_page_background_patterns(): array{
752 return [
753 'pattern_1' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(45deg, #ff9a9e 0%, #fad0c4 99%, #fad0c4 100%);',
754 'pattern_2' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%);',
755 'pattern_3' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #fbc2eb 0%, #a6c1ee 100%);',
756 'pattern_4' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(120deg, #f6d365 0%, #fda085 100%);',
757 'pattern_5' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(180deg, #2af598 0%, #009efd 100%);',
758 'pattern_6' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to right, #6a11cb 0%, #2575fc 100%);',
759 '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;',
760 'pattern_8' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #f77062 0%, #fe5196 100%);',
761 'pattern_9' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #00c6fb 0%, #005bea 100%);',
762 'pattern_10' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #09203f 0%, #537895 100%);',
763 '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;',
764 '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%);',
765 'pattern_13' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #fddb92 0%, #d1fdff 100%);',
766 'pattern_14' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #dfe9f3 0%, white 100%);',
767 'pattern_15' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(-225deg, #5271C4 0%, #B19FFF 48%, #ECA1FE 100%);',
768 '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;',
769 'pattern_17' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to top, #f43b47 0%, #453a94 100%);',
770 'pattern_18' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(to right, #222 0%, #111 100%);',
771 'pattern_19' => 'background-color: transparent; background-size: auto; background-image: linear-gradient(-20deg, #d558c8 0%, #24d292 100%);',
772 ];
773 }
774
775 public static function get_default_wp_role_for_new_customers() : string {
776 if(!wp_roles()->is_role( LATEPOINT_WP_CUSTOMER_ROLE )){
777 OsRolesHelper::register_customer_role();
778 }
779 return OsSettingsHelper::get_settings_value('default_wp_role_for_customer', LATEPOINT_WP_CUSTOMER_ROLE);
780 }
781
782 }
783
784 ?>