manager = $manager; $this->catalog = $catalog; $this->variables = $variables; } public function register() { add_action( 'admin_menu', array( $this, 'menu' ), 20 ); add_action( 'admin_post_glovario_save_locale_settings', array( $this, 'save' ) ); add_action( 'wp_ajax_glovario_dismiss_openlitespeed_notice', array( $this, 'dismiss_openlitespeed_notice' ) ); add_action( 'glovario_admin_after_variable_form', array( $this, 'preview_panel' ), 5 ); add_action( 'admin_bar_menu', array( $this, 'toolbar' ), 90 ); add_filter( 'glovario_admin_settings', array( $this, 'picker_settings' ) ); add_action( 'glovario_admin_before_variable_list', array( $this, 'two_language_warning' ) ); } /** * When a multilingual plugin is active, state plainly that values exist for * two languages only and which languages of that plugin show default values. */ /** * Whether LiteSpeed Cache reports an OpenLiteSpeed server, which reads * .htaccess changes (such as its cookie vary rule) only after a restart. */ public static function on_openlitespeed() { return defined( 'LITESPEED_SERVER_TYPE' ) && 'LITESPEED_SERVER_OLS' === LITESPEED_SERVER_TYPE; } /** * Whether the current user should see the OpenLiteSpeed restart notice: * until they dismiss it, and again once the cache rule changes (the * server then needs another restart). PHP cannot tell whether it restarted. */ private function show_openlitespeed_notice() { if ( ! self::on_openlitespeed() ) { return false; } $dismissed = get_user_option( self::OPENLITESPEED_DISMISSED ); return false === $dismissed || (string) get_option( PageCacheCompatibility::LITESPEED_CHANGED, '' ) !== $dismissed; } public function dismiss_openlitespeed_notice() { check_ajax_referer( 'glovario_dismiss_openlitespeed_notice' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( null, 403 ); } update_user_option( get_current_user_id(), self::OPENLITESPEED_DISMISSED, (string) get_option( PageCacheCompatibility::LITESPEED_CHANGED, '' ) ); wp_send_json_success(); } public function two_language_warning() { /** * Filters whether the two-language notice is shown when a multilingual plugin is active. * * @param bool $show Whether to show the notice. */ if ( ! $this->manager->has_multilingual_integration() || ! apply_filters( 'glovario_show_language_limit_notice', true ) ) { return; } $settings = $this->manager->settings(); $providers = $this->manager->detected_providers(); $plugin = $providers ? $providers[0]['label'] : $this->manager->integration()['label']; $unconfigured = $this->manager->unconfigured_provider_locales(); if ( ! $unconfigured ) { // The plugin's languages are exactly the two Glovario handles: nothing to warn about. return; } if ( '' === $settings['second_locale'] && 1 === count( $unconfigured ) ) { // Two languages in total: Free supports them; only the second one is not chosen yet. ?>

catalog->options(); } elseif ( 'glovario' === $page && in_array( $action, array( 'edit', 'add' ), true ) ) { // The preview and rule pickers offer the site's languages: the cached list is enough. $cached = get_site_transient( 'available_translations' ); $settings['locales'] = $this->catalog->options( is_array( $cached ) ? $cached : array() ); } else { return $settings; } $settings['localePicker'] = array( 'recommended' => __( 'Relevant to this site', 'glovario' ), 'all' => __( 'All WordPress locales', 'glovario' ), 'noResults' => __( 'No matching locales.', 'glovario' ), 'remove' => __( 'Remove', 'glovario' ), 'required' => __( 'Select at least one locale.', 'glovario' ), 'custom' => __( 'Use custom locale code', 'glovario' ), 'customLabel' => __( 'Custom locale', 'glovario' ), 'customWarning' => __( 'Custom locales only match when WordPress or a multilingual integration returns the exact same code.', 'glovario' ), /* translators: %d: maximum number of selectable locales. */ 'maximum' => __( 'You can select up to %d locales.', 'glovario' ), ); return $settings; } public function menu() { $this->hook = add_submenu_page( 'glovario', __( 'Locale Settings', 'glovario' ), __( 'Locale Settings', 'glovario' ), 'manage_options', 'glovario-locale-settings', array( $this, 'page' ) ); } public function page() { $this->guard(); $settings = $this->manager->settings(); $status = $this->manager->status(); $integration = $status['integration']; $missing = $this->manager->missing_wordpress_language_packs(); $diagnostics = $this->manager->diagnostics(); $providers = $diagnostics['providers']; $provider_labels = wp_list_pluck( $providers, 'label' ); ?>

notice(); ?>


1 ) : ?>

show_openlitespeed_notice() ) : ?>

manager->is_supported_locale( $integration['locale'] ) ) : ?>

two_language_warning(); ?>
'glovario-default-locale', 'name' => 'default_locale', 'label' => __( 'Default language', 'glovario' ), 'selected' => array( $settings['default_locale'] ), 'required' => true, 'description' => __( 'The language of your variable values as you enter them.', 'glovario' ), ) ); LocalePicker::render( array( 'id' => 'glovario-second-locale', 'name' => 'second_locale', 'label' => __( 'Second language (optional)', 'glovario' ), 'selected' => '' === $settings['second_locale'] ? array() : array( $settings['second_locale'] ), 'description' => __( 'Variables can have a different value in this language. Used by language-specific values, previews, and, in Standalone mode, the public language switcher.', 'glovario' ), ) ); } ?>

diagnostics_table( $diagnostics ); ?>

[glvr_locale_switcher]

$diagnostics['mode'], __( 'Detected providers', 'glovario' ) => $providers ? implode( '; ', $providers ) : __( 'None', 'glovario' ), __( 'Selected provider', 'glovario' ) => $diagnostics['integration']['label'], __( 'Provider-reported locale', 'glovario' ) => $diagnostics['provider_raw_locale'] ? $diagnostics['provider_raw_locale'] : __( 'Not available', 'glovario' ), /* translators: Glovario is the product name; do not translate it. */ __( 'Resolved Glovario locale', 'glovario' ) => $diagnostics['resolved_locale'], __( 'WordPress request locale', 'glovario' ) => $diagnostics['wordpress_locale'], __( 'WordPress site locale', 'glovario' ) => $diagnostics['site_locale'], __( 'Configured languages', 'glovario' ) => implode( ', ', $diagnostics['configured_locales'] ), /* translators: Glovario is the product name; do not translate it. */ __( 'Default Glovario locale', 'glovario' ) => $diagnostics['default_locale'], __( 'Provider destination languages', 'glovario' ) => $destinations ? implode( ', ', $destinations ) : __( 'Not reported', 'glovario' ), __( 'Missing WordPress language packs', 'glovario' ) => $diagnostics['missing_packs'] ? implode( ', ', $diagnostics['missing_packs'] ) : __( 'None', 'glovario' ), ); ?>

$value ) : ?>
guard(); check_admin_referer( 'glovario_save_locale_settings' ); $mode = isset( $_POST['locale_mode'] ) ? sanitize_key( wp_unslash( $_POST['locale_mode'] ) ) : ''; $global_switcher = ! empty( $_POST['global_switcher'] ); /** * Short-circuits saving the language fields. * Nonce and capability are verified before this filter runs. * * @param array|\WP_Error|null $result Null to save the default and the second language. * @param string $mode Resolution mode. * @param bool $global_switcher Whether the site-wide switcher is enabled. */ $result = apply_filters( 'glovario_pre_save_locale_settings', null, $mode, $global_switcher ); if ( null === $result ) { $default = isset( $_POST['default_locale'] ) ? sanitize_locale_name( wp_unslash( $_POST['default_locale'] ) ) : ''; $second = isset( $_POST['second_locale'] ) ? sanitize_locale_name( wp_unslash( $_POST['second_locale'] ) ) : ''; $result = $this->manager->save_settings( $mode, $default, $second, array( 'global_switcher' => $global_switcher ) ); } if ( is_wp_error( $result ) ) { $this->redirect( $result->get_error_message(), 'error' ); } $this->redirect( __( 'Locale settings saved.', 'glovario' ) ); } public function preview_panel( $variable ) { if ( empty( $variable['id'] ) ) { return; } $selected = $this->manager->preview_request_locale(); if ( ! $selected ) { $selected = $this->manager->status()['locale']; } $value = glovario_get_rendered_value( $variable['variable_key'], array( 'locale' => $selected, 'source' => 'admin_locale_preview', ) ); ?>

'glovario-variable-preview-locale', 'name' => LocaleManager::PREVIEW_QUERY, 'label' => __( 'Preview this variable as', 'glovario' ), 'selected' => array( $selected ), 'required' => true, 'description' => __( 'Previewing does not change the public site or save a visitor language.', 'glovario' ), ) ); ?>
manager->preview_request_locale(); $active = $active ? $active : $this->manager->status()['locale']; $admin_bar->add_node( array( 'id' => 'glovario-locale-preview', /* translators: %s: locale code currently used for Site Variable previewing. Glovario is the product name; do not translate it. */ 'title' => esc_html( sprintf( __( 'Glovario locale: %s', 'glovario' ), $active ) ), 'href' => admin_url( 'admin.php?page=glovario-locale-settings' ), ) ); $current = $this->current_url(); foreach ( $this->manager->preview_locales() as $locale ) { $url = add_query_arg( array( LocaleManager::PREVIEW_QUERY => $locale, '_glovario_locale_nonce' => wp_create_nonce( 'glovario_preview_locale' ), ), $current ); $admin_bar->add_node( array( 'parent' => 'glovario-locale-preview', 'id' => 'glovario-locale-preview-' . sanitize_html_class( $locale ), 'title' => esc_html( $locale ), 'href' => $url, ) ); } if ( $this->manager->preview_request_locale() ) { $admin_bar->add_node( array( 'parent' => 'glovario-locale-preview', 'id' => 'glovario-locale-preview-clear', 'title' => esc_html__( 'Clear locale preview', 'glovario' ), 'href' => remove_query_arg( array( LocaleManager::PREVIEW_QUERY, '_glovario_locale_nonce' ), $current ), ) ); } } private function guard() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to use this feature.', 'glovario' ), 403 ); } } private function redirect( $message, $type = 'success' ) { set_transient( 'glovario_locale_notice_' . get_current_user_id(), array( 'message' => $message, 'type' => $type, ), 60 ); wp_safe_redirect( admin_url( 'admin.php?page=glovario-locale-settings' ) ); exit; } private function notice() { $key = 'glovario_locale_notice_' . get_current_user_id(); $notice = get_transient( $key ); if ( $notice ) { delete_transient( $key ); printf( '

%2$s

', esc_attr( $notice['type'] ), esc_html( $notice['message'] ) ); } } private function current_url() { return StandaloneLocale::request_path(); } }