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(); ?>
diagnostics_table( $diagnostics ); ?>
$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' ),
);
?>
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',
)
);
?>
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( '', esc_attr( $notice['type'] ), esc_html( $notice['message'] ) );
}
}
private function current_url() {
return StandaloneLocale::request_path();
}
}