1, 'position' => 'right', 'phone' => '', 'viber' => '', 'telegram' => '', 'whatsapp' => '', 'whatsapp_message' => '', 'open_new_tab' => 1, 'pulse' => 1, 'button_size' => 56, 'show_labels' => 0, 'devices' => 'all', 'schedule_enabled' => 0, 'schedule_start' => '09:00', 'schedule_end' => '18:00', 'schedule_days' => array( '1','2','3','4','5' ), 'visibility_mode' => 'everywhere', 'page_ids' => '', ); } public function get_options() { return wp_parse_args( get_option( self::OPTION_KEY, array() ), $this->defaults() ); } public function add_admin_menu() { add_options_page( __( 'AGAPOVDEV Smart Contact Buttons', 'agapovdev-floating-contact-buttons' ), __( 'AGAPOVDEV Contact', 'agapovdev-floating-contact-buttons' ), 'manage_options', 'agapovdev-floating-contact-buttons', array( $this, 'settings_page' ) ); } public function register_settings() { register_setting( 'agapovdev_fcb_group', self::OPTION_KEY, array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_options' ), 'default' => $this->defaults() ) ); } private function sanitize_time( $value, $fallback ) { $value = sanitize_text_field( (string) $value ); return preg_match( '/^(?:[01]\d|2[0-3]):[0-5]\d$/', $value ) ? $value : $fallback; } public function sanitize_options( $input ) { $input = is_array( $input ) ? $input : array(); $out = $this->defaults(); $out['enabled'] = empty( $input['enabled'] ) ? 0 : 1; $out['position'] = ( isset( $input['position'] ) && 'left' === $input['position'] ) ? 'left' : 'right'; foreach ( array( 'phone','viber','telegram','whatsapp' ) as $key ) { $out[ $key ] = isset( $input[ $key ] ) ? sanitize_text_field( $input[ $key ] ) : ''; } $out['whatsapp_message'] = isset( $input['whatsapp_message'] ) ? sanitize_textarea_field( $input['whatsapp_message'] ) : ''; $out['open_new_tab'] = empty( $input['open_new_tab'] ) ? 0 : 1; $out['pulse'] = empty( $input['pulse'] ) ? 0 : 1; $out['show_labels'] = empty( $input['show_labels'] ) ? 0 : 1; $out['button_size'] = isset( $input['button_size'] ) ? min( 84, max( 40, absint( $input['button_size'] ) ) ) : 56; $out['devices'] = isset( $input['devices'] ) && in_array( $input['devices'], array( 'all','desktop','mobile' ), true ) ? $input['devices'] : 'all'; $out['schedule_enabled'] = empty( $input['schedule_enabled'] ) ? 0 : 1; $out['schedule_start'] = $this->sanitize_time( isset( $input['schedule_start'] ) ? $input['schedule_start'] : '', '09:00' ); $out['schedule_end'] = $this->sanitize_time( isset( $input['schedule_end'] ) ? $input['schedule_end'] : '', '18:00' ); $days = isset( $input['schedule_days'] ) && is_array( $input['schedule_days'] ) ? array_map( 'absint', $input['schedule_days'] ) : array(); $out['schedule_days'] = array_map( 'strval', array_values( array_intersect( array(1,2,3,4,5,6,7), $days ) ) ); $out['visibility_mode'] = isset( $input['visibility_mode'] ) && in_array( $input['visibility_mode'], array( 'everywhere','include','exclude' ), true ) ? $input['visibility_mode'] : 'everywhere'; $ids = isset( $input['page_ids'] ) ? preg_split( '/[\s,]+/', sanitize_text_field( $input['page_ids'] ) ) : array(); $ids = array_filter( array_map( 'absint', $ids ) ); $out['page_ids'] = implode( ',', array_unique( $ids ) ); return $out; } public function settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $o = $this->get_options(); $days = array( '1'=>'Mon','2'=>'Tue','3'=>'Wed','4'=>'Thu','5'=>'Fri','6'=>'Sat','7'=>'Sun' ); ?>

format( 'N' ), (array) $o['schedule_days'], true ) ) { return false; } $current = $now->format( 'H:i' ); $start = $o['schedule_start']; $end = $o['schedule_end']; $inside = ( $start <= $end ) ? ( $current >= $start && $current <= $end ) : ( $current >= $start || $current <= $end ); if ( ! $inside ) { return false; } } return true; } public function enqueue_assets() { $o = $this->get_options(); if ( ! $this->should_render( $o ) ) { return; } wp_enqueue_style( 'agapovdev-fcb', plugin_dir_url( __FILE__ ) . 'assets/fcb.css', array(), self::VERSION ); wp_enqueue_script( 'agapovdev-fcb', plugin_dir_url( __FILE__ ) . 'assets/fcb.js', array(), self::VERSION, true ); wp_add_inline_style( 'agapovdev-fcb', ':root{--agfcb-size:' . absint( $o['button_size'] ) . 'px;}' ); } private function normalize_phone( $value ) { return preg_replace( '/[^0-9+]/', '', (string) $value ); } private function digits_only( $value ) { return preg_replace( '/\D+/', '', (string) $value ); } private function telegram_url( $value ) { $value = trim( (string) $value ); if ( '' === $value ) { return ''; } if ( preg_match( '#^https://(?:t\.me|telegram\.me)/#i', $value ) ) { return esc_url_raw( $value ); } $username = preg_replace( '/[^A-Za-z0-9_]/', '', ltrim( $value, '@' ) ); return $username ? 'https://t.me/' . $username : ''; } private function icon_svg( $type ) { $icons = array( 'phone'=>'', 'viber'=>'', 'telegram'=>'', 'whatsapp'=>'', 'main'=>'', ); return isset( $icons[ $type ] ) ? $icons[ $type ] : ''; } private function escape_contact_url( $url ) { return esc_url( $url, array( 'http','https','tel','viber' ) ); } public function render_widget() { $o = $this->get_options(); if ( ! $this->should_render( $o ) ) { return; } $items = array(); $phone = $this->normalize_phone( $o['phone'] ); if ( $phone && preg_match( '/\d/', $phone ) ) { $items[] = array( 'type'=>'phone','label'=>__( 'Phone', 'agapovdev-floating-contact-buttons' ),'url'=>'tel:' . $phone ); } $viber = $this->normalize_phone( $o['viber'] ); if ( $viber && preg_match( '/\d/', $viber ) ) { $items[] = array( 'type'=>'viber','label'=>__( 'Viber', 'agapovdev-floating-contact-buttons' ),'url'=>'viber://chat?number=' . rawurlencode( $viber ) ); } $telegram = $this->telegram_url( $o['telegram'] ); if ( $telegram ) { $items[] = array( 'type'=>'telegram','label'=>__( 'Telegram', 'agapovdev-floating-contact-buttons' ),'url'=>$telegram ); } $whatsapp = $this->digits_only( $o['whatsapp'] ); if ( $whatsapp ) { $url = 'https://wa.me/' . $whatsapp; if ( $o['whatsapp_message'] ) { $url .= '?text=' . rawurlencode( $o['whatsapp_message'] ); } $items[] = array( 'type'=>'whatsapp','label'=>__( 'WhatsApp', 'agapovdev-floating-contact-buttons' ),'url'=>$url ); } if ( empty( $items ) ) { return; } $classes = 'agfcb agfcb--' . $o['position'] . ' agfcb--device-' . $o['devices']; if ( $o['show_labels'] ) { $classes .= ' agfcb--labels'; } ?>