= 1 && $day <= 5 ) { $weekdays[ $day ][] = array( 'start_second' => 9 * HOUR_IN_SECONDS, 'end_second' => 18 * HOUR_IN_SECONDS, ); } } return array( 'enabled' => 'Off', 'default' => array( 'weekdays' => $weekdays, ), 'resources' => array(), ); } /** * Normalize Working Time settings. * * @param mixed $settings Settings. * * @return array */ function wpbc_working_time__normalize_settings( $settings ) { $defaults = wpbc_working_time__get_default_settings(); if ( ! is_array( $settings ) ) { return $defaults; } $settings = wp_parse_args( $settings, $defaults ); $settings['enabled'] = ( 'On' === (string) $settings['enabled'] ) ? 'On' : 'Off'; $settings['default'] = array( 'weekdays' => wpbc_working_time__normalize_weekday_intervals( isset( $settings['default']['weekdays'] ) ? $settings['default']['weekdays'] : array() ), ); if ( ! is_array( $settings['resources'] ) ) { $settings['resources'] = array(); } foreach ( $settings['resources'] as $resource_id => $resource_settings ) { $resource_id = absint( $resource_id ); if ( empty( $resource_id ) || ! is_array( $resource_settings ) ) { unset( $settings['resources'][ $resource_id ] ); continue; } $mode = isset( $resource_settings['mode'] ) ? (string) $resource_settings['mode'] : 'inherit'; if ( ! in_array( $mode, array( 'inherit', 'custom', 'disabled' ), true ) ) { $mode = 'inherit'; } $settings['resources'][ $resource_id ] = array( 'mode' => $mode, 'weekdays' => wpbc_working_time__normalize_weekday_intervals( isset( $resource_settings['weekdays'] ) ? $resource_settings['weekdays'] : array() ), ); } return $settings; } /** * Normalize weekly intervals. * * @param mixed $weekdays Weekday intervals. * * @return array */ function wpbc_working_time__normalize_weekday_intervals( $weekdays ) { $normalized = array(); for ( $day = 0; $day <= 6; $day++ ) { $normalized[ $day ] = array(); if ( empty( $weekdays[ $day ] ) || ! is_array( $weekdays[ $day ] ) ) { continue; } foreach ( $weekdays[ $day ] as $interval ) { if ( ! is_array( $interval ) ) { continue; } $start_second = isset( $interval['start_second'] ) ? absint( $interval['start_second'] ) : 0; $end_second = isset( $interval['end_second'] ) ? absint( $interval['end_second'] ) : 0; $start_second = max( 0, min( DAY_IN_SECONDS, $start_second ) ); $end_second = max( 0, min( DAY_IN_SECONDS, $end_second ) ); if ( $start_second < $end_second ) { $normalized[ $day ][] = array( 'start_second' => $start_second, 'end_second' => $end_second, ); } } usort( $normalized[ $day ], function ( $a, $b ) { return $a['start_second'] - $b['start_second']; } ); } return $normalized; } /** * Get stored Working Time settings. * * @return array */ function wpbc_working_time__get_settings() { $settings = get_bk_option( 'booking_working_time_rules', array() ); return wpbc_working_time__normalize_settings( maybe_unserialize( $settings ) ); } /** * Save Working Time settings. * * @param array $settings Settings. * * @return void */ function wpbc_working_time__update_settings( $settings ) { $settings = wpbc_working_time__normalize_settings( $settings ); update_bk_option( 'booking_working_time_rules', $settings ); update_bk_option( 'booking_working_time_enabled', $settings['enabled'] ); } /** * Add default Working Time options on activation/update. * * @return void */ function wpbc_activation__working_time() { $settings = wpbc_working_time__get_default_settings(); add_bk_option( 'booking_working_time_enabled', 'Off' ); add_bk_option( 'booking_working_time_rules', $settings ); } add_bk_action( 'wpbc_free_version_activation', 'wpbc_activation__working_time' ); add_bk_action( 'wpbc_other_versions_activation', 'wpbc_activation__working_time' ); /** * Keep Working Time options present after plugin updates for existing installs. * * @return void */ function wpbc_working_time__maybe_install_options() { if ( ! is_admin() ) { return; } if ( ( false === get_bk_option( 'booking_working_time_enabled', false ) ) || ( false === get_bk_option( 'booking_working_time_rules', false ) ) ) { wpbc_activation__working_time(); } } add_action( 'admin_init', 'wpbc_working_time__maybe_install_options' ); /** * Remove Working Time options when Booking Calendar data is deleted on deactivation. * * @return void */ function wpbc_deactivation__working_time() { delete_bk_option( 'booking_working_time_enabled' ); delete_bk_option( 'booking_working_time_rules' ); } add_bk_action( 'wpbc_free_version_deactivation', 'wpbc_deactivation__working_time' ); add_bk_action( 'wpbc_other_versions_deactivation', 'wpbc_deactivation__working_time' ); /** * Convert time string into seconds. * * @param string $time_value Time in H:i format. * * @return int */ function wpbc_working_time__time_to_seconds( $time_value ) { $time_value = (string) $time_value; if ( ! preg_match( '/^([01]?\d|2[0-4]):([0-5]\d)$/', $time_value, $matches ) ) { return 0; } $hours = min( 24, absint( $matches[1] ) ); $mins = ( 24 === $hours ) ? 0 : absint( $matches[2] ); return min( DAY_IN_SECONDS, ( $hours * HOUR_IN_SECONDS ) + ( $mins * MINUTE_IN_SECONDS ) ); } /** * Convert seconds into H:i time. * * @param int $seconds Seconds. * * @return string */ function wpbc_working_time__seconds_to_time( $seconds ) { $seconds = max( 0, min( DAY_IN_SECONDS, absint( $seconds ) ) ); $hours = (int) floor( $seconds / HOUR_IN_SECONDS ); $mins = (int) floor( ( $seconds % HOUR_IN_SECONDS ) / MINUTE_IN_SECONDS ); return sprintf( '%02d:%02d', $hours, $mins ); } /** * Get effective Working Time rule for a resource. * * @param int $resource_id Resource ID. * * @return array|false */ function wpbc_working_time__get_effective_rule( $resource_id ) { $settings = wpbc_working_time__get_settings(); $resource_id = absint( $resource_id ); if ( 'On' !== $settings['enabled'] ) { return false; } if ( ! empty( $settings['resources'][ $resource_id ] ) ) { $resource_settings = $settings['resources'][ $resource_id ]; if ( 'disabled' === $resource_settings['mode'] ) { return false; } if ( 'custom' === $resource_settings['mode'] ) { return array( 'source' => 'resource', 'weekdays' => $resource_settings['weekdays'], ); } } return array( 'source' => 'default', 'weekdays' => $settings['default']['weekdays'], ); } /** * Get working intervals for date/resource. * * @param int $resource_id Resource ID. * @param string $sql_date SQL date. * * @return array */ function wpbc_working_time__get_working_intervals_for_date( $resource_id, $sql_date ) { $rule = wpbc_working_time__get_effective_rule( $resource_id ); if ( false === $rule || empty( $sql_date ) ) { return array(); } $weekday = (int) gmdate( 'w', strtotime( $sql_date . ' 00:00:00' ) ); return isset( $rule['weekdays'][ $weekday ] ) ? $rule['weekdays'][ $weekday ] : array(); } /** * Get outside-working-time intervals for date/resource. * * @param int $resource_id Resource ID. * @param string $sql_date SQL date. * * @return array */ function wpbc_working_time__get_non_working_intervals_for_date( $resource_id, $sql_date ) { $working_intervals = wpbc_working_time__get_working_intervals_for_date( $resource_id, $sql_date ); if ( false === wpbc_working_time__get_effective_rule( $resource_id ) ) { return array(); } if ( empty( $working_intervals ) ) { return array( array( 'date' => $sql_date, 'resource_id' => absint( $resource_id ), 'start_second' => 0, 'end_second' => DAY_IN_SECONDS, 'source_type' => 'working_time', 'readable_time' => __( 'Full day', 'booking' ), ), ); } $busy = array(); $cursor = 0; foreach ( $working_intervals as $interval ) { $start_second = absint( $interval['start_second'] ); $end_second = absint( $interval['end_second'] ); if ( $cursor < $start_second ) { $busy[] = array( 'date' => $sql_date, 'resource_id' => absint( $resource_id ), 'start_second' => $cursor, 'end_second' => $start_second, 'source_type' => 'working_time', 'readable_time' => wpbc_transform_timerange__seconds_arr__in__formated_hours( array( $cursor, $start_second ) ), ); } $cursor = max( $cursor, $end_second ); } if ( $cursor < DAY_IN_SECONDS ) { $busy[] = array( 'date' => $sql_date, 'resource_id' => absint( $resource_id ), 'start_second' => $cursor, 'end_second' => DAY_IN_SECONDS, 'source_type' => 'working_time', 'readable_time' => wpbc_transform_timerange__seconds_arr__in__formated_hours( array( $cursor, DAY_IN_SECONDS ) ), ); } return $busy; }