'default', 'calendar' => 'gregorian', 'time_format' => '24', 'use_site_tz' => 1, 'custom_timezone' => 'UTC', 'time_color' => '#2ECC71', 'date_color' => '#E74C3C', 'clickable_clock' => 1, ]; } /** * Retrieve a single option (with defaults). * * @param string $key Option key. * @return mixed */ function atlc_get_option( $key ) { $all = wp_parse_args( get_option( ATLC_OPTION_NAME, [] ), atlc_default_options() ); return $all[ $key ]; } /** * Return the site’s timezone (IANA or UTC±offset). * * @return string */ function atlc_get_site_timezone() { $tz_string = get_option( 'timezone_string' ); if ( $tz_string ) { return $tz_string; } $offset = get_option( 'gmt_offset' ); if ( ! $offset ) { return 'UTC'; } $hours = floor( $offset ); $minutes = abs( ( $offset - $hours ) * 60 ); return sprintf( 'UTC%+03d:%02d', $hours, $minutes ); } /* -------------------------------------------------------------------------- */ /* Internationalisation */ /* -------------------------------------------------------------------------- */ /** * Scan /languages for available locales. * * @return array code => label */ function atlc_available_languages() { static $cache = null; if ( null !== $cache ) { return $cache; } $cache = [ 'default' => __( 'Default (Dashboard)', 'admin-toolbar-live-clock' ) ]; foreach ( glob( plugin_dir_path( __FILE__ ) . 'languages/' . ATLC_DOMAIN . '-*.mo' ) as $file ) { $code = str_replace( [ ATLC_DOMAIN . '-', '.mo' ], '', basename( $file ) ); $label = ''; if ( function_exists( 'locale_get_display_language' ) ) { $label = locale_get_display_language( $code, $code ); } // Fallback for locales where PHP returns an empty label. if ( ! $label ) { $map = [ 'hi_IN' => 'हिन्दी', 'th_TH' => 'ไทย', ]; $label = $map[ $code ] ?? $code; } // Capitalise only Latin labels. if ( preg_match( '/^[a-z]/i', $label ) ) { $label = ucwords( $label ); } $cache[ $code ] = sprintf( '%s (%s)', $label, $code ); } $cache['en_US'] = $cache['en_US'] ?? 'English (en_US)'; return $cache; } /* Force chosen locale for this text-domain */ add_filter( 'plugin_locale', static function ( $locale, $domain ) { if ( ATLC_DOMAIN !== $domain ) { return $locale; } $sel = atlc_get_option( 'language' ); return ( $sel && 'default' !== $sel ) ? $sel : $locale; }, 10, 2 ); /* Load .mo file after plugins_loaded */ add_action( 'plugins_loaded', static function () { $sel = atlc_get_option( 'language' ); if ( $sel && 'default' !== $sel ) { unload_textdomain( ATLC_DOMAIN ); if ( 'en_US' === $sel ) { load_textdomain( ATLC_DOMAIN, false ); return; } $mofiles = [ plugin_dir_path( __FILE__ ) . 'languages/' . ATLC_DOMAIN . "-$sel.mo", WP_LANG_DIR . '/plugins/' . ATLC_DOMAIN . "-$sel.mo", ]; foreach ( $mofiles as $mofile ) { if ( is_readable( $mofile ) && load_textdomain( ATLC_DOMAIN, $mofile ) ) { return; } } load_textdomain( ATLC_DOMAIN, false ); } }, 0 ); /* -------------------------------------------------------------------------- */ /* Sanitisation */ /* -------------------------------------------------------------------------- */ /** * Validate & sanitise settings. * * @param array $raw Raw options. * @return array */ function atlc_sanitize_options( $raw ) { $clean = atlc_default_options(); $raw = (array) $raw; $langs = array_keys( atlc_available_languages() ); $calendars = [ 'gregorian', 'persian', 'islamic', 'hebrew', 'buddhist', 'japanese' ]; if ( isset( $raw['language'] ) && in_array( $raw['language'], $langs, true ) ) { $clean['language'] = $raw['language']; } if ( isset( $raw['calendar'] ) && in_array( $raw['calendar'], $calendars, true ) ) { $clean['calendar'] = $raw['calendar']; } $clean['time_format'] = ( isset( $raw['time_format'] ) && '12' === $raw['time_format'] ) ? '12' : '24'; $clean['use_site_tz'] = empty( $raw['use_site_tz'] ) ? 0 : 1; $clean['clickable_clock'] = empty( $raw['clickable_clock'] ) ? 0 : 1; if ( isset( $raw['custom_timezone'] ) && in_array( $raw['custom_timezone'], timezone_identifiers_list(), true ) ) { $clean['custom_timezone'] = $raw['custom_timezone']; } foreach ( [ 'time_color', 'date_color' ] as $c ) { if ( $hex = sanitize_hex_color( $raw[ $c ] ?? '' ) ) { $clean[ $c ] = strtoupper( $hex ); } } return $clean; } /* -------------------------------------------------------------------------- */ /* Settings page */ /* -------------------------------------------------------------------------- */ add_action( 'admin_menu', static function () { add_options_page( __( 'Admin Toolbar Live Clock', 'admin-toolbar-live-clock' ), __( 'Toolbar Clock', 'admin-toolbar-live-clock' ), 'manage_options', ATLC_MENU_SLUG, 'atlc_render_settings_page' ); } ); add_action( 'admin_init', static function () { register_setting( ATLC_OPTION_GROUP, ATLC_OPTION_NAME, 'atlc_sanitize_options' ); add_settings_section( 'atlc_main', '', '__return_false', ATLC_MENU_SLUG ); $fields = [ 'language' => __( 'Plugin language', 'admin-toolbar-live-clock' ), 'calendar' => __( 'Calendar system', 'admin-toolbar-live-clock' ), 'time_format' => __( 'Clock format', 'admin-toolbar-live-clock' ), 'use_site_tz' => __( 'Use site timezone', 'admin-toolbar-live-clock' ), 'custom_timezone' => __( 'Custom timezone', 'admin-toolbar-live-clock' ), 'time_color' => __( 'Clock colour', 'admin-toolbar-live-clock' ), 'date_color' => __( 'Date colour', 'admin-toolbar-live-clock' ), 'clickable_clock' => __( 'Make clock clickable', 'admin-toolbar-live-clock' ), ]; foreach ( $fields as $id => $label ) { add_settings_field( $id, $label, "atlc_field_{$id}", ATLC_MENU_SLUG, 'atlc_main' ); } } ); /* ---------- field callbacks ----------- */ function atlc_field_language() { $val = atlc_get_option( 'language' ); ?> __( 'Gregorian', 'admin-toolbar-live-clock' ), 'persian' => __( 'Jalali (Persian)', 'admin-toolbar-live-clock' ), 'islamic' => __( 'Hijri (Islamic)', 'admin-toolbar-live-clock' ), 'hebrew' => __( 'Hebrew', 'admin-toolbar-live-clock' ), 'buddhist' => __( 'Buddhist (Thai)', 'admin-toolbar-live-clock' ), 'japanese' => __( 'Japanese', 'admin-toolbar-live-clock' ), ]; ?> __( '24-hour', 'admin-toolbar-live-clock' ), '12' => __( '12-hour AM/PM', 'admin-toolbar-live-clock' ), ]; ?> /> /> ', esc_attr( ATLC_OPTION_NAME ), esc_attr( $key ), esc_attr( atlc_get_option( $key ) ) ); } function atlc_field_time_color() { atlc_color_picker_input( 'time_color' ); } function atlc_field_date_color() { atlc_color_picker_input( 'date_color' ); } /** * Render settings page. */ function atlc_render_settings_page() { ?>

© Amin Raoufi ·

atlc_get_option( 'time_format' ), 'calendar' => atlc_get_option( 'calendar' ), 'time_color' => atlc_get_option( 'time_color' ), 'date_color' => atlc_get_option( 'date_color' ), 'timezone' => atlc_get_site_timezone(), ] ); } ); /* -------------------------------------------------------------------------- */ /* Toolbar node */ /* -------------------------------------------------------------------------- */ /** * Format date/time for different calendars. * * @param DateTime $dt DateTime object. * @param string $cal Calendar key. * @param string $pattern Time format (e.g. H:i:s A). * @return string */ function atlc_format_datetime( DateTime $dt, $cal, $pattern ) { if ( 'gregorian' === $cal ) { return $dt->format( $pattern . ' Y-m-d' ); } if ( class_exists( 'IntlDateFormatter' ) ) { $map = [ 'persian' => 'fa_IR@calendar=persian', 'islamic' => 'ar_SA@calendar=islamic', 'hebrew' => 'he_IL@calendar=hebrew', 'buddhist' => 'th_TH@calendar=buddhist', 'japanese' => 'ja_JP@calendar=japanese', ]; $locale = $map[ $cal ] ?? get_locale(); $fmt = new IntlDateFormatter( $locale, IntlDateFormatter::NONE, IntlDateFormatter::NONE, $dt->getTimezone()->getName(), IntlDateFormatter::TRADITIONAL, $pattern . ' yyyy-MM-dd' ); return $fmt->format( $dt ); } return $dt->format( $pattern . ' Y-m-d' ); } add_action( 'admin_bar_menu', static function ( WP_Admin_Bar $bar ) { if ( ! current_user_can( 'manage_options' ) ) { return; } $tz = atlc_get_option( 'use_site_tz' ) ? atlc_get_site_timezone() : atlc_get_option( 'custom_timezone' ); $pattern = ( '12' === atlc_get_option( 'time_format' ) ) ? 'h:i:s A' : 'H:i:s'; $now = new DateTime( 'now', new DateTimeZone( $tz ) ); $label = atlc_format_datetime( $now, atlc_get_option( 'calendar' ), $pattern ); $clock_html = esc_html( $label ); if ( atlc_get_option( 'clickable_clock' ) ) { $clock_html = sprintf( '%s', esc_url( admin_url( 'options-general.php?page=' . ATLC_MENU_SLUG ) ), $clock_html ); } else { $clock_html = sprintf( '%s', $clock_html ); } $bar->add_node( [ 'id' => 'atlc-node', 'parent' => 'top-secondary', 'title' => $clock_html, ] ); }, 999 ); /* -------------------------------------------------------------------------- */ /* Force English when user selects “en_US” */ /* -------------------------------------------------------------------------- */ add_filter( 'gettext', static function ( $translated, $text, $domain ) { if ( ATLC_DOMAIN === $domain && 'en_US' === atlc_get_option( 'language' ) ) { return $text; } return $translated; }, 10, 3 ); /* -------------------------------------------------------------------------- */ /* Add “Settings” link in plugin list */ /* -------------------------------------------------------------------------- */ add_filter( 'plugin_action_links_' . plugin_basename(__FILE__), static function ( $links ) { if ( current_user_can( 'manage_options' ) ) { $settings_link = sprintf( '%s', esc_url( admin_url( 'options-general.php?page=' . ATLC_MENU_SLUG ) ), esc_html__( 'Settings', 'admin-toolbar-live-clock' ) ); array_unshift( $links, $settings_link ); } return $links; } );