first commit
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\LanguageSwitcher\AjaxNavigation;
|
||||
|
||||
class Hooks implements \IWPML_Frontend_Action, \IWPML_DIC_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_enqueue_scripts', [ $this, 'enqueueScripts' ] );
|
||||
}
|
||||
|
||||
public function enqueueScripts() {
|
||||
if ( $this->isEnabled() ) {
|
||||
wp_enqueue_script(
|
||||
'wpml-ajax-navigation',
|
||||
ICL_PLUGIN_URL . '/dist/js/ajaxNavigation/app.js',
|
||||
[],
|
||||
ICL_SITEPRESS_VERSION
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function isEnabled() {
|
||||
/**
|
||||
* This filter allows to enable/disable the feature to automatically
|
||||
* refresh the language switchers on AJAX navigation.
|
||||
*
|
||||
* @since 4.4.0
|
||||
*
|
||||
* @param bool false (default) Is the feature enabled.
|
||||
*/
|
||||
return apply_filters( 'wpml_ls_enable_ajax_navigation', false );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
class WPML_Get_LS_Languages_Status {
|
||||
private static $the_instance;
|
||||
|
||||
private $in_get_ls_languages = false;
|
||||
|
||||
public function is_getting_ls_languages() {
|
||||
return $this->in_get_ls_languages;
|
||||
}
|
||||
|
||||
public function start() {
|
||||
$this->in_get_ls_languages = true;
|
||||
}
|
||||
|
||||
public function end() {
|
||||
$this->in_get_ls_languages = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_Get_LS_Languages_Status
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$the_instance ) {
|
||||
self::$the_instance = new WPML_Get_LS_Languages_Status();
|
||||
}
|
||||
return self::$the_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_Get_LS_Languages_Status $instance
|
||||
*/
|
||||
public static function set_instance( $instance ) {
|
||||
self::$the_instance = $instance;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_Language_Switcher
|
||||
*
|
||||
* Main class
|
||||
*/
|
||||
class WPML_Language_Switcher extends WPML_SP_User {
|
||||
|
||||
/* @var array $dependencies */
|
||||
private $dependencies;
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_LS_Dependencies_Factory $dependencies
|
||||
*/
|
||||
public function __construct( SitePress $sitepress, WPML_LS_Dependencies_Factory $dependencies = null ) {
|
||||
parent::__construct( $sitepress );
|
||||
$this->dependencies = $dependencies ? $dependencies : new WPML_LS_Dependencies_Factory( $sitepress, self::parameters() );
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
if ( $this->sitepress->get_setting( 'setup_complete' ) ) {
|
||||
add_action( 'widgets_init', array( 'WPML_LS_Widget', 'register' ), 20 );
|
||||
}
|
||||
|
||||
$this->dependencies->templates()->init_hooks();
|
||||
$this->dependencies->settings()->init_hooks();
|
||||
$this->dependencies->render()->init_hooks();
|
||||
$this->dependencies->shortcodes()->init_hooks();
|
||||
$this->dependencies->actions()->init_hooks();
|
||||
$this->dependencies->inline_styles()->init_hooks();
|
||||
|
||||
if ( is_admin() ) {
|
||||
if ( did_action( 'set_current_user' ) ) {
|
||||
$this->init_admin_hooks();
|
||||
} else {
|
||||
add_action( 'set_current_user', array( $this, 'init_admin_hooks' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function init_admin_hooks() {
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$this->dependencies->admin_ui()->init_hooks();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param string $group
|
||||
* @param string $slot
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
public function get_slot( $group, $slot ) {
|
||||
return $this->dependencies->settings()->get_slot( $group, $slot );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $slot ) {
|
||||
return $this->dependencies->render()->render( $slot );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type 'sidebars', 'menus', 'statics'
|
||||
* @param string|int $slug_or_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_button_to_edit_slot( $type, $slug_or_id ) {
|
||||
return $this->dependencies->admin_ui()->get_button_to_edit_slot( $type, $slug_or_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function parameters() {
|
||||
return array(
|
||||
'css_prefix' => 'wpml-ls-',
|
||||
'core_templates' => array(
|
||||
'dropdown' => 'wpml-legacy-dropdown',
|
||||
'dropdown-click' => 'wpml-legacy-dropdown-click',
|
||||
'list-vertical' => 'wpml-legacy-vertical-list',
|
||||
'list-horizontal' => 'wpml-legacy-horizontal-list',
|
||||
'post-translations' => 'wpml-legacy-post-translations',
|
||||
'menu-item' => 'wpml-menu-item',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,620 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
class WPML_LS_Admin_UI extends WPML_Templates_Factory {
|
||||
|
||||
const NONCE_NAME = 'wpml-language-switcher-admin';
|
||||
const MAIN_UI_TEMPLATE = 'layout-main.twig';
|
||||
const RESET_UI_TEMPLATE = 'layout-reset.twig';
|
||||
const BUTTON_TEMPLATE = 'layout-slot-edit-button.twig';
|
||||
const SLOT_SLUG_PLACEHOLDER = '%id%';
|
||||
const RESET_NONCE_NAME = 'wpml-language-switcher-reset';
|
||||
|
||||
/* @var WPML_LS_Templates $templates */
|
||||
private $templates;
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var WPML_LS_Render $render */
|
||||
private $render;
|
||||
|
||||
/* @var WPML_LS_Inline_Styles $inline_styles */
|
||||
private $inline_styles;
|
||||
|
||||
/* @var WPML_LS_Assets $assets */
|
||||
private $assets;
|
||||
|
||||
/* @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Menu constructor.
|
||||
*
|
||||
* @param WPML_LS_Templates $templates
|
||||
* @param WPML_LS_Settings $settings
|
||||
* @param WPML_LS_Render $render
|
||||
* @param WPML_LS_Inline_Styles $inline_styles
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_LS_Assets $assets
|
||||
*/
|
||||
public function __construct( $templates, $settings, $render, $inline_styles, $sitepress, $assets = null ) {
|
||||
$this->templates = $templates;
|
||||
$this->settings = $settings;
|
||||
$this->render = $render;
|
||||
$this->inline_styles = $inline_styles;
|
||||
$this->assets = $assets ? $assets : new WPML_LS_Assets( $this->templates, $this->settings );
|
||||
$this->sitepress = $sitepress;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_action( 'wpml_admin_languages_navigation_items', array( $this, 'languages_navigation_items_filter' ) );
|
||||
add_action( 'wpml_admin_after_languages_url_format', array( $this, 'after_languages_url_format_action' ) );
|
||||
add_action( 'wpml_admin_after_wpml_love', array( $this, 'after_wpml_love_action' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts_action' ) );
|
||||
add_action( 'admin_head', array( $this, 'admin_head_action' ) );
|
||||
add_action( 'wp_ajax_wpml-ls-save-settings', array( $this, 'save_settings_action' ) );
|
||||
add_action( 'wp_ajax_wpml-ls-update-preview', array( $this, 'update_preview_action' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public static function get_page_hook() {
|
||||
return WPML_PLUGIN_FOLDER . '/menu/languages.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hook
|
||||
*/
|
||||
public function admin_enqueue_scripts_action( $hook ) {
|
||||
if ( self::get_page_hook() === $hook ) {
|
||||
$suffix = $this->sitepress->get_wp_api()->constant( 'SCRIPT_DEBUG' ) ? '' : '.min';
|
||||
|
||||
wp_register_script(
|
||||
'wpml-language-switcher-settings',
|
||||
ICL_PLUGIN_URL . '/res/js/language-switchers-settings' . $suffix . '.js',
|
||||
array( 'jquery', 'wp-util', 'jquery-ui-sortable', 'jquery-ui-dialog', 'wp-color-picker', 'wp-pointer' )
|
||||
);
|
||||
wp_enqueue_script( 'wpml-language-switcher-settings' );
|
||||
|
||||
wp_enqueue_style( 'wp-pointer' );
|
||||
wp_enqueue_style( 'wp-color-picker' );
|
||||
|
||||
wp_register_style(
|
||||
'wpml-language-switcher-settings',
|
||||
ICL_PLUGIN_URL . '/res/css/wpml-language-switcher-settings.css'
|
||||
);
|
||||
wp_enqueue_style( 'wpml-language-switcher-settings' );
|
||||
|
||||
$js_vars = array(
|
||||
'nonce' => wp_create_nonce( self::NONCE_NAME ),
|
||||
'menus' => $this->settings->get_available_menus(),
|
||||
'sidebars' => $this->settings->get_registered_sidebars(),
|
||||
'color_schemes' => $this->settings->get_default_color_schemes(),
|
||||
'strings' => $this->get_javascript_strings(),
|
||||
'templates' => $this->templates->get_all_templates_data(),
|
||||
);
|
||||
|
||||
wp_localize_script( 'wpml-language-switcher-settings', 'wpml_language_switcher_admin', $js_vars );
|
||||
|
||||
$this->assets->wp_enqueue_scripts_action();
|
||||
}
|
||||
}
|
||||
|
||||
public function admin_head_action() {
|
||||
$this->inline_styles->admin_output();
|
||||
}
|
||||
|
||||
public function save_settings_action() {
|
||||
if ( $this->has_valid_nonce() && isset( $_POST['settings'] ) ) {
|
||||
$new_settings = $this->parse_request_settings( 'settings' );
|
||||
$this->settings->save_settings( $new_settings );
|
||||
$this->maybe_complete_setup_wizard_step( $new_settings );
|
||||
$this->sitepress->get_wp_api()->wp_send_json_success( esc_html__( 'Settings saved', 'sitepress' ) );
|
||||
} else {
|
||||
$this->sitepress->get_wp_api()->wp_send_json_error( esc_html__( "You can't do that!", 'sitepress' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $new_settings
|
||||
*/
|
||||
private function maybe_complete_setup_wizard_step( $new_settings ) {
|
||||
if ( isset( $new_settings['submit_setup_wizard'] ) && $new_settings['submit_setup_wizard'] == 1 ) {
|
||||
$setup_instance = wpml_get_setup_instance();
|
||||
$setup_instance->finish_step3();
|
||||
}
|
||||
}
|
||||
|
||||
public function update_preview_action() {
|
||||
$preview = false;
|
||||
|
||||
if ( $this->has_valid_nonce() ) {
|
||||
$settings = $this->parse_request_settings( 'slot_settings' );
|
||||
|
||||
foreach ( array( 'menus', 'sidebars', 'statics' ) as $group ) {
|
||||
if ( isset( $settings[ $group ] ) ) {
|
||||
$slot_slug = key( $settings[ $group ] );
|
||||
|
||||
if ( preg_match( '/' . self::SLOT_SLUG_PLACEHOLDER . '/', $slot_slug ) ) {
|
||||
$new_slug = preg_replace( '/' . self::SLOT_SLUG_PLACEHOLDER . '/', '__id__', $slot_slug );
|
||||
$settings[ $group ][ $new_slug ] = $settings[ $group ][ $slot_slug ];
|
||||
unset( $settings[ $group ][ $slot_slug ] );
|
||||
$slot_slug = $new_slug;
|
||||
}
|
||||
|
||||
$settings[ $group ][ $slot_slug ]['slot_slug'] = $slot_slug;
|
||||
$settings[ $group ][ $slot_slug ]['slot_group'] = $group;
|
||||
$settings = $this->settings->convert_slot_settings_to_objects( $settings );
|
||||
$slot = $settings[ $group ][ $slot_slug ];
|
||||
$preview = $this->render->get_preview( $slot );
|
||||
$this->sitepress->get_wp_api()->wp_send_json_success( $preview );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $preview ) {
|
||||
$this->sitepress->get_wp_api()->wp_send_json_error( esc_html__( 'Preview update failed', 'sitepress' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
private function parse_request_settings( $key ) {
|
||||
$settings = array_key_exists( $key, $_POST ) ? $_POST[ $key ] : null;
|
||||
$settings = Sanitize::string($settings, ENT_NOQUOTES);
|
||||
|
||||
$settings = urldecode( $settings );
|
||||
parse_str( $settings, $settings_array );
|
||||
return $settings_array;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function has_valid_nonce() {
|
||||
$nonce = Sanitize::stringProp( 'nonce', $_POST );
|
||||
|
||||
return (bool) wp_verify_nonce( $nonce, self::NONCE_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function languages_navigation_items_filter( $items ) {
|
||||
$item_to_insert = array( '#wpml-ls-settings-form' => esc_html__( 'Language switcher options', 'sitepress' ) );
|
||||
$insert_position = array_search( '#lang-sec-2', array_keys( $items ), true ) + 1;
|
||||
|
||||
$items = array_merge( array_slice( $items, 0, $insert_position ), $item_to_insert, array_slice( $items, $insert_position ) );
|
||||
|
||||
$items['#wpml_ls_reset'] = esc_html__( 'Reset settings', 'sitepress' );
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
public function after_languages_url_format_action() {
|
||||
$setup_wizard_step = (int) $this->sitepress->get_setting( 'setup_wizard_step' );
|
||||
$setup_complete = $this->sitepress->get_setting( 'setup_complete' );
|
||||
$active_languages = $this->sitepress->get_active_languages();
|
||||
|
||||
if ( 3 === $setup_wizard_step || ( ! empty( $setup_complete ) && count( $active_languages ) > 1 ) ) {
|
||||
$this->show( self::MAIN_UI_TEMPLATE, $this->get_main_ui_model() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|bool $theme_wpml_config_file
|
||||
*/
|
||||
public function after_wpml_love_action( $theme_wpml_config_file ) {
|
||||
$setup_complete = $this->sitepress->get_setting( 'setup_complete' );
|
||||
$active_languages = $this->sitepress->get_active_languages();
|
||||
|
||||
if ( $setup_complete && count( $active_languages ) > 1 ) {
|
||||
$this->show( self::RESET_UI_TEMPLATE, $this->get_reset_ui_model( $theme_wpml_config_file ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $type 'sidebars', 'menus', 'statics'
|
||||
* @param string|int $slug_or_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_button_to_edit_slot( $type, $slug_or_id ) {
|
||||
$slug = $slug_or_id;
|
||||
|
||||
if ( 'menus' === $type ) {
|
||||
$menu = wp_get_nav_menu_object( $slug_or_id );
|
||||
$slug = isset( $menu->term_id ) ? $menu->term_id : null;
|
||||
}
|
||||
|
||||
$slot = $this->settings->get_slot( $type, $slug );
|
||||
$url = admin_url( 'admin.php?page=' . self::get_page_hook() . '#' . $type . '/' . $slug );
|
||||
|
||||
if ( $slot->slug() === $slug ) {
|
||||
$model = array(
|
||||
'action' => 'edit',
|
||||
'url' => $url,
|
||||
'label' => __( 'Customize the language switcher', 'sitepress' ),
|
||||
);
|
||||
} else {
|
||||
$model = array(
|
||||
'action' => 'add',
|
||||
'url' => $url,
|
||||
'label' => __( 'Add a language switcher', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
return $this->get_view( self::BUTTON_TEMPLATE, $model );
|
||||
}
|
||||
|
||||
protected function init_template_base_dir() {
|
||||
$this->template_paths = array(
|
||||
WPML_PLUGIN_PATH . '/templates/language-switcher-admin-ui/',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_template() {
|
||||
return self::MAIN_UI_TEMPLATE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_all_previews() {
|
||||
$previews = array();
|
||||
|
||||
foreach ( array( 'menus', 'sidebars', 'statics' ) as $slot_group ) {
|
||||
|
||||
$previews[ $slot_group ] = array();
|
||||
|
||||
foreach ( $this->settings->get_setting( $slot_group ) as $slug => $slot_settings ) {
|
||||
$prev = $this->render->get_preview( $slot_settings );
|
||||
|
||||
foreach ( array( 'html', 'css', 'js', 'styles' ) as $preview_part ) {
|
||||
$previews[ $slot_group ][ $slug ][ $preview_part ] = $prev[ $preview_part ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $previews;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is compulsory but should not be used
|
||||
* Use "get_main_ui_model" and "get_reset_ui_model" instead
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_model() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_main_ui_model() {
|
||||
$slot_factory = new WPML_LS_Slot_Factory();
|
||||
|
||||
$model = array(
|
||||
'strings' => array(
|
||||
'misc' => $this->get_misc_strings(),
|
||||
'tooltips' => $this->get_tooltip_strings(),
|
||||
'color_picker' => $this->get_color_picker_strings(),
|
||||
'options' => $this->get_options_section_strings(),
|
||||
'menus' => $this->get_menus_section_strings(),
|
||||
'sidebars' => $this->get_sidebars_section_strings(),
|
||||
'footer' => $this->get_footer_section_strings(),
|
||||
'post_translations' => $this->get_post_translations_strings(),
|
||||
'shortcode_actions' => $this->get_shortcode_actions_strings(),
|
||||
),
|
||||
'data' => array(
|
||||
'templates' => $this->templates->get_templates(),
|
||||
'menus' => $this->settings->get_available_menus(),
|
||||
'sidebars' => $this->settings->get_registered_sidebars(),
|
||||
),
|
||||
'ordered_languages' => $this->settings->get_ordered_languages(),
|
||||
'settings' => $this->settings->get_settings_model(),
|
||||
'settings_slug' => $this->settings->get_settings_base_slug(),
|
||||
'previews' => $this->get_all_previews(),
|
||||
'color_schemes' => $this->settings->get_default_color_schemes(),
|
||||
'notifications' => $this->get_notifications(),
|
||||
'default_menus_slot' => $slot_factory->get_default_slot_arguments( 'menus' ),
|
||||
'default_sidebars_slot' => $slot_factory->get_default_slot_arguments( 'sidebars' ),
|
||||
'setup_complete' => $this->sitepress->get_setting( 'setup_complete' ),
|
||||
'setup_step_2_nonce_field' => wp_nonce_field( 'setup_got_to_step2_nonce', '_icl_nonce_gts2', true, false ),
|
||||
);
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_misc_strings() {
|
||||
return array(
|
||||
'no_templates' => __( 'There are no templates available.', 'sitepress' ),
|
||||
'label_preview' => _x( 'Preview', 'Language switcher preview', 'sitepress' ),
|
||||
'label_position' => _x( 'Position', 'Language switcher preview', 'sitepress' ),
|
||||
'label_actions' => _x( 'Actions', 'Language switcher preview', 'sitepress' ),
|
||||
'label_action' => _x( 'Action', 'Language switcher preview', 'sitepress' ),
|
||||
'button_save' => __( 'Save', 'sitepress' ),
|
||||
'button_cancel' => __( 'Cancel', 'sitepress' ),
|
||||
'title_what_to_include' => __( 'What to include in the language switcher:', 'sitepress' ),
|
||||
'label_include_flag' => __( 'Flag', 'sitepress' ),
|
||||
'label_include_native_lang' => __( 'Native language name', 'sitepress' ),
|
||||
'label_include_display_lang' => __( 'Language name in current language', 'sitepress' ),
|
||||
'label_include_current_lang' => __( 'Current language', 'sitepress' ),
|
||||
'label_include_flag_width' => __( 'Width', 'sitepress' ),
|
||||
'label_include_flag_height' => __( 'Height', 'sitepress' ),
|
||||
'label_include_flag_width_placeholder' => __( 'auto', 'sitepress' ),
|
||||
'label_include_flag_height_placeholder' => __( 'auto', 'sitepress' ),
|
||||
'label_include_flag_width_suffix' => __( 'px', 'sitepress' ),
|
||||
'label_include_flag_height_suffix' => __( 'px', 'sitepress' ),
|
||||
'templates_dropdown_label' => __( 'Language switcher style:', 'sitepress' ),
|
||||
'templates_wpml_group' => __( 'WPML', 'sitepress' ),
|
||||
'templates_custom_group' => __( 'Custom', 'sitepress' ),
|
||||
'title_action_edit' => __( 'Edit language switcher', 'sitepress' ),
|
||||
'title_action_delete' => __( 'Delete language switcher', 'sitepress' ),
|
||||
'button_back' => __( 'Back', 'sitepress' ),
|
||||
'button_next' => __( 'Next', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_tooltip_strings() {
|
||||
return array(
|
||||
'languages_order' => array(
|
||||
'text' => __( 'This is the order in which the languages will be displayed in the language switcher.', 'sitepress' ),
|
||||
),
|
||||
'languages_without_translation' => array(
|
||||
'text' => __( 'Some content may not be translated to all languages. Choose what should appear in the language switcher when translation is missing.', 'sitepress' ),
|
||||
),
|
||||
'preserve_url_arguments' => array(
|
||||
'text' => __( 'Add a comma-separated list of URL arguments that you want WPML to pass when switching languages.', 'sitepress' ),
|
||||
'link' => array(
|
||||
'text' => __( 'Preserving URL arguments', 'sitepress' ),
|
||||
'url' => 'https://wpml.org/documentation/getting-started-guide/language-setup/language-switcher-options/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore#preserving-url-parameters',
|
||||
'target' => '_blank',
|
||||
),
|
||||
),
|
||||
'additional_css' => array(
|
||||
'text' => __( 'Enter CSS to add to the page. This is useful when you want to add styling to the language switcher, without having to edit the CSS file on the server.', 'sitepress' ),
|
||||
'link' => array(
|
||||
'text' => __( 'Styling the language switcher with additional CSS', 'sitepress' ),
|
||||
'url' => 'https://wpml.org/documentation/getting-started-guide/language-setup/language-switcher-options/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore#styling-the-language-switcher-with-additional-css',
|
||||
'target' => '_blank',
|
||||
),
|
||||
),
|
||||
'section_post_translations' => array(
|
||||
'text' => __( 'You can display links to translation of posts before the post and after it. These links look like "This post is also available in..."', 'sitepress' ),
|
||||
),
|
||||
'add_menu_all_assigned' => array(
|
||||
'text' => __( 'The button is disabled because all existing menus have language switchers. You can edit the settings of the existing language switchers.', 'sitepress' ),
|
||||
),
|
||||
'add_menu_no_menu' => array(
|
||||
'text' => __( 'The button is disabled because there are no menus in the site. Add a menu and you can later enable a language switcher in it.', 'sitepress' ),
|
||||
),
|
||||
'add_sidebar_all_assigned' => array(
|
||||
'text' => __( 'The button is disabled because all existing widget areas have language switchers. You can edit the settings of the existing language switchers.', 'sitepress' ),
|
||||
),
|
||||
'add_sidebar_no_sidebar' => array(
|
||||
'text' => __( 'The button is disabled because there are no registered widget areas in the site.', 'sitepress' ),
|
||||
),
|
||||
'what_to_include' => array(
|
||||
'text' => __( 'Elements to include in the language switcher.', 'sitepress' ),
|
||||
),
|
||||
'available_menus' => array(
|
||||
'text' => __( 'Select the menus, in which to display the language switcher.', 'sitepress' ),
|
||||
),
|
||||
'available_sidebars' => array(
|
||||
'text' => __( 'Select the widget area where to include the language switcher.', 'sitepress' ),
|
||||
),
|
||||
'available_templates' => array(
|
||||
'text' => __( 'Select the style of the language switcher.', 'sitepress' ),
|
||||
),
|
||||
'menu_style_type' => array(
|
||||
'text' => __( 'Select how to display the language switcher in the menu. Choose "List of languages" to display all the items at the same level or "Dropdown" to display the current language as parent and other languages as children.', 'sitepress' ),
|
||||
),
|
||||
'menu_position' => array(
|
||||
'text' => __( 'Select the position to display the language switcher in the menu.', 'sitepress' ),
|
||||
),
|
||||
'widget_title' => array(
|
||||
'text' => __( 'Enter the title of the widget or leave empty for no title.', 'sitepress' ),
|
||||
),
|
||||
'post_translation_position' => array(
|
||||
'text' => __( 'Select the position to display the post translations links.', 'sitepress' ),
|
||||
),
|
||||
'alternative_languages_text' => array(
|
||||
'text' => __( 'This text appears before the list of languages. Your text needs to include the string %s which is a placeholder for the actual links.', 'sitepress' ),
|
||||
),
|
||||
'backwards_compatibility' => array(
|
||||
'text' => __( "Since WPML 3.6.0, the language switchers are not using CSS IDs and the CSS classes have changed. This was required to fix some bugs and match the latest standards. If your theme or your custom CSS is not relying on these old selectors, it's recommended to skip the backwards compatibility. However, it's still possible to re-activate this option later.", 'sitepress' ),
|
||||
),
|
||||
'show_in_footer' => array(
|
||||
'text' => __( "You can display a language switcher in the site's footer. You can customize and style it here.", 'sitepress' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_options_section_strings() {
|
||||
return array(
|
||||
'section_title' => __( 'Language switcher options', 'sitepress' ),
|
||||
'section_description' => __( 'All language switchers in your site are affected by the settings in this section.', 'sitepress' ),
|
||||
'label_language_order' => __( 'Order of languages', 'sitepress' ),
|
||||
'tip_drag_languages' => __( 'Drag and drop the languages to change their order', 'sitepress' ),
|
||||
'label_languages_with_no_translations' => __( 'How to handle languages without translation', 'sitepress' ),
|
||||
'option_skip_link' => __( 'Skip language', 'sitepress' ),
|
||||
'option_link_home' => __( 'Link to home of language for missing translations', 'sitepress' ),
|
||||
'label_preserve_url_args' => __( 'Preserve URL arguments', 'sitepress' ),
|
||||
'label_additional_css' => __( 'Additional CSS', 'sitepress' ),
|
||||
'label_migrated_toggle' => __( 'Backwards compatibility', 'sitepress' ),
|
||||
'label_skip_backwards_compatibility' => __( 'Skip backwards compatibility', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_menus_section_strings() {
|
||||
return array(
|
||||
'section_title' => __( 'Menu language switcher', 'sitepress' ),
|
||||
'add_button_label' => __( 'Add a new language switcher to a menu', 'sitepress' ),
|
||||
'select_label' => __( 'Menu', 'sitepress' ),
|
||||
'select_option_choose' => __( 'Choose a menu', 'sitepress' ),
|
||||
'position_label' => __( 'Position:', 'sitepress' ),
|
||||
'position_first_item' => __( 'First menu item', 'sitepress' ),
|
||||
'position_last_item' => __( 'Last menu item', 'sitepress' ),
|
||||
'is_hierarchical_label' => __( 'Language menu items style:', 'sitepress' ),
|
||||
'flat' => __( 'List of languages', 'sitepress' ),
|
||||
'flat_desc' => __( 'good for menus that display items as a list', 'sitepress' ),
|
||||
'hierarchical' => __( 'Dropdown', 'sitepress' ),
|
||||
'hierarchical_desc' => __( 'good for menus that support drop-downs', 'sitepress' ),
|
||||
'dialog_title' => __( 'Edit Menu Language Switcher', 'sitepress' ),
|
||||
'dialog_title_new' => __( 'New Menu Language Switcher', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_sidebars_section_strings() {
|
||||
return array(
|
||||
'section_title' => __( 'Widget language switcher', 'sitepress' ),
|
||||
'add_button_label' => __( 'Add a new language switcher to a widget area', 'sitepress' ),
|
||||
'select_label' => __( 'Widget area', 'sitepress' ),
|
||||
'select_option_choose' => __( 'Choose a widget area', 'sitepress' ),
|
||||
'label_widget_title' => __( 'Widget title:', 'sitepress' ),
|
||||
'dialog_title' => __( 'Edit Widget Area Language Switcher', 'sitepress' ),
|
||||
'dialog_title_new' => __( 'New Widget Area language switcher', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_footer_section_strings() {
|
||||
return array(
|
||||
'section_title' => __( 'Footer language switcher', 'sitepress' ),
|
||||
'show' => __( 'Show language switcher in footer', 'sitepress' ),
|
||||
'dialog_title' => __( 'Edit Footer Language Switcher', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_post_translations_strings() {
|
||||
return array(
|
||||
'section_title' => __( 'Links to translation of posts', 'sitepress' ),
|
||||
'show' => __( 'Show links above or below posts, offering them in other languages', 'sitepress' ),
|
||||
'position_label' => __( 'Position of link(s):', 'sitepress' ),
|
||||
'position_above' => __( 'Above post', 'sitepress' ),
|
||||
'position_below' => __( 'Below post', 'sitepress' ),
|
||||
'label_alternative_languages_text' => __( 'Text for alternative languages for posts:', 'sitepress' ),
|
||||
'default_alternative_languages_text' => __( 'This post is also available in: %s', 'sitepress' ),
|
||||
'dialog_title' => __( 'Edit Post Translations Language Switcher', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_shortcode_actions_strings() {
|
||||
|
||||
$description_link_text = _x( "insert WPML's switchers in custom locations", 'Custom languuage switcher description: external link text', 'sitepress' );
|
||||
$description_link_url = 'https://wpml.org/documentation/getting-started-guide/language-setup/language-switcher-options/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore#custom-locations';
|
||||
$description_link = '<a href="' . $description_link_url . '" target="_blank">' . $description_link_text . '</a>';
|
||||
$description = _x( 'Need more options? See how you can %s.', 'Custom languuage switcher description: text', 'sitepress' );
|
||||
|
||||
return array(
|
||||
'section_title' => __( 'Custom language switchers', 'sitepress' ),
|
||||
'section_description' => sprintf( $description, $description_link ),
|
||||
'show' => __( 'Enable', 'sitepress' ),
|
||||
'customize_button_label' => __( 'Customize', 'sitepress' ),
|
||||
'dialog_title' => __( 'Edit Shortcode Actions Language Switcher', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_color_picker_strings() {
|
||||
return array(
|
||||
'panel_title' => __( 'Language switcher colors', 'sitepress' ),
|
||||
'label_color_preset' => __( 'Color themes:', 'sitepress' ),
|
||||
'select_option_choose' => __( 'Select a preset', 'sitepress' ),
|
||||
'label_normal_scheme' => __( 'Normal', 'sitepress' ),
|
||||
'label_hover_scheme' => __( 'Hover', 'sitepress' ),
|
||||
'background' => __( 'Background', 'sitepress' ),
|
||||
'border' => __( 'Border', 'sitepress' ),
|
||||
'font_current' => __( 'Current language font color', 'sitepress' ),
|
||||
'background_current' => __( 'Current language background color', 'sitepress' ),
|
||||
'font_other' => __( 'Other language font color', 'sitepress' ),
|
||||
'background_other' => __( 'Other language background color', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_javascript_strings() {
|
||||
return array(
|
||||
'confirmation_item_remove' => esc_html__( 'Do you really want to remove this item?', 'sitepress' ),
|
||||
'leave_text_box_to_save' => esc_html__( 'Leave the text box to auto-save', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|bool $theme_wpml_config_file
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_reset_ui_model( $theme_wpml_config_file ) {
|
||||
$reset_locations = esc_html__( 'in options, menus, widgets, footer and shortcode', 'sitepress' );
|
||||
|
||||
$model = array(
|
||||
'title' => __( 'Reset settings', 'sitepress' ),
|
||||
'description' => sprintf( esc_html__( 'This will change the settings of your language switchers %s to their defaults as set by the theme. Please note that some switchers may be removed and others may be added.', 'sitepress' ), '<strong>(' . $reset_locations . ')</strong>' ),
|
||||
'theme_config_file' => $theme_wpml_config_file,
|
||||
'explanation_text' => sprintf( esc_html__( '* Your theme has a %s file, which sets the default values for WPML.', 'sitepress' ), '<strong title="' . esc_attr( $theme_wpml_config_file ) . '">wpml-config.xml</strong>' ),
|
||||
'confirmation_message' => __( 'Are you sure you want to reset to the default settings?', 'sitepress' ),
|
||||
'restore_page_url' => admin_url( 'admin.php?page=' . self::get_page_hook() . '&restore_ls_settings=1&nonce=' . wp_create_nonce( self::RESET_NONCE_NAME ) ),
|
||||
'restore_button_label' => __( 'Restore default', 'sitepress' ),
|
||||
);
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_notifications() {
|
||||
$notifications = array();
|
||||
|
||||
if ( $this->sitepress->get_wp_api()->constant( 'ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS' ) ) {
|
||||
$notifications['css_not_loaded'] = sprintf(
|
||||
__( "%s is defined in your theme. The language switcher can only be customized using the theme's CSS.", 'sitepress' ),
|
||||
'ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS'
|
||||
);
|
||||
}
|
||||
|
||||
return $notifications;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Assets {
|
||||
|
||||
/* @var array $enqueued_templates */
|
||||
private $enqueued_templates = array();
|
||||
|
||||
/* @var WPML_LS_Templates $templates */
|
||||
private $templates;
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Render_Assets constructor.
|
||||
*
|
||||
* @param WPML_LS_Templates $templates
|
||||
* @param WPML_LS_Settings $settings
|
||||
*/
|
||||
public function __construct( $templates, &$settings ) {
|
||||
$this->templates = $templates;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts_action' ) );
|
||||
}
|
||||
|
||||
public function wp_enqueue_scripts_action() {
|
||||
$active_templates_slugs = $this->settings->get_active_templates();
|
||||
|
||||
/**
|
||||
* Filter the templates to be enqueued (CSS & JS)
|
||||
* To use if a language switcher is rendered
|
||||
* with a specific template later in the script
|
||||
*
|
||||
* @param array $active_templates
|
||||
*/
|
||||
$active_templates_slugs = apply_filters( 'wpml_ls_enqueue_templates', $active_templates_slugs );
|
||||
|
||||
$templates = $this->templates->get_templates( $active_templates_slugs );
|
||||
|
||||
foreach ( $templates as $slug => $template ) {
|
||||
$this->enqueue_template_resources( $slug, $template );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*/
|
||||
public function maybe_late_enqueue_template( $slug ) {
|
||||
if ( ! in_array( $slug, $this->enqueued_templates ) ) {
|
||||
$template = $this->templates->get_template( $slug );
|
||||
$this->enqueue_template_resources( $slug, $template );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
* @param WPML_LS_Template $template
|
||||
*/
|
||||
private function enqueue_template_resources( $slug, $template ) {
|
||||
$this->enqueued_templates[] = $slug;
|
||||
if ( $this->settings->can_load_script( $slug ) ) {
|
||||
|
||||
foreach ( $template->get_scripts() as $k => $url ) {
|
||||
wp_enqueue_script( $template->get_resource_handler( $k ), $url, array(), $template->get_version() );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->settings->can_load_styles( $slug ) ) {
|
||||
|
||||
foreach ( $template->get_styles() as $k => $url ) {
|
||||
wp_enqueue_style( $template->get_resource_handler( $k ), $url, array(), $template->get_version() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Dependencies_Factory {
|
||||
|
||||
/* @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/* @var array $parameters */
|
||||
private $parameters;
|
||||
|
||||
/* @var WPML_LS_Templates $templates */
|
||||
private $templates;
|
||||
|
||||
/* @var WPML_LS_Slot_Factory $slot_factory */
|
||||
private $slot_factory;
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var WPML_LS_Model_Build $model_build */
|
||||
private $model_build;
|
||||
|
||||
/* @var WPML_LS_Inline_Styles $inline_styles */
|
||||
private $inline_styles;
|
||||
|
||||
/* @var WPML_LS_Render $render */
|
||||
private $render;
|
||||
|
||||
/* @var WPML_LS_Admin_UI $admin_ui */
|
||||
private $admin_ui;
|
||||
|
||||
/** @var WPML_LS_Shortcodes */
|
||||
private $shortcodes;
|
||||
|
||||
/** @var WPML_LS_Actions */
|
||||
private $actions;
|
||||
|
||||
/**
|
||||
* WPML_LS_Dependencies_Factory constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param array $parameters
|
||||
*/
|
||||
public function __construct( SitePress $sitepress, array $parameters = [] ) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return SitePress
|
||||
*/
|
||||
public function sitepress() {
|
||||
return $this->sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function parameter( $key ) {
|
||||
return isset( $this->parameters[ $key ] ) ? $this->parameters[ $key ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Templates
|
||||
*/
|
||||
public function templates() {
|
||||
if ( ! $this->templates ) {
|
||||
$this->templates = new WPML_LS_Templates();
|
||||
}
|
||||
|
||||
return $this->templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Slot_Factory
|
||||
*/
|
||||
public function slot_factory() {
|
||||
if ( ! $this->slot_factory ) {
|
||||
$this->slot_factory = new WPML_LS_Slot_Factory();
|
||||
}
|
||||
|
||||
return $this->slot_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Settings
|
||||
*/
|
||||
public function settings() {
|
||||
if ( ! $this->settings ) {
|
||||
$this->settings = new WPML_LS_Settings( $this->templates(), $this->sitepress(), $this->slot_factory() );
|
||||
}
|
||||
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Model_Build
|
||||
*/
|
||||
public function model_build() {
|
||||
if ( ! $this->model_build ) {
|
||||
$this->model_build = new WPML_LS_Model_Build( $this->settings(), $this->sitepress(), $this->parameter( 'css_prefix' ) );
|
||||
}
|
||||
|
||||
return $this->model_build;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Inline_Styles
|
||||
*/
|
||||
public function inline_styles() {
|
||||
if ( ! $this->inline_styles ) {
|
||||
$this->inline_styles = new WPML_LS_Inline_Styles( $this->templates(), $this->settings(), $this->model_build() );
|
||||
}
|
||||
|
||||
return $this->inline_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Render
|
||||
*/
|
||||
public function render() {
|
||||
if ( ! $this->render ) {
|
||||
$this->render = new WPML_LS_Render( $this->templates(), $this->settings(), $this->model_build(), $this->inline_styles(), $this->sitepress() );
|
||||
}
|
||||
|
||||
return $this->render;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Admin_UI
|
||||
*/
|
||||
public function admin_ui() {
|
||||
if ( ! $this->admin_ui ) {
|
||||
$this->admin_ui = new WPML_LS_Admin_UI( $this->templates(), $this->settings(), $this->render(), $this->inline_styles(), $this->sitepress() );
|
||||
}
|
||||
|
||||
return $this->admin_ui;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Shortcodes
|
||||
*/
|
||||
public function shortcodes() {
|
||||
if ( ! $this->shortcodes ) {
|
||||
$this->shortcodes = new WPML_LS_Shortcodes( $this->settings(), $this->render(), $this->sitepress() );
|
||||
}
|
||||
|
||||
return $this->shortcodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Shortcodes
|
||||
*/
|
||||
public function actions() {
|
||||
if ( ! $this->actions ) {
|
||||
$this->actions = new WPML_LS_Actions( $this->settings(), $this->render(), $this->sitepress() );
|
||||
}
|
||||
|
||||
return $this->actions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: bruce
|
||||
* Date: 17/10/17
|
||||
* Time: 10:56 PM
|
||||
*/
|
||||
|
||||
use WPML\FP\Obj;
|
||||
|
||||
class WPML_LS_Display_As_Translated_Link {
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
/** @var IWPML_URL_Converter_Strategy $url_converter */
|
||||
private $url_converter;
|
||||
/** @var WP_Query $wp_query */
|
||||
private $wp_query;
|
||||
/** @var WPML_Translation_Element_Factory $element_factory */
|
||||
private $element_factory;
|
||||
/** @var string $default_language */
|
||||
private $default_language;
|
||||
/** @var string $processed_language */
|
||||
private $processed_language;
|
||||
|
||||
public function __construct(
|
||||
SitePress $sitepress,
|
||||
IWPML_URL_Converter_Strategy $url_converter,
|
||||
WP_Query $wp_query,
|
||||
WPML_Translation_Element_Factory $element_factory
|
||||
) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->url_converter = $url_converter;
|
||||
$this->wp_query = $wp_query;
|
||||
$this->element_factory = $element_factory;
|
||||
$this->default_language = $sitepress->get_default_language();
|
||||
}
|
||||
|
||||
public function get_url( $translations, $lang ) {
|
||||
$queried_object = $this->wp_query->get_queried_object();
|
||||
if ( $queried_object instanceof WP_Post ) {
|
||||
return $this->get_post_url( $translations, $lang, $queried_object );
|
||||
} elseif ( $queried_object instanceof WP_Term ) {
|
||||
return $this->get_term_url( $translations, $lang, $queried_object );
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private function get_post_url( $translations, $lang, $queried_object ) {
|
||||
$url = null;
|
||||
|
||||
if ( $this->sitepress->is_display_as_translated_post_type( $queried_object->post_type ) &&
|
||||
isset( $translations[ $this->default_language ] ) ) {
|
||||
|
||||
$this->sitepress->switch_lang( $this->default_language );
|
||||
$this->processed_language = $lang;
|
||||
|
||||
$setLanguageCode = Obj::set( Obj::lensProp( 'language_code' ), $lang );
|
||||
|
||||
add_filter( 'post_link_category', array( $this, 'adjust_category_in_post_permalink' ) );
|
||||
add_filter( 'wpml_st_post_type_link_filter_language_details', $setLanguageCode );
|
||||
|
||||
$url = get_permalink( $translations[ $this->default_language ]->element_id );
|
||||
|
||||
remove_filter( 'wpml_st_post_type_link_filter_language_details', $setLanguageCode );
|
||||
remove_filter( 'post_link_category', array( $this, 'adjust_category_in_post_permalink' ) );
|
||||
|
||||
$this->sitepress->switch_lang();
|
||||
$url = $this->url_converter->convert_url_string( $url, $lang );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
private function get_term_url( $translations, $lang, $queried_object ) {
|
||||
$url = null;
|
||||
|
||||
if ( $this->sitepress->is_display_as_translated_taxonomy( $queried_object->taxonomy ) &&
|
||||
isset( $translations[ $this->default_language ] ) ) {
|
||||
|
||||
$url = get_term_link( (int) $translations[ $this->default_language ]->term_id, $queried_object->taxonomy );
|
||||
$url = $this->url_converter->convert_url_string( $url, $lang );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* The permalink needs to be adjusted when the URL structure contains the category tag (%category%).
|
||||
*
|
||||
* @param WP_Term $cat
|
||||
*
|
||||
* @return WP_Term
|
||||
*/
|
||||
public function adjust_category_in_post_permalink( $cat ) {
|
||||
$cat_element = $this->element_factory->create( $cat->term_id, 'term' );
|
||||
$translation = $cat_element->get_translation( $this->processed_language );
|
||||
|
||||
if ( $translation ) {
|
||||
$cat = $translation->get_wp_object() ?: $cat;
|
||||
}
|
||||
|
||||
return $cat;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,306 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Inline_Styles {
|
||||
|
||||
/* @var WPML_LS_Templates $templates */
|
||||
private $templates;
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var WPML_LS_Model_Build $model_build */
|
||||
private $model_build;
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Render_Assets constructor.
|
||||
*
|
||||
* @param WPML_LS_Templates $templates
|
||||
* @param WPML_LS_Settings $settings
|
||||
* @param WPML_LS_Model_Build $model_build
|
||||
*/
|
||||
public function __construct( $templates, $settings, $model_build ) {
|
||||
$this->templates = $templates;
|
||||
$this->settings = $settings;
|
||||
$this->model_build = $model_build;
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'wp_enqueue_scripts_action' ), 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_slot_color_picker_css( $slot ) {
|
||||
$css = '';
|
||||
|
||||
if ( $slot->is_menu() ) {
|
||||
$css = $this->get_slot_color_picker_css_for_menus( $slot );
|
||||
} elseif ( ! $slot->is_post_translations() ) {
|
||||
$css = $this->get_slot_color_picker_css_for_widgets_and_statics( $slot );
|
||||
}
|
||||
|
||||
return $this->sanitize_css( $css );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_slot_color_picker_css_for_menus( $slot ) {
|
||||
$css = '';
|
||||
$prefix = '.' . $this->model_build->get_css_prefix();
|
||||
$menu_item_class = $prefix . 'slot-' . $slot->slug();
|
||||
|
||||
if ( $slot->get( 'background_other_normal' ) || $slot->get( 'font_other_normal' ) ) {
|
||||
$css .= "$menu_item_class,";
|
||||
$css .= " $menu_item_class a,";
|
||||
$css .= " $menu_item_class a:visited{";
|
||||
$css .= $slot->get( 'background_other_normal' ) ? "background-color:{$slot->get( 'background_other_normal' )};" : '';
|
||||
$css .= $slot->get( 'font_other_normal' ) ? "color:{$slot->get( 'font_other_normal' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_other_hover' ) || $slot->get( 'background_other_hover' ) ) {
|
||||
$css .= "$menu_item_class:hover,";
|
||||
$css .= " $menu_item_class:hover a,";
|
||||
$css .= " $menu_item_class a:hover{";
|
||||
$css .= $slot->get( 'font_other_hover' ) ? "color:{$slot->get( 'font_other_hover' )};" : '';
|
||||
$css .= $slot->get( 'background_other_hover' ) ? "background-color:{$slot->get( 'background_other_hover' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_current_normal' ) || $slot->get( 'background_current_normal' ) ) {
|
||||
$css .= "$menu_item_class{$prefix}current-language,";
|
||||
$css .= " $menu_item_class{$prefix}current-language a,";
|
||||
$css .= " $menu_item_class{$prefix}current-language a:visited{";
|
||||
$css .= $slot->get( 'font_current_normal' ) ? "color:{$slot->get( 'font_current_normal' )};" : '';
|
||||
$css .= $slot->get( 'background_current_normal' ) ? "background-color:{$slot->get( 'background_current_normal' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_current_hover' ) || $slot->get( 'background_current_hover' ) ) {
|
||||
$css .= "$menu_item_class{$prefix}current-language:hover,";
|
||||
$css .= " $menu_item_class{$prefix}current-language:hover a,";
|
||||
$css .= " $menu_item_class{$prefix}current-language a:hover{";
|
||||
$css .= $slot->get( 'font_current_hover' ) ? "color:{$slot->get( 'font_current_hover' )};" : '';
|
||||
$css .= $slot->get( 'background_current_hover' ) ? "background-color:{$slot->get( 'background_current_hover' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
// Override parent menu styles for hierarchical menus
|
||||
if ( $slot->get( 'is_hierarchical' ) ) {
|
||||
|
||||
if ( $slot->get( 'background_other_normal' ) || $slot->get( 'font_other_normal' ) ) {
|
||||
$css .= "$menu_item_class{$prefix}current-language $menu_item_class,";
|
||||
$css .= " $menu_item_class{$prefix}current-language $menu_item_class a,";
|
||||
$css .= " $menu_item_class{$prefix}current-language $menu_item_class a:visited{";
|
||||
$css .= $slot->get( 'background_other_normal' ) ? "background-color:{$slot->get( 'background_other_normal' )};" : '';
|
||||
$css .= $slot->get( 'font_other_normal' ) ? "color:{$slot->get( 'font_other_normal' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_other_hover' ) || $slot->get( 'background_other_hover' ) ) {
|
||||
$css .= "$menu_item_class{$prefix}current-language $menu_item_class:hover,";
|
||||
$css .= " $menu_item_class{$prefix}current-language $menu_item_class:hover a,";
|
||||
$css .= " $menu_item_class{$prefix}current-language $menu_item_class a:hover {";
|
||||
$css .= $slot->get( 'font_other_hover' ) ? "color:{$slot->get( 'font_other_hover' )};" : '';
|
||||
$css .= $slot->get( 'background_other_hover' ) ? "background-color:{$slot->get( 'background_other_hover' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_slot_color_picker_css_for_widgets_and_statics( $slot ) {
|
||||
$css = '';
|
||||
$prefix = '.' . $this->model_build->get_css_prefix();
|
||||
$wrapper_class = '.' . $this->model_build->get_slot_css_main_class( $slot->group(), $slot->slug() );
|
||||
|
||||
if ( $slot->get( 'background_normal' ) ) {
|
||||
$css .= "$wrapper_class{";
|
||||
$css .= "background-color:{$slot->get( 'background_normal' )};";
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'border_normal' ) ) {
|
||||
$css .= "$wrapper_class, $wrapper_class {$prefix}sub-menu, $wrapper_class a {";
|
||||
$css .= "border-color:{$slot->get( 'border_normal' )};";
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_other_normal' ) || $slot->get( 'background_other_normal' ) ) {
|
||||
$css .= "$wrapper_class a {";
|
||||
$css .= $slot->get( 'font_other_normal' ) ? "color:{$slot->get( 'font_other_normal' )};" : '';
|
||||
$css .= $slot->get( 'background_other_normal' ) ? "background-color:{$slot->get( 'background_other_normal' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_other_hover' ) || $slot->get( 'background_other_hover' ) ) {
|
||||
$css .= "$wrapper_class a:hover,$wrapper_class a:focus {";
|
||||
$css .= $slot->get( 'font_other_hover' ) ? "color:{$slot->get( 'font_other_hover' )};" : '';
|
||||
$css .= $slot->get( 'background_other_hover' ) ? "background-color:{$slot->get( 'background_other_hover' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_current_normal' ) || $slot->get( 'background_current_normal' ) ) {
|
||||
$css .= "$wrapper_class {$prefix}current-language>a {";
|
||||
$css .= $slot->get( 'font_current_normal' ) ? "color:{$slot->get( 'font_current_normal' )};" : '';
|
||||
$css .= $slot->get( 'background_current_normal' ) ? "background-color:{$slot->get( 'background_current_normal' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
if ( $slot->get( 'font_current_hover' ) || $slot->get( 'background_current_hover' ) ) {
|
||||
$css .= "$wrapper_class {$prefix}current-language:hover>a, $wrapper_class {$prefix}current-language>a:focus {";
|
||||
$css .= $slot->get( 'font_current_hover' ) ? "color:{$slot->get( 'font_current_hover' )};" : '';
|
||||
$css .= $slot->get( 'background_current_hover' ) ? "background-color:{$slot->get( 'background_current_hover' )};" : '';
|
||||
$css .= '}';
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $slots
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_slots_inline_styles( $slots ) {
|
||||
$all_styles = '';
|
||||
|
||||
if ( $this->settings->can_load_styles() ) {
|
||||
|
||||
foreach ( $slots as $slot ) {
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
$css = $this->get_slot_color_picker_css( $slot );
|
||||
|
||||
if ( $css ) {
|
||||
$style_id = 'wpml-ls-inline-styles-' . $slot->group() . '-' . $slot->slug();
|
||||
$all_styles .= '<style type="text/css" id="' . $style_id . '">' . $css . '</style>' . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $all_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_additional_style() {
|
||||
$css = $this->sanitize_css( $this->settings->get_setting( 'additional_css' ) );
|
||||
|
||||
if ( $css ) {
|
||||
$css = '<style type="text/css" id="wpml-ls-inline-styles-additional-css">' . $css . '</style>' . PHP_EOL;
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
public function wp_enqueue_scripts_action() {
|
||||
$this->enqueue_inline_styles();
|
||||
}
|
||||
|
||||
private function enqueue_inline_styles() {
|
||||
if ( $this->settings->can_load_styles() ) {
|
||||
$active_slots = $this->settings->get_active_slots();
|
||||
$first_valid_handler = $this->get_first_valid_style_handler( $active_slots );
|
||||
|
||||
foreach ( $active_slots as $slot ) {
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
$css = $this->get_slot_color_picker_css( $slot );
|
||||
|
||||
if ( empty( $css ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$template = $this->templates->get_template( $slot->template() );
|
||||
|
||||
if ( $template->has_styles() ) {
|
||||
wp_add_inline_style( $template->get_inline_style_handler(), $css );
|
||||
} elseif ( $first_valid_handler ) {
|
||||
wp_add_inline_style( $first_valid_handler, $css );
|
||||
} else {
|
||||
echo $this->get_raw_inline_style_tag( $slot, $css );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $first_valid_handler ) {
|
||||
$additional_css = $this->sanitize_css( $this->settings->get_setting( 'additional_css' ) );
|
||||
|
||||
if ( ! empty( $additional_css ) ) {
|
||||
wp_add_inline_style( $first_valid_handler, $additional_css );
|
||||
}
|
||||
} else {
|
||||
echo $this->get_additional_style();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $active_slots
|
||||
*
|
||||
* @return bool|mixed|null|string
|
||||
*/
|
||||
private function get_first_valid_style_handler( $active_slots ) {
|
||||
$first_handler = null;
|
||||
|
||||
foreach ( $active_slots as $slot ) {
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
$template = $this->templates->get_template( $slot->template() );
|
||||
$handler = $template->get_inline_style_handler();
|
||||
|
||||
if ( $handler ) {
|
||||
$first_handler = $handler;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $first_handler;
|
||||
}
|
||||
|
||||
public function admin_output() {
|
||||
if ( $this->settings->can_load_styles() ) {
|
||||
$active_slots = $this->settings->get_active_slots();
|
||||
|
||||
foreach ( $active_slots as $slot ) {
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
$css = $this->get_slot_color_picker_css( $slot );
|
||||
echo $this->get_raw_inline_style_tag( $slot, $css );
|
||||
}
|
||||
|
||||
echo $this->get_additional_style();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
* @param string $css
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_raw_inline_style_tag( $slot, $css ) {
|
||||
$style_id = 'wpml-ls-inline-styles-' . $slot->group() . '-' . $slot->slug();
|
||||
return '<style type="text/css" id="' . $style_id . '">' . $css . '</style>' . PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $css
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function sanitize_css( $css ) {
|
||||
$css = wp_strip_all_tags( $css );
|
||||
$css = preg_replace( '/\s+/S', ' ', trim( $css ) );
|
||||
return $css;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Created by PhpStorm.
|
||||
* User: bruce
|
||||
* Date: 17/10/17
|
||||
* Time: 5:18 PM
|
||||
*/
|
||||
|
||||
class WPML_LS_Languages_Cache {
|
||||
|
||||
private $cache_key;
|
||||
private $cache;
|
||||
|
||||
public function __construct( $template_args, $current_language, $default_language, $wp_query ) {
|
||||
$cache_key_args = $template_args ? array_filter( $template_args ) : array( 'default' );
|
||||
$cache_key_args[] = $current_language;
|
||||
$cache_key_args[] = $default_language;
|
||||
if ( isset( $wp_query->request ) ) {
|
||||
$cache_key_args[] = $wp_query->request;
|
||||
}
|
||||
$cache_key_args = array_filter( $cache_key_args );
|
||||
$this->cache_key = md5( wp_json_encode( $cache_key_args ) );
|
||||
$cache_group = 'ls_languages';
|
||||
$this->cache = new WPML_WP_Cache( $cache_group );
|
||||
wp_cache_add_non_persistent_groups( $cache_group );
|
||||
}
|
||||
|
||||
public function get() {
|
||||
$found = false;
|
||||
$result = $this->cache->get( $this->cache_key, $found );
|
||||
if ( $found ) {
|
||||
return $result;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function set( $ls_languages ) {
|
||||
$this->cache->set( $this->cache_key, $ls_languages );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Menu_Item {
|
||||
|
||||
/**
|
||||
* @see wp_setup_nav_menu_item() to decorate the object
|
||||
*/
|
||||
public $ID; // The term_id if the menu item represents a taxonomy term.
|
||||
public $attr_title; // The title attribute of the link element for this menu item.
|
||||
public $classes = array(); // The array of class attribute values for the link element of this menu item.
|
||||
public $db_id; // The DB ID of this item as a nav_menu_item object, if it exists (0 if it doesn't exist).
|
||||
public $description; // The description of this menu item.
|
||||
public $menu_item_parent; // The DB ID of the nav_menu_item that is this item's menu parent, if any. 0 otherwise.
|
||||
public $object = 'wpml_ls_menu_item'; // The type of object originally represented, such as "category," "post", or "attachment."
|
||||
public $object_id; // The DB ID of the original object this menu item represents, e.g. ID for posts and term_id for categories.
|
||||
public $post_parent; // The DB ID of the original object's parent object, if any (0 otherwise).
|
||||
public $post_title; // A "no title" label if menu item represents a post that lacks a title.
|
||||
public $target; // The target attribute of the link element for this menu item.
|
||||
public $title; // The title of this menu item.
|
||||
public $type = 'wpml_ls_menu_item'; // The family of objects originally represented, such as "post_type" or "taxonomy."
|
||||
public $type_label; // The singular label used to describe this type of menu item.
|
||||
public $url; // The URL to which this menu item points.
|
||||
public $xfn; // The XFN relationship expressed in the link of this menu item.
|
||||
public $_invalid = false; // Whether the menu item represents an object that no longer exists.
|
||||
public $menu_order;
|
||||
|
||||
public $post_type = 'nav_menu_item'; // * Extra property => see [wpmlcore-3855]
|
||||
|
||||
/**
|
||||
* WPML_LS_Menu_Item constructor.
|
||||
*
|
||||
* @param array $language
|
||||
* @param string $item_content
|
||||
*/
|
||||
public function __construct( $language, $item_content ) {
|
||||
$this->decorate_object( $language, $item_content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lang
|
||||
* @param string $item_content
|
||||
*/
|
||||
private function decorate_object( $lang, $item_content ) {
|
||||
$this->ID = isset( $lang['db_id'] ) ? $lang['db_id'] : null;
|
||||
$this->object_id = isset( $lang['db_id'] ) ? $lang['db_id'] : null;
|
||||
$this->db_id = isset( $lang['db_id'] ) ? $lang['db_id'] : null;
|
||||
$this->menu_item_parent = isset( $lang['menu_item_parent'] ) ? $lang['menu_item_parent'] : null;
|
||||
$this->attr_title = isset( $lang['display_name'] )
|
||||
? $lang['display_name'] : ( isset( $lang['native_name'] ) ? $lang['native_name'] : '' );
|
||||
$this->title = $item_content;
|
||||
$this->post_title = $item_content;
|
||||
$this->url = isset( $lang['url'] ) ? $lang['url'] : null;
|
||||
|
||||
if ( isset( $lang['css_classes'] ) ) {
|
||||
$this->classes = $lang['css_classes'];
|
||||
if ( is_string( $lang['css_classes'] ) ) {
|
||||
$this->classes = explode( ' ', $lang['css_classes'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function __get( $property ) {
|
||||
return isset( $this->{$property} ) ? $this->{$property} : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,339 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Migration {
|
||||
|
||||
const ICL_OPTIONS_SLUG = 'icl_sitepress_settings';
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/* @var WPML_LS_Slot_Factory $slot_factory */
|
||||
private $slot_factory;
|
||||
|
||||
/* @var array $old_settings */
|
||||
private $old_settings;
|
||||
|
||||
/**
|
||||
* WPML_LS_Migration constructor.
|
||||
*
|
||||
* @param WPML_LS_Settings $settings
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_LS_Slot_Factory $slot_factory
|
||||
*/
|
||||
public function __construct( $settings, $sitepress, $slot_factory ) {
|
||||
$this->settings = $settings;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->slot_factory = $slot_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $old_settings
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_converted_settings( $old_settings ) {
|
||||
$this->old_settings = is_array( $old_settings ) ? $old_settings : array();
|
||||
|
||||
$new_settings = array( 'migrated' => 0 );
|
||||
|
||||
if ( $this->has_old_keys() ) {
|
||||
$new_settings = $this->get_converted_global_settings();
|
||||
$new_settings['menus'] = $this->get_converted_menus_settings();
|
||||
$new_settings['sidebars'] = $this->get_converted_sidebars_settings();
|
||||
$new_settings['statics']['footer'] = $this->get_converted_footer_settings();
|
||||
$new_settings['statics']['post_translations'] = $this->get_converted_post_translations_settings();
|
||||
$new_settings['statics']['shortcode_actions'] = $this->get_converted_shortcode_actions_settings();
|
||||
|
||||
$new_settings['migrated'] = 1;
|
||||
}
|
||||
|
||||
return $new_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_converted_global_settings() {
|
||||
$new_settings['additional_css'] = isset( $this->old_settings['icl_additional_css'] )
|
||||
? $this->old_settings['icl_additional_css'] : '';
|
||||
$new_settings['copy_parameters'] = isset( $this->old_settings['icl_lang_sel_copy_parameters'] )
|
||||
? $this->old_settings['icl_lang_sel_copy_parameters'] : '';
|
||||
|
||||
return $new_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_converted_menus_settings() {
|
||||
$menus_settings = array();
|
||||
|
||||
if ( $this->get_old_setting( 'display_ls_in_menu' ) ) {
|
||||
$menu_id = $this->get_old_setting( 'menu_for_ls' );
|
||||
$menu_id = $this->sitepress->get_object_id( $menu_id, 'nav_menu', true, $this->sitepress->get_default_language() );
|
||||
|
||||
if ( $menu_id ) {
|
||||
$s = array(
|
||||
'slot_group' => 'menus',
|
||||
'slot_slug' => $menu_id,
|
||||
'show' => 1,
|
||||
'template' => $this->get_template_for( 'menus' ),
|
||||
'display_flags' => $this->get_old_setting( 'icl_lso_flags' ),
|
||||
'display_names_in_native_lang' => $this->get_old_setting( 'icl_lso_native_lang' ),
|
||||
'display_names_in_current_lang' => $this->get_old_setting( 'icl_lso_display_lang' ),
|
||||
'display_link_for_current_lang' => 1,
|
||||
'position_in_menu' => 'after',
|
||||
'is_hierarchical' => $this->get_old_setting( 'icl_lang_sel_type' ) === 'dropdown' ? 1 : 0,
|
||||
);
|
||||
|
||||
$menus_settings[ $menu_id ] = $this->slot_factory->get_slot( $s );
|
||||
}
|
||||
}
|
||||
|
||||
return $menus_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_converted_sidebars_settings() {
|
||||
$sidebars_settings = array();
|
||||
|
||||
$sidebars_widgets = wp_get_sidebars_widgets();
|
||||
|
||||
foreach ( $sidebars_widgets as $sidebar_slug => $widgets ) {
|
||||
$sidebar_has_selector = false;
|
||||
|
||||
if ( is_array( $widgets ) ) {
|
||||
foreach ( $widgets as $widget ) {
|
||||
if ( strpos( $widget, WPML_LS_Widget::SLUG ) === 0 ) {
|
||||
$sidebar_has_selector = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $sidebar_has_selector ) {
|
||||
$s = array(
|
||||
'slot_group' => 'sidebars',
|
||||
'slot_slug' => $sidebar_slug,
|
||||
'show' => 1,
|
||||
'template' => $this->get_template_for( 'sidebars' ),
|
||||
'display_flags' => $this->get_old_setting( 'icl_lso_flags' ),
|
||||
'display_names_in_native_lang' => $this->get_old_setting( 'icl_lso_native_lang' ),
|
||||
'display_names_in_current_lang' => $this->get_old_setting( 'icl_lso_display_lang' ),
|
||||
'display_link_for_current_lang' => 1,
|
||||
'widget_title' => $this->get_old_setting( 'icl_widget_title_show' )
|
||||
? esc_html__( 'Languages', 'sitepress' ) : '',
|
||||
);
|
||||
|
||||
$s = array_merge( $s, $this->get_color_picker_settings_for( 'sidebars' ) );
|
||||
|
||||
$sidebars_settings[ $sidebar_slug ] = $this->slot_factory->get_slot( $s );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $sidebars_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_converted_footer_settings() {
|
||||
|
||||
$s = array(
|
||||
'slot_group' => 'statics',
|
||||
'slot_slug' => 'footer',
|
||||
'show' => $this->get_old_setting( 'icl_lang_sel_footer' ),
|
||||
'template' => $this->get_template_for( 'footer' ),
|
||||
'display_flags' => $this->get_old_setting( 'icl_lso_flags' ),
|
||||
'display_names_in_native_lang' => $this->get_old_setting( 'icl_lso_native_lang' ),
|
||||
'display_names_in_current_lang' => $this->get_old_setting( 'icl_lso_display_lang' ),
|
||||
'display_link_for_current_lang' => 1,
|
||||
);
|
||||
|
||||
$s = array_merge( $s, $this->get_color_picker_settings_for( 'footer' ) );
|
||||
|
||||
return $this->slot_factory->get_slot( $s );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_converted_post_translations_settings() {
|
||||
$s = array(
|
||||
'slot_group' => 'statics',
|
||||
'slot_slug' => 'post_translations',
|
||||
'show' => $this->get_old_setting( 'icl_post_availability' ),
|
||||
'template' => $this->get_template_for( 'post_translations' ),
|
||||
'display_before_content' => $this->get_old_setting( 'icl_post_availability_position' ) === 'above' ? 1 : 0,
|
||||
'display_after_content' => $this->get_old_setting( 'icl_post_availability_position' ) === 'below' ? 1 : 0,
|
||||
'availability_text' => $this->get_old_setting( 'icl_post_availability_text' ),
|
||||
'display_flags' => 0,
|
||||
'display_names_in_native_lang' => 0,
|
||||
'display_names_in_current_lang' => 1,
|
||||
'display_link_for_current_lang' => 0,
|
||||
);
|
||||
|
||||
return $this->slot_factory->get_slot( $s );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_converted_shortcode_actions_settings() {
|
||||
$s = array(
|
||||
'slot_group' => 'statics',
|
||||
'slot_slug' => 'shortcode_actions',
|
||||
'show' => 1,
|
||||
'template' => $this->get_template_for( 'shortcode_actions' ),
|
||||
'display_flags' => $this->get_old_setting( 'icl_lso_flags' ),
|
||||
'display_names_in_native_lang' => $this->get_old_setting( 'icl_lso_native_lang' ),
|
||||
'display_names_in_current_lang' => $this->get_old_setting( 'icl_lso_display_lang' ),
|
||||
'display_link_for_current_lang' => 1,
|
||||
);
|
||||
|
||||
$s = array_merge( $s, $this->get_color_picker_settings_for( 'shortcode_actions' ) );
|
||||
|
||||
return $this->slot_factory->get_slot( $s );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $context
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_color_picker_settings_for( $context ) {
|
||||
$ret = array();
|
||||
|
||||
$map = array(
|
||||
'font-current-normal' => 'font_current_normal',
|
||||
'font-current-hover' => 'font_current_hover',
|
||||
'background-current-normal' => 'background_current_normal',
|
||||
'background-current-hover' => 'background_current_hover',
|
||||
'font-other-normal' => 'font_other_normal',
|
||||
'font-other-hover' => 'font_other_hover',
|
||||
'background-other-normal' => 'background_other_normal',
|
||||
'background-other-hover' => 'background_other_hover',
|
||||
'border' => 'border_normal',
|
||||
'background' => 'background_normal',
|
||||
);
|
||||
|
||||
$key = $context !== 'footer' ? 'icl_lang_sel_config' : 'icl_lang_sel_footer_config';
|
||||
$settings = isset( $this->old_settings[ $key ] ) ? $this->old_settings[ $key ] : array();
|
||||
|
||||
foreach ( $settings as $k => $v ) {
|
||||
$ret[ $map[ $k ] ] = $v;
|
||||
}
|
||||
|
||||
return array_filter( $ret );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed|string|int|null
|
||||
*/
|
||||
private function get_old_setting( $key ) {
|
||||
return isset( $this->old_settings[ $key ] ) ? $this->old_settings[ $key ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slot_type
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function get_template_for( $slot_type ) {
|
||||
$templates = $this->settings->get_core_templates();
|
||||
$type = 'dropdown';
|
||||
$old_type = $this->get_old_setting( 'icl_lang_sel_type' ); // dropdown | list
|
||||
$old_stype = $this->get_old_setting( 'icl_lang_sel_stype' ); // classic | mobile-auto | mobile
|
||||
$old_orientation = $this->get_old_setting( 'icl_lang_sel_orientation' ); // vertical | horizontal
|
||||
|
||||
if ( $slot_type === 'menus' ) {
|
||||
$type = 'menu-item';
|
||||
} elseif ( $slot_type === 'sidebars' ) {
|
||||
$type = $old_type === 'dropdown' ? 'dropdown' : ( $old_orientation === 'vertical' ? 'list-vertical' : 'list-horizontal' );
|
||||
} elseif ( $slot_type === 'shortcode_actions' ) {
|
||||
$type = $old_type === 'dropdown' ? 'dropdown' : ( $old_orientation === 'vertical' ? 'list-vertical' : 'list-horizontal' );
|
||||
} elseif ( $slot_type === 'footer' ) {
|
||||
$type = 'list-horizontal';
|
||||
} elseif ( $slot_type === 'post_translations' ) {
|
||||
$type = 'post-translations';
|
||||
}
|
||||
|
||||
if ( $type === 'dropdown' ) {
|
||||
$type = $old_stype === 'mobile' ? 'dropdown-click' : 'dropdown';
|
||||
}
|
||||
|
||||
return $templates[ $type ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function has_old_keys() {
|
||||
$result = false;
|
||||
$old_keys = array(
|
||||
'icl_lang_sel_config',
|
||||
'icl_lang_sel_footer_config',
|
||||
'icl_language_switcher_sidebar',
|
||||
'icl_widget_title_show',
|
||||
'icl_lang_sel_type',
|
||||
'icl_lso_flags',
|
||||
'icl_lso_native_lang',
|
||||
'icl_lso_display_lang',
|
||||
'icl_lang_sel_footer',
|
||||
'icl_post_availability',
|
||||
'icl_post_availability_position',
|
||||
'icl_post_availability_text',
|
||||
);
|
||||
|
||||
foreach ( $old_keys as $old_key ) {
|
||||
if ( array_key_exists( $old_key, $this->old_settings ) ) {
|
||||
$result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.7.0 Convert menu LS handled now by ID instead of slugs previously
|
||||
*
|
||||
* @param array $settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convert_menu_ids( $settings ) {
|
||||
if ( $settings['menus'] ) {
|
||||
|
||||
foreach ( $settings['menus'] as $slug => $menu_slot ) {
|
||||
|
||||
/** @var WPML_LS_Menu_Slot $menu_slot */
|
||||
if ( is_string( $slug ) ) {
|
||||
|
||||
$current_lang = $this->sitepress->get_current_language();
|
||||
$this->sitepress->switch_lang( $this->sitepress->get_default_language() );
|
||||
$menu = wp_get_nav_menu_object( $slug );
|
||||
$new_id = $menu->term_id;
|
||||
$slot_args = $menu_slot->get_model();
|
||||
$slot_args['slot_slug'] = $new_id;
|
||||
$new_slot = $this->slot_factory->get_slot( $slot_args );
|
||||
unset( $settings['menus'][ $slug ] );
|
||||
$settings['menus'][ $new_id ] = $new_slot;
|
||||
$this->sitepress->switch_lang( $current_lang );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$settings['converted_menu_ids'] = 1;
|
||||
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Model_Build extends WPML_SP_User {
|
||||
|
||||
const LINK_CSS_CLASS = 'wpml-ls-link';
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var WPML_Mobile_Detect $mobile_detect */
|
||||
private $mobile_detect;
|
||||
|
||||
/* @var bool $is_touch_screen */
|
||||
private $is_touch_screen = false;
|
||||
|
||||
/* @var string $css_prefix */
|
||||
private $css_prefix;
|
||||
|
||||
private $allowed_vars = [
|
||||
'languages' => 'array',
|
||||
'current_language_code' => 'string',
|
||||
'css_classes' => 'string',
|
||||
'css_classes_link' => 'string',
|
||||
'backward_compatibility' => 'array',
|
||||
];
|
||||
|
||||
private $allowed_language_vars = [
|
||||
'code' => 'string',
|
||||
'url' => 'string',
|
||||
'flag_url' => 'string',
|
||||
'flag_title' => 'string',
|
||||
'flag_alt' => 'string',
|
||||
'native_name' => 'string',
|
||||
'display_name' => 'string',
|
||||
'is_current' => 'bool',
|
||||
'css_classes' => 'string',
|
||||
'db_id' => 'string',
|
||||
'menu_item_parent' => 'mixed',
|
||||
'is_parent' => 'bool',
|
||||
'backward_compatibility' => 'array',
|
||||
'flag_width' => 'int',
|
||||
'flag_height' => 'int',
|
||||
];
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Render_Model constructor.
|
||||
*
|
||||
* @param WPML_LS_Settings $settings
|
||||
* @param SitePress $sitepress
|
||||
* @param string $css_prefix
|
||||
*/
|
||||
public function __construct( $settings, $sitepress, $css_prefix ) {
|
||||
$this->settings = $settings;
|
||||
$this->css_prefix = $css_prefix;
|
||||
parent::__construct( $sitepress );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
* @param array $template_data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get( $slot, $template_data = [] ) {
|
||||
$vars = [];
|
||||
|
||||
$vars['current_language_code'] = $this->sitepress->get_current_language();
|
||||
$vars['languages'] = $this->get_language_items( $slot, $template_data );
|
||||
$vars['css_classes'] = $this->get_slot_css_classes( $slot );
|
||||
$vars['css_classes_link'] = self::LINK_CSS_CLASS;
|
||||
|
||||
$vars = $this->add_backward_compatibility_to_wrapper( $vars, $slot );
|
||||
|
||||
return $this->sanitize_vars( $vars, $this->allowed_vars );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_slot_css_classes( $slot ) {
|
||||
$classes = [ $this->get_slot_css_main_class( $slot->group(), $slot->slug() ) ];
|
||||
|
||||
$classes[] = trim( $this->css_prefix, '-' );
|
||||
|
||||
if ( $this->sitepress->is_rtl( $this->sitepress->get_current_language() ) ) {
|
||||
$classes[] = $this->css_prefix . 'rtl';
|
||||
}
|
||||
|
||||
$classes = $this->add_user_agent_touch_device_classes( $classes );
|
||||
|
||||
/**
|
||||
* Filter the css classes for the language switcher wrapper
|
||||
* The wrapper is not available for menus
|
||||
*
|
||||
* @param array $classes
|
||||
*/
|
||||
$classes = apply_filters( 'wpml_ls_model_css_classes', $classes );
|
||||
|
||||
return implode( ' ', $classes );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $group
|
||||
* @param string $slug
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_slot_css_main_class( $group, $slug ) {
|
||||
return $this->css_prefix . $group . '-' . $slug;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_css_prefix() {
|
||||
return $this->css_prefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
* @param array $template_data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_language_items( $slot, $template_data ) {
|
||||
$ret = [];
|
||||
|
||||
|
||||
$get_ls_args = [
|
||||
'skip_missing' => ! $this->settings->get_setting( 'link_empty' ),
|
||||
];
|
||||
|
||||
if ( $slot->is_post_translations() ) {
|
||||
$get_ls_args['skip_missing'] = true;
|
||||
} elseif ( ( WPML_Root_Page::uses_html_root() || WPML_Root_Page::get_root_id() ) && WPML_Root_Page::is_current_request_root() ) {
|
||||
$get_ls_args['skip_missing'] = false;
|
||||
}
|
||||
|
||||
$flag_width = $slot->get( 'include_flag_width' );
|
||||
$flag_height = $slot->get( 'include_flag_height' );
|
||||
|
||||
$languages = $this->sitepress->get_ls_languages( $get_ls_args );
|
||||
$languages = is_array( $languages ) ? $languages : [];
|
||||
|
||||
$languages = $this->order_languages( $languages, $this->sitepress->get_current_language() );
|
||||
|
||||
if ( $languages ) {
|
||||
|
||||
foreach ( $languages as $code => $data ) {
|
||||
|
||||
$is_current_language = $code === $this->sitepress->get_current_language();
|
||||
|
||||
if ( ! $slot->get( 'display_link_for_current_lang' ) && $is_current_language ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ret[ $code ] = [
|
||||
'code' => $code,
|
||||
'url' => $data['url'],
|
||||
];
|
||||
|
||||
if ( $flag_width ) {
|
||||
$ret[ $code ]['flag_width'] = $flag_width;
|
||||
}
|
||||
if ( $flag_height ) {
|
||||
$ret[ $code ]['flag_height'] = $flag_height;
|
||||
}
|
||||
|
||||
/* @deprecated Use 'wpml_ls_language_url' instead */
|
||||
$ret[ $code ]['url'] = apply_filters( 'WPML_filter_link', $ret[ $code ]['url'], $data );
|
||||
|
||||
/**
|
||||
* This filter allows to change the URL for each languages links in the switcher
|
||||
*
|
||||
* @param string $ret [ $code ]['url'] The language URL to be filtered
|
||||
* @param array $data The language information
|
||||
*/
|
||||
$ret[ $code ]['url'] = apply_filters( 'wpml_ls_language_url', $ret[ $code ]['url'], $data );
|
||||
|
||||
$ret[ $code ]['url'] = $this->sitepress->get_wp_api()->is_admin() ? '#' : $ret[ $code ]['url'];
|
||||
|
||||
$css_classes = $this->get_language_css_classes( $slot, $code );
|
||||
|
||||
$display_native = $slot->get( 'display_names_in_native_lang' );
|
||||
$display_name = $slot->get( 'display_names_in_current_lang' );
|
||||
|
||||
if ( $slot->get( 'display_flags' ) ) {
|
||||
$ret[ $code ]['flag_url'] = $this->filter_flag_url( $data['country_flag_url'], $template_data );
|
||||
$ret[ $code ]['flag_title'] = $data['native_name'];
|
||||
$ret[ $code ]['flag_alt'] = ( $display_name || $display_native ) ? '' : $data['translated_name'];
|
||||
}
|
||||
|
||||
if ( $display_native ) {
|
||||
$ret[ $code ]['native_name'] = $data['native_name'];
|
||||
}
|
||||
|
||||
if ( $display_name ) {
|
||||
$ret[ $code ]['display_name'] = $data['translated_name'];
|
||||
}
|
||||
|
||||
if ( $is_current_language ) {
|
||||
$ret[ $code ]['is_current'] = true;
|
||||
array_push( $css_classes, $this->css_prefix . 'current-language' );
|
||||
}
|
||||
|
||||
if ( $slot->is_menu() ) {
|
||||
$ret[ $code ]['db_id'] = $this->get_menu_item_id( $code, $slot );
|
||||
$ret[ $code ]['menu_item_parent'] = $slot->get( 'is_hierarchical' ) && ! $is_current_language && $slot->get( 'display_link_for_current_lang' )
|
||||
? $this->get_menu_item_id( $this->sitepress->get_current_language(), $slot ) : 0;
|
||||
$ret[ $code ]['is_parent'] = $slot->get( 'is_hierarchical' ) && $is_current_language;
|
||||
|
||||
array_unshift( $css_classes, 'menu-item' );
|
||||
array_push( $css_classes, $this->css_prefix . 'menu-item' );
|
||||
}
|
||||
|
||||
$ret[ $code ]['css_classes'] = $css_classes;
|
||||
}
|
||||
|
||||
$i = 1;
|
||||
foreach ( $ret as &$lang ) {
|
||||
if ( $i === 1 ) {
|
||||
array_push( $lang['css_classes'], $this->css_prefix . 'first-item' );
|
||||
}
|
||||
|
||||
if ( $i === count( $ret ) ) {
|
||||
array_push( $lang['css_classes'], $this->css_prefix . 'last-item' );
|
||||
}
|
||||
|
||||
$lang = $this->add_backward_compatibility_to_languages( $lang, $slot );
|
||||
|
||||
/**
|
||||
* Filter the css classes for each language item
|
||||
*
|
||||
* @param array $lang ['css_classes']
|
||||
*/
|
||||
$lang['css_classes'] = apply_filters( 'wpml_ls_model_language_css_classes', $lang['css_classes'] );
|
||||
|
||||
$lang['css_classes'] = implode( ' ', $lang['css_classes'] );
|
||||
|
||||
$lang = $this->sanitize_vars( $lang, $this->allowed_language_vars );
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $languages
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function order_languages( $languages, $current_language ) {
|
||||
if ( isset( $languages[$current_language] ) ) {
|
||||
$current_language_value = $languages[$current_language];
|
||||
unset($languages[$current_language]);
|
||||
return array_merge([$current_language => $current_language_value], $languages);
|
||||
} else {
|
||||
return $languages;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param array $template_data
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function filter_flag_url( $url, $template_data = [] ) {
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
$has_custom_flag = strpos( $url, $wp_upload_dir['baseurl'] . '/flags/' ) === 0 ? true : false;
|
||||
|
||||
if ( ! $has_custom_flag && ! empty( $template_data['flags_base_uri'] ) ) {
|
||||
$url = trailingslashit( $template_data['flags_base_uri'] ) . basename( $url );
|
||||
|
||||
if ( isset( $template_data['flag_extension'] ) ) {
|
||||
$old_ext = pathinfo( $url, PATHINFO_EXTENSION );
|
||||
$url = preg_replace( '#' . $old_ext . '$#', $template_data['flag_extension'], $url, 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
* @param string $code
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_language_css_classes( $slot, $code ) {
|
||||
return [
|
||||
$this->css_prefix . 'slot-' . $slot->slug(),
|
||||
$this->css_prefix . 'item',
|
||||
$this->css_prefix . 'item-' . $code,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function add_user_agent_touch_device_classes( $classes ) {
|
||||
|
||||
if ( is_null( $this->mobile_detect ) ) {
|
||||
require_once WPML_PLUGIN_PATH . '/lib/mobile-detect.php';
|
||||
$this->mobile_detect = new WPML_Mobile_Detect();
|
||||
$this->is_touch_screen = $this->mobile_detect->isMobile() || $this->mobile_detect->isTablet();
|
||||
}
|
||||
|
||||
if ( $this->is_touch_screen ) {
|
||||
$classes[] = $this->css_prefix . 'touch-device';
|
||||
}
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function needs_backward_compatibility() {
|
||||
return (bool) $this->settings->get_setting( 'migrated' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_menu_item_id( $code, $slot ) {
|
||||
return $this->css_prefix . $slot->slug() . '-' . $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $vars
|
||||
* @param array $allowed_vars
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function sanitize_vars( $vars, $allowed_vars ) {
|
||||
$sanitized = [];
|
||||
|
||||
foreach ( $allowed_vars as $allowed_var => $type ) {
|
||||
if ( isset( $vars[ $allowed_var ] ) ) {
|
||||
switch ( $type ) {
|
||||
case 'array':
|
||||
$sanitized[ $allowed_var ] = (array) $vars[ $allowed_var ];
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
$sanitized[ $allowed_var ] = (string) $vars[ $allowed_var ];
|
||||
break;
|
||||
|
||||
case 'int':
|
||||
$sanitized[ $allowed_var ] = (int) $vars[ $allowed_var ];
|
||||
break;
|
||||
|
||||
case 'bool':
|
||||
$sanitized[ $allowed_var ] = (bool) $vars[ $allowed_var ];
|
||||
break;
|
||||
|
||||
case 'mixed':
|
||||
$sanitized[ $allowed_var ] = $vars[ $allowed_var ];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $sanitized;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $lang
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function add_backward_compatibility_to_languages( $lang, $slot ) {
|
||||
|
||||
if ( $this->needs_backward_compatibility() ) {
|
||||
|
||||
$is_current_language = isset( $lang['is_current'] ) && $lang['is_current'];
|
||||
|
||||
if ( $slot->is_menu() ) {
|
||||
|
||||
if ( $is_current_language ) {
|
||||
array_unshift( $lang['css_classes'], 'menu-item-language-current' );
|
||||
}
|
||||
|
||||
array_unshift( $lang['css_classes'], 'menu-item-language' );
|
||||
}
|
||||
|
||||
if ( $slot->is_sidebar() || $slot->is_shortcode_actions() ) {
|
||||
|
||||
if ( $this->is_legacy_template( $slot->template(), 'list-vertical' )
|
||||
|| $this->is_legacy_template( $slot->template(), 'list-horizontal' )
|
||||
) {
|
||||
array_unshift( $lang['css_classes'], 'icl-' . $lang['code'] );
|
||||
$lang['backward_compatibility']['css_classes_a'] = $is_current_language ?
|
||||
'lang_sel_sel' : 'lang_sel_other';
|
||||
}
|
||||
|
||||
if ( $this->is_legacy_template( $slot->template(), 'dropdown' )
|
||||
|| $this->is_legacy_template( $slot->template(), 'dropdown-click' )
|
||||
) {
|
||||
|
||||
if ( $is_current_language ) {
|
||||
$lang['backward_compatibility']['css_classes_a'] = 'lang_sel_sel icl-' . $lang['code'];
|
||||
} else {
|
||||
array_unshift( $lang['css_classes'], 'icl-' . $lang['code'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $vars
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function add_backward_compatibility_to_wrapper( $vars, $slot ) {
|
||||
|
||||
if ( $this->needs_backward_compatibility() ) {
|
||||
|
||||
if ( $slot->is_sidebar() || $slot->is_shortcode_actions() ) {
|
||||
|
||||
if ( $this->is_legacy_template( $slot->template(), 'list-vertical' )
|
||||
|| $this->is_legacy_template( $slot->template(), 'list-horizontal' )
|
||||
) {
|
||||
$vars['backward_compatibility']['css_id'] = 'lang_sel_list';
|
||||
|
||||
if ( $this->is_legacy_template( $slot->template(), 'list-horizontal' ) ) {
|
||||
$vars['css_classes'] = 'lang_sel_list_horizontal ' . $vars['css_classes'];
|
||||
} else {
|
||||
$vars['css_classes'] = 'lang_sel_list_vertical ' . $vars['css_classes'];
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->is_legacy_template( $slot->template(), 'dropdown' ) ) {
|
||||
$vars['backward_compatibility']['css_id'] = 'lang_sel';
|
||||
}
|
||||
|
||||
if ( $this->is_legacy_template( $slot->template(), 'dropdown-click' ) ) {
|
||||
$vars['backward_compatibility']['css_id'] = 'lang_sel_click';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $slot->is_post_translations() ) {
|
||||
$vars['css_classes'] = 'icl_post_in_other_langs ' . $vars['css_classes'];
|
||||
}
|
||||
|
||||
if ( $slot->is_footer() ) {
|
||||
$vars['backward_compatibility']['css_id'] = 'lang_sel_footer';
|
||||
}
|
||||
|
||||
$vars['backward_compatibility']['css_classes_flag'] = 'iclflag';
|
||||
$vars['backward_compatibility']['css_classes_native'] = 'icl_lang_sel_native';
|
||||
$vars['backward_compatibility']['css_classes_display'] = 'icl_lang_sel_translated';
|
||||
$vars['backward_compatibility']['css_classes_bracket'] = 'icl_lang_sel_bracket';
|
||||
}
|
||||
|
||||
return $vars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template_slug
|
||||
* @param string|null $type
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_legacy_template( $template_slug, $type = null ) {
|
||||
$templates = $this->settings->get_core_templates();
|
||||
$ret = in_array( $template_slug, $templates, true );
|
||||
|
||||
if ( $ret && array_key_exists( $type, $templates ) ) {
|
||||
$ret = $templates[ $type ] === $template_slug;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Render extends WPML_SP_User {
|
||||
|
||||
const THE_CONTENT_FILTER_PRIORITY = 100;
|
||||
|
||||
/* @var WPML_LS_Template $current_template */
|
||||
private $current_template;
|
||||
|
||||
/* @var WPML_LS_Templates $templates */
|
||||
private $templates;
|
||||
|
||||
/* @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var WPML_LS_Model_Build $model_build */
|
||||
private $model_build;
|
||||
|
||||
/* @var WPML_LS_Inline_Styles &$inline_styles */
|
||||
private $inline_styles;
|
||||
|
||||
/* @var WPML_LS_Assets $assets */
|
||||
private $assets;
|
||||
|
||||
/** @var bool */
|
||||
private $wpml_ls_exclude_in_menu;
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Menu constructor.
|
||||
*
|
||||
* @param WPML_LS_Templates $templates
|
||||
* @param WPML_LS_Settings $settings
|
||||
* @param WPML_LS_Model_Build $model_build
|
||||
* @param WPML_LS_Inline_Styles $inline_styles
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct( $templates, $settings, $model_build, $inline_styles, $sitepress ) {
|
||||
$this->templates = $templates;
|
||||
$this->settings = $settings;
|
||||
$this->model_build = $model_build;
|
||||
$this->inline_styles = $inline_styles;
|
||||
$this->assets = new WPML_LS_Assets( $this->templates, $this->settings );
|
||||
parent::__construct( $sitepress );
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
if ( $this->sitepress->get_setting( 'setup_complete' ) ) {
|
||||
|
||||
add_filter( 'wp_get_nav_menu_items', array( $this, 'wp_get_nav_menu_items_filter' ), 10, 2 );
|
||||
add_filter( 'wp_setup_nav_menu_item', array( $this, 'maybe_repair_menu_item' ), PHP_INT_MAX );
|
||||
|
||||
add_filter( 'the_content', array( $this, 'the_content_filter' ), self::THE_CONTENT_FILTER_PRIORITY );
|
||||
if ( ! $this->is_widgets_page() ) {
|
||||
add_action( 'wp_footer', array( $this, 'wp_footer_action' ), 19 );
|
||||
}
|
||||
|
||||
$this->assets->init_hooks();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $slot ) {
|
||||
$html = '';
|
||||
$model = array();
|
||||
|
||||
if ( ! $this->is_hidden( $slot ) ) {
|
||||
|
||||
$this->assets->maybe_late_enqueue_template( $slot->template() );
|
||||
$this->current_template = clone $this->templates->get_template( $slot->template() );
|
||||
|
||||
if ( $slot->template_string() ) {
|
||||
$this->current_template->set_template_string( $slot->template_string() );
|
||||
}
|
||||
|
||||
$model = $this->model_build->get( $slot, $this->current_template->get_template_data() );
|
||||
|
||||
if ( $model['languages'] ) {
|
||||
$this->current_template->set_model( $model );
|
||||
$html = $this->current_template->get_html();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->filter_html( $html, $model, $slot );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $html
|
||||
* @param array $model
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function filter_html( $html, $model, $slot ) {
|
||||
/**
|
||||
* @param string $html The HTML for the language switcher
|
||||
* @param array $model The model passed to the template
|
||||
* @param WPML_LS_Slot $slot The language switcher settings for this slot
|
||||
*/
|
||||
return apply_filters( 'wpml_ls_html', $html, $model, $slot );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_preview( $slot ) {
|
||||
$ret = [];
|
||||
|
||||
if ( $slot->is_menu() ) {
|
||||
$ret['html'] = $this->render_menu_preview( $slot );
|
||||
} elseif ( $slot->is_post_translations() ) {
|
||||
$ret['html'] = $this->post_translations_label( $slot );
|
||||
} else {
|
||||
$ret['html'] = $this->render( $slot );
|
||||
}
|
||||
|
||||
$ret['css'] = $this->current_template->get_styles( true );
|
||||
$ret['js'] = $this->current_template->get_scripts( true );
|
||||
$ret['styles'] = $this->inline_styles->get_slots_inline_styles( [ $slot ] );
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param WP_Term $menu
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function wp_get_nav_menu_items_filter( $items, $menu ) {
|
||||
if ( $this->should_not_alter_menu() ) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
if ( $this->is_for_menu_panel_in_customizer() ) {
|
||||
return $items;
|
||||
}
|
||||
|
||||
$slot = $this->settings->get_menu_settings_from_id( $menu->term_id );
|
||||
|
||||
if ( $slot->is_enabled() && ! $this->is_hidden( $slot ) ) {
|
||||
$is_before = 'before' === $slot->get( 'position_in_menu' );
|
||||
$lang_items = $this->get_menu_items( $slot );
|
||||
|
||||
if ( $items && $lang_items ) {
|
||||
$items = $this->merge_menu_items( $items, $lang_items, $is_before );
|
||||
} elseif ( ! $items && $lang_items ) {
|
||||
$items = $lang_items;
|
||||
}
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
private function is_for_menu_panel_in_customizer() {
|
||||
return is_customize_preview() && ! did_action( 'template_redirect' );
|
||||
}
|
||||
|
||||
private function should_not_alter_menu() {
|
||||
if ( null === $this->wpml_ls_exclude_in_menu ) {
|
||||
$this->wpml_ls_exclude_in_menu = apply_filters( 'wpml_ls_exclude_in_menu', true );
|
||||
}
|
||||
|
||||
return is_admin() && $this->wpml_ls_exclude_in_menu;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WP_Post[] $items
|
||||
* @param WPML_LS_Menu_Item[] $lang_items
|
||||
* @param bool $is_before
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function merge_menu_items( $items, $lang_items, $is_before ) {
|
||||
if ( $is_before ) {
|
||||
$items_to_prepend = $lang_items;
|
||||
$items_to_append = $items;
|
||||
} else {
|
||||
$items_to_prepend = $items;
|
||||
$items_to_append = $lang_items;
|
||||
}
|
||||
|
||||
$menu_orders = wp_list_pluck( $items_to_prepend, 'menu_order' );
|
||||
$offset = max( $menu_orders );
|
||||
|
||||
foreach ( $items_to_append as $item ) {
|
||||
$item->menu_order = $item->menu_order + $offset;
|
||||
}
|
||||
|
||||
return array_merge( $items_to_prepend, $items_to_append );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_menu_items( $slot ) {
|
||||
$lang_items = array();
|
||||
$model = $this->model_build->get( $slot );
|
||||
|
||||
if ( isset( $model['languages'] ) ) {
|
||||
|
||||
$this->current_template = $this->templates->get_template( $slot->template() );
|
||||
$menu_order = 1;
|
||||
|
||||
foreach ( $model['languages'] as $language_model ) {
|
||||
$this->current_template->set_model( $language_model );
|
||||
$item_content = $this->filter_html( $this->current_template->get_html(), $language_model, $slot );
|
||||
$ls_menu_item = new WPML_LS_Menu_Item( $language_model, $item_content );
|
||||
$ls_menu_item->menu_order = $menu_order;
|
||||
$menu_order++;
|
||||
|
||||
$lang_items[] = $ls_menu_item;
|
||||
}
|
||||
}
|
||||
|
||||
return $lang_items;
|
||||
}
|
||||
|
||||
/**
|
||||
* @link https://onthegosystems.myjetbrains.com/youtrack/issue/wpmlcore-4706#comment=102-231339
|
||||
*
|
||||
* @param WP_Post|WPML_LS_Menu_Item|object $item
|
||||
*
|
||||
* @return object $item
|
||||
*/
|
||||
public function maybe_repair_menu_item( $item ) {
|
||||
if ( $this->should_not_alter_menu() ) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
if ( ! $item instanceof WPML_LS_Menu_Item ) {
|
||||
return $item;
|
||||
}
|
||||
|
||||
if ( ! $item->db_id ) {
|
||||
$item->db_id = $item->ID;
|
||||
}
|
||||
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function render_menu_preview( $slot ) {
|
||||
$items = $this->get_menu_items( $slot );
|
||||
$class = $slot->get( 'is_hierarchical' ) ? 'wpml-ls-menu-hierarchical-preview' : 'wpml-ls-menu-flat-preview';
|
||||
$defaults = array(
|
||||
'before' => '',
|
||||
'after' => '',
|
||||
'link_before' => '',
|
||||
'link_after' => '',
|
||||
'theme_location' => '',
|
||||
);
|
||||
$defaults = (object) $defaults;
|
||||
$output = walk_nav_menu_tree( $items, 2, $defaults );
|
||||
|
||||
$dummy_item = esc_html__( 'menu items', 'sitepress' );
|
||||
|
||||
if ( $slot->get( 'position_in_menu' ) === 'before' ) {
|
||||
$output .= '<li class="dummy-menu-item"><a href="#">' . $dummy_item . '...</a></li>';
|
||||
} else {
|
||||
$output = '<li class="dummy-menu-item"><a href="#">...' . $dummy_item . '</a></li>' . $output;
|
||||
}
|
||||
|
||||
return '<div><ul class="wpml-ls-menu-preview ' . $class . '">' . $output . '</ul></div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return bool true if the switcher is to be hidden
|
||||
*/
|
||||
private function is_hidden( $slot ) {
|
||||
if ( ! function_exists( 'wpml_home_url_ls_hide_check' ) ) {
|
||||
require WPML_PLUGIN_PATH . '/inc/post-translation/wpml-root-page-actions.class.php';
|
||||
}
|
||||
|
||||
return wpml_home_url_ls_hide_check() && ! $slot->is_shortcode_actions();
|
||||
}
|
||||
|
||||
public function is_widgets_page() {
|
||||
global $pagenow;
|
||||
|
||||
return is_admin() && 'widgets.php' === $pagenow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function the_content_filter( $content ) {
|
||||
$post_translations = '';
|
||||
$slot = $this->settings->get_slot( 'statics', 'post_translations' );
|
||||
|
||||
if ( $slot->is_enabled() && $this->sitepress->get_wp_api()->is_singular() ) {
|
||||
$post_translations = $this->post_translations_label( $slot );
|
||||
}
|
||||
|
||||
if ( $post_translations ) {
|
||||
if ( $slot->get( 'display_before_content' ) ) {
|
||||
$content = $post_translations . $content;
|
||||
}
|
||||
|
||||
if ( $slot->get( 'display_after_content' ) ) {
|
||||
$content = $content . $post_translations;
|
||||
}
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return mixed|string|void
|
||||
*/
|
||||
public function post_translations_label( $slot ) {
|
||||
$css_classes = $this->model_build->get_slot_css_classes( $slot );
|
||||
$html = $this->render( $slot );
|
||||
if ( $html ) {
|
||||
$html = sprintf( $slot->get( 'availability_text' ), $html );
|
||||
$html = '<p class="' . $css_classes . '">' . $html . '</p>';
|
||||
|
||||
/* @deprecated use 'wpml_ls_post_alternative_languages' instead */
|
||||
$html = apply_filters( 'icl_post_alternative_languages', $html );
|
||||
|
||||
/**
|
||||
* @param string $html
|
||||
*/
|
||||
$html = apply_filters( 'wpml_ls_post_alternative_languages', $html );
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
public function wp_footer_action() {
|
||||
$slot = $this->settings->get_slot( 'statics', 'footer' );
|
||||
if ( $slot->is_enabled() ) {
|
||||
echo $this->render( $slot );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Settings_Color_Presets {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_defaults() {
|
||||
$void = array(
|
||||
'font_current_normal' => '',
|
||||
'font_current_hover' => '',
|
||||
'background_current_normal' => '',
|
||||
'background_current_hover' => '',
|
||||
'font_other_normal' => '',
|
||||
'font_other_hover' => '',
|
||||
'background_other_normal' => '',
|
||||
'background_other_hover' => '',
|
||||
'border_normal' => '',
|
||||
'background_normal' => '',
|
||||
);
|
||||
|
||||
$gray = array(
|
||||
'font_current_normal' => '#222222',
|
||||
'font_current_hover' => '#000000',
|
||||
'background_current_normal' => '#eeeeee',
|
||||
'background_current_hover' => '#eeeeee',
|
||||
'font_other_normal' => '#222222',
|
||||
'font_other_hover' => '#000000',
|
||||
'background_other_normal' => '#e5e5e5',
|
||||
'background_other_hover' => '#eeeeee',
|
||||
'border_normal' => '#cdcdcd',
|
||||
'background_normal' => '#e5e5e5',
|
||||
);
|
||||
|
||||
$white = array(
|
||||
'font_current_normal' => '#444444',
|
||||
'font_current_hover' => '#000000',
|
||||
'background_current_normal' => '#ffffff',
|
||||
'background_current_hover' => '#eeeeee',
|
||||
'font_other_normal' => '#444444',
|
||||
'font_other_hover' => '#000000',
|
||||
'background_other_normal' => '#ffffff',
|
||||
'background_other_hover' => '#eeeeee',
|
||||
'border_normal' => '#cdcdcd',
|
||||
'background_normal' => '#ffffff',
|
||||
);
|
||||
|
||||
$blue = array(
|
||||
'font_current_normal' => '#ffffff',
|
||||
'font_current_hover' => '#000000',
|
||||
'background_current_normal' => '#95bedd',
|
||||
'background_current_hover' => '#95bedd',
|
||||
'font_other_normal' => '#000000',
|
||||
'font_other_hover' => '#ffffff',
|
||||
'background_other_normal' => '#cbddeb',
|
||||
'background_other_hover' => '#95bedd',
|
||||
'border_normal' => '#0099cc',
|
||||
'background_normal' => '#cbddeb',
|
||||
);
|
||||
|
||||
return array(
|
||||
'void' => array(
|
||||
'label' => esc_html__( 'Clear all colors', 'sitepress' ),
|
||||
'values' => $void,
|
||||
),
|
||||
'gray' => array(
|
||||
'label' => esc_html__( 'Gray', 'sitepress' ),
|
||||
'values' => $gray,
|
||||
),
|
||||
'white' => array(
|
||||
'label' => esc_html__( 'White', 'sitepress' ),
|
||||
'values' => $white,
|
||||
),
|
||||
'blue' => array(
|
||||
'label' => esc_html__( 'Blue', 'sitepress' ),
|
||||
'values' => $blue,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Settings_Sanitize {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_global_settings_keys() {
|
||||
return array(
|
||||
'migrated' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 1,
|
||||
),
|
||||
'converted_menu_ids' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'languages_order' => array( 'type' => 'array' ),
|
||||
'link_empty' => array( 'type' => 'int' ),
|
||||
'additional_css' => array( 'type' => 'string' ),
|
||||
'copy_parameters' => array( 'type' => 'string' ),
|
||||
// Slot groups
|
||||
'menus' => array(
|
||||
'type' => 'array',
|
||||
'force_missing_to' => array(),
|
||||
),
|
||||
'sidebars' => array(
|
||||
'type' => 'array',
|
||||
'force_missing_to' => array(),
|
||||
),
|
||||
'statics' => array(
|
||||
'type' => 'array',
|
||||
'force_missing_to' => array(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $s
|
||||
* @return array
|
||||
*/
|
||||
public function sanitize_all_settings( $s ) {
|
||||
$s = $this->sanitize_settings( $s, $this->get_global_settings_keys() );
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings_slice
|
||||
* @param array $allowed_keys
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function sanitize_settings( $settings_slice, $allowed_keys ) {
|
||||
$ret = array();
|
||||
|
||||
foreach ( $allowed_keys as $key => $expected ) {
|
||||
if ( array_key_exists( $key, $settings_slice ) ) {
|
||||
switch ( $expected['type'] ) {
|
||||
case 'string':
|
||||
$ret[ $key ] = (string) $settings_slice[ $key ];
|
||||
break;
|
||||
case 'int':
|
||||
$ret[ $key ] = (int) $settings_slice[ $key ];
|
||||
break;
|
||||
case 'array':
|
||||
$ret[ $key ] = (array) $settings_slice[ $key ];
|
||||
break;
|
||||
}
|
||||
} elseif ( array_key_exists( 'force_missing_to', $expected ) ) {
|
||||
$ret[ $key ] = $expected['force_missing_to'];
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Settings_Strings {
|
||||
|
||||
private $strings_meta = array(
|
||||
'availability_text' => array(
|
||||
'domain' => 'WPML',
|
||||
'name' => 'Text for alternative languages for posts',
|
||||
),
|
||||
'widget_title' => array(
|
||||
'domain' => 'Widgets',
|
||||
'name' => 'widget title',
|
||||
),
|
||||
);
|
||||
|
||||
/* @var WPML_LS_Slot_Factory $slot_factory */
|
||||
private $slot_factory;
|
||||
|
||||
public function __construct( $slot_factory ) {
|
||||
$this->slot_factory = $slot_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $new_settings
|
||||
* @param array $old_settings
|
||||
*/
|
||||
public function register_all( $new_settings, $old_settings ) {
|
||||
$void_slot = array( 'show' => false );
|
||||
|
||||
foreach ( $new_settings['sidebars'] as $slug => $slot_settings ) {
|
||||
$old_slot_settings = isset( $old_settings['sidebars'][ $slug ] )
|
||||
? $old_settings['sidebars'][ $slug ] : $this->slot_factory->get_slot( $void_slot );
|
||||
$this->register_slot_strings( $slot_settings, $old_slot_settings );
|
||||
}
|
||||
|
||||
$post_translations_settings = isset( $new_settings['statics']['post_translations'] )
|
||||
? $new_settings['statics']['post_translations'] : null;
|
||||
|
||||
if ( $post_translations_settings ) {
|
||||
|
||||
$old_slot_settings = isset( $old_settings['statics']['post_translations'] )
|
||||
? $old_settings['statics']['post_translations'] : $this->slot_factory->get_slot( $void_slot );
|
||||
|
||||
$this->register_slot_strings( $post_translations_settings, $old_slot_settings );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function translate_all( $settings ) {
|
||||
|
||||
if ( isset( $settings['sidebars'] ) ) {
|
||||
foreach ( $settings['sidebars'] as &$slot_settings ) {
|
||||
$slot_settings = $this->translate_slot_strings( $slot_settings );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $settings['statics']['post_translations'] ) ) {
|
||||
$settings['statics']['post_translations'] = $this->translate_slot_strings( $settings['statics']['post_translations'] );
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
* @param WPML_LS_Slot $old_slot
|
||||
*/
|
||||
private function register_slot_strings( WPML_LS_Slot $slot, WPML_LS_Slot $old_slot ) {
|
||||
foreach ( $this->strings_meta as $key => $string_meta ) {
|
||||
|
||||
if ( $slot->get( $key ) ) {
|
||||
$old_string = $old_slot->get( $key );
|
||||
|
||||
if ( $key === 'widget_title' && $old_string && function_exists( 'icl_st_update_string_actions' ) ) {
|
||||
icl_st_update_string_actions( 'Widgets', $this->get_string_name( $key, $old_string ), $old_string, $slot->get( $key ) );
|
||||
} else {
|
||||
do_action(
|
||||
'wpml_register_single_string',
|
||||
$this->strings_meta[ $key ]['domain'],
|
||||
$this->get_string_name( $key, $slot->get( $key ) ),
|
||||
$slot->get( $key )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
private function translate_slot_strings( $slot ) {
|
||||
foreach ( $this->strings_meta as $key => $string_meta ) {
|
||||
|
||||
if ( $slot->get( $key ) ) {
|
||||
|
||||
if ( $key === 'title' && function_exists( 'icl_sw_filters_widget_title' ) ) {
|
||||
$translation = icl_sw_filters_widget_title( $slot->get( $key ) );
|
||||
$slot->set( $key, $translation );
|
||||
} else {
|
||||
$string_name = $this->get_string_name( $key, $slot->get( $key ) );
|
||||
$domain = $this->strings_meta[ $key ]['domain'];
|
||||
$translation = apply_filters( 'wpml_translate_single_string', $slot->get( $key ), $domain, $string_name );
|
||||
$slot->set( $key, $translation );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $string_value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_string_name( $key, $string_value ) {
|
||||
$name = $this->strings_meta[ $key ]['name'];
|
||||
|
||||
if ( $key === 'widget_title' ) {
|
||||
$name = $name . ' - ' . md5( $string_value );
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,783 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
use WPML\FP\Obj;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Lst;
|
||||
use WPML\FP\Maybe;
|
||||
use function WPML\FP\partial;
|
||||
use function WPML\FP\invoke;
|
||||
|
||||
class WPML_LS_Settings {
|
||||
|
||||
const SETTINGS_SLUG = 'wpml_language_switcher';
|
||||
|
||||
const DEFAULT_FLAG_WIDTH = 18;
|
||||
const DEFAULT_FLAG_HEIGHT = 12;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
protected $sitepress;
|
||||
|
||||
/* @var array $settings */
|
||||
private $settings;
|
||||
|
||||
/* @var WPML_LS_Templates $templates */
|
||||
private $templates;
|
||||
|
||||
/* @var WPML_LS_Slot_Factory $slot_factory */
|
||||
private $slot_factory;
|
||||
|
||||
/* @var WPML_LS_Migration $migration */
|
||||
private $migration;
|
||||
|
||||
/* @var WPML_LS_Settings_Sanitize $sanitizer */
|
||||
private $sanitizer;
|
||||
|
||||
/* @var WPML_LS_Settings_Strings $strings */
|
||||
private $strings;
|
||||
|
||||
/* @var WPML_LS_Settings_Color_Presets $color_presets */
|
||||
private $color_presets;
|
||||
|
||||
/**
|
||||
* WPML_LS_Settings constructor.
|
||||
*
|
||||
* @param WPML_LS_Templates $templates
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_LS_Slot_Factory $slot_factory
|
||||
* @param WPML_LS_Migration $migration
|
||||
*/
|
||||
public function __construct( $templates, $sitepress, $slot_factory, $migration = null ) {
|
||||
$this->templates = $templates;
|
||||
$this->sitepress = &$sitepress;
|
||||
$this->slot_factory = $slot_factory;
|
||||
$this->migration = $migration;
|
||||
$this->sanitizer = new WPML_LS_Settings_Sanitize();
|
||||
$this->strings = new WPML_LS_Settings_Strings( $this->slot_factory );
|
||||
$this->color_presets = new WPML_LS_Settings_Color_Presets();
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_filter( 'widget_update_callback', array( $this, 'widget_update_callback_filter' ), 10, 4 );
|
||||
add_action( 'update_option_sidebars_widgets', array( $this, 'update_option_sidebars_widgets_action' ), 10, 2 );
|
||||
add_action( 'wpml_reset_ls_settings', array( $this, 'reset_ls_settings_action' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $ls_config
|
||||
*/
|
||||
public function reset_ls_settings_action( array $ls_config ) {
|
||||
$restore_ls_settings = ( isset( $_GET['restore_ls_settings'] ) && 1 == $_GET['restore_ls_settings'] );
|
||||
$has_valid_nonce = isset( $_GET['nonce'] )
|
||||
&& wp_create_nonce( WPML_LS_Admin_UI::RESET_NONCE_NAME ) === $_GET['nonce'];
|
||||
$restore_ls_settings = $restore_ls_settings && $has_valid_nonce;
|
||||
|
||||
if ( ! $this->sitepress->get_setting( 'language_selector_initialized' ) || $restore_ls_settings ) {
|
||||
|
||||
delete_option( self::SETTINGS_SLUG );
|
||||
$this->settings = null;
|
||||
|
||||
if ( ! empty( $ls_config ) ) {
|
||||
|
||||
$this->sitepress->set_setting( 'language_selector_initialized', 1 );
|
||||
$reset_settings = $this->read_config_settings_recursive( $ls_config['key'] );
|
||||
|
||||
$converted_settings = $this->migration()->get_converted_settings( $reset_settings );
|
||||
|
||||
if ( isset( $converted_settings['migrated'] ) && 1 === $converted_settings['migrated'] ) {
|
||||
$reset_settings = $converted_settings;
|
||||
} else {
|
||||
$reset_settings['migrated'] = 0;
|
||||
}
|
||||
|
||||
$this->save_settings( $reset_settings );
|
||||
} else {
|
||||
$this->maybe_init_settings();
|
||||
}
|
||||
|
||||
if ( $this->sitepress->get_setting( 'setup_complete' ) && $restore_ls_settings ) {
|
||||
$this->sitepress->get_wp_api()->wp_safe_redirect( $this->get_restore_redirect_url() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|void
|
||||
*/
|
||||
public function get_restore_redirect_url() {
|
||||
return admin_url( 'admin.php?page=' . WPML_LS_Admin_UI::get_page_hook() . '&ls_reset=default' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $arr
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function read_config_settings_recursive( $arr ) {
|
||||
$ret = array();
|
||||
|
||||
if ( is_array( $arr ) ) {
|
||||
foreach ( $arr as $v ) {
|
||||
if ( isset( $v['key'] ) && is_array( $v['key'] ) ) {
|
||||
$partial = ! is_numeric( key( $v['key'] ) ) ? array( $v['key'] ) : $v['key'];
|
||||
$ret[ $v['attr']['name'] ] = $this->read_config_settings_recursive( $partial );
|
||||
} else {
|
||||
$ret[ $v['attr']['name'] ] = $v['value'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_settings_base_slug() {
|
||||
return self::SETTINGS_SLUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_settings() {
|
||||
$this->maybe_init_settings();
|
||||
|
||||
return $this->settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_settings_model() {
|
||||
$settings = $this->get_settings();
|
||||
|
||||
foreach ( array( 'menus', 'sidebars', 'statics' ) as $group ) {
|
||||
$slots = $this->get_setting( $group );
|
||||
foreach ( $slots as $slot_slug => $slot_setting ) {
|
||||
$slot_vars = $slot_setting->get_model();
|
||||
$slot = new \WPML_LS_Slot( $slot_vars );
|
||||
|
||||
$settings[ $group ][ $slot_slug ] = $slot->get_model();
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_default_settings() {
|
||||
$core_templates = $this->get_core_templates();
|
||||
|
||||
$footer_slot = array(
|
||||
'show' => 0,
|
||||
'display_names_in_current_lang' => 1,
|
||||
'template' => $core_templates['list-horizontal'],
|
||||
'slot_group' => 'statics',
|
||||
'slot_slug' => 'footer',
|
||||
);
|
||||
|
||||
$post_translations = array(
|
||||
'show' => 0,
|
||||
'display_names_in_current_lang' => 1,
|
||||
'display_before_content' => 1,
|
||||
'availability_text' => esc_html__( 'This post is also available in: %s', 'sitepress' ),
|
||||
'template' => $core_templates['post-translations'],
|
||||
'slot_group' => 'statics',
|
||||
'slot_slug' => 'post_translations',
|
||||
);
|
||||
|
||||
$shortcode_actions = array(
|
||||
'show' => 0,
|
||||
'display_names_in_current_lang' => 1,
|
||||
'template' => $core_templates['list-horizontal'],
|
||||
'slot_group' => 'statics',
|
||||
'slot_slug' => 'shortcode_actions',
|
||||
);
|
||||
|
||||
$getMergedArgs = function ( $args ) {
|
||||
$shared = [
|
||||
'include_flag_width' => \WPML_LS_Settings::DEFAULT_FLAG_WIDTH,
|
||||
'include_flag_height' => \WPML_LS_Settings::DEFAULT_FLAG_HEIGHT,
|
||||
];
|
||||
|
||||
return array_merge( $shared, $args );
|
||||
};
|
||||
|
||||
return array(
|
||||
'menus' => array(),
|
||||
'sidebars' => array(),
|
||||
'statics' => array(
|
||||
'footer' => $this->slot_factory->get_slot( $getMergedArgs( $footer_slot ) ),
|
||||
'post_translations' => $this->slot_factory->get_slot( $getMergedArgs( $post_translations ) ),
|
||||
'shortcode_actions' => $this->slot_factory->get_slot( $getMergedArgs( $shortcode_actions ) ),
|
||||
),
|
||||
'additional_css' => '',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_shared_settings_keys() {
|
||||
return array(
|
||||
// SitePress::settings => WPML_LS_Settings::settings
|
||||
'languages_order' => 'languages_order',
|
||||
'icl_lso_link_empty' => 'link_empty',
|
||||
'icl_lang_sel_copy_parameters' => 'copy_parameters',
|
||||
);
|
||||
}
|
||||
|
||||
private function init_shared_settings() {
|
||||
foreach ( $this->get_shared_settings_keys() as $sp_key => $ls_key ) {
|
||||
$this->settings[ $ls_key ] = $this->sitepress->get_setting( $sp_key );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $new_settings
|
||||
*/
|
||||
private function persist_shared_settings( $new_settings ) {
|
||||
foreach ( $this->get_shared_settings_keys() as $sp_key => $ls_key ) {
|
||||
if ( array_key_exists( $ls_key, $new_settings ) ) {
|
||||
$this->sitepress->set_setting( $sp_key, $new_settings[ $ls_key ] );
|
||||
}
|
||||
}
|
||||
|
||||
$this->sitepress->save_settings();
|
||||
}
|
||||
|
||||
private function maybe_init_settings() {
|
||||
if ( null === $this->settings ) {
|
||||
$this->settings = get_option( self::SETTINGS_SLUG );
|
||||
|
||||
$this->handle_corrupted_settings();
|
||||
|
||||
if ( ! $this->settings || ! isset( $this->settings['migrated'] ) ) {
|
||||
$this->settings = $this->migration()->get_converted_settings( $this->sitepress->get_settings() );
|
||||
$default_settings = $this->get_default_settings();
|
||||
$this->settings = wp_parse_args( $this->settings, $default_settings );
|
||||
$this->save_settings( $this->settings );
|
||||
}
|
||||
|
||||
if ( ! isset( $this->settings['converted_menu_ids'] ) ) {
|
||||
$this->settings = $this->migration()->convert_menu_ids( $this->settings );
|
||||
$this->persist_settings( $this->settings );
|
||||
}
|
||||
|
||||
$this->init_shared_settings();
|
||||
|
||||
if ( ! $this->sitepress->get_wp_api()->is_admin() ) {
|
||||
$this->settings = $this->strings->translate_all( $this->settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function handle_corrupted_settings() {
|
||||
|
||||
$corrupted_settings = [];
|
||||
|
||||
foreach ( array( 'menus', 'sidebars', 'statics' ) as $group ) {
|
||||
if ( ! isset( $this->settings[ $group ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $this->settings[ $group ] as $key => $slot ) {
|
||||
if ( $slot instanceof __PHP_Incomplete_Class ) {
|
||||
unset( $this->settings[ $group ][ $key ] );
|
||||
$corrupted_settings[] = ucfirst( $group ) . ' - ' . $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $corrupted_settings ) {
|
||||
$this->add_corrupted_settings_notice( $corrupted_settings );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $corrupted_settings
|
||||
*/
|
||||
private function add_corrupted_settings_notice( $corrupted_settings ) {
|
||||
|
||||
$message = __( 'Some WPML Language Switcher settings were reinitialized because they were corrupted. Please re-configure them:', 'sitepress' );
|
||||
$message .= ' ' . join( ', ', $corrupted_settings ) . '.';
|
||||
|
||||
$admin_notices = wpml_get_admin_notices();
|
||||
$notice = $admin_notices->create_notice( 'corrupted_settings', $message, 'wpml-ls-settings' );
|
||||
|
||||
$notice->set_css_class_types( 'error' );
|
||||
$notice->set_dismissible( true );
|
||||
$notice->set_flash( true );
|
||||
|
||||
$admin_notices->add_notice( $notice );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_registered_sidebars() {
|
||||
global $wp_registered_sidebars;
|
||||
|
||||
return is_array( $wp_registered_sidebars ) ? $wp_registered_sidebars : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_available_menus() {
|
||||
$has_term_filter = remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
|
||||
|
||||
$ret = array();
|
||||
$default_lang = $this->sitepress->get_default_language();
|
||||
$menus = wp_get_nav_menus( array( 'orderby' => 'name' ) );
|
||||
if ( $menus ) {
|
||||
foreach ( $menus as $menu ) {
|
||||
$menu_details = $this->sitepress->get_element_language_details( $menu->term_taxonomy_id, 'tax_nav_menu' );
|
||||
if ( isset( $menu_details->language_code ) && $menu_details->language_code === $default_lang ) {
|
||||
$ret[ $menu->term_id ] = $menu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $has_term_filter ) {
|
||||
add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1, 1 );
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $new_settings
|
||||
*/
|
||||
private function persist_settings( $new_settings ) {
|
||||
$this->persist_shared_settings( $new_settings );
|
||||
|
||||
if ( null !== $new_settings && count( $new_settings ) > 0 ) {
|
||||
update_option( self::SETTINGS_SLUG, $new_settings );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slot_group
|
||||
* @param string $slot_slug
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
public function get_slot( $slot_group, $slot_slug ) {
|
||||
$void_settings = array( 'show' => 0 );
|
||||
$groups = $this->get_settings();
|
||||
$slot = isset( $groups[ $slot_group ][ $slot_slug ] )
|
||||
? $groups[ $slot_group ][ $slot_slug ] : $this->slot_factory->get_slot( $void_settings );
|
||||
|
||||
return $slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $term_id
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
public function get_menu_settings_from_id( $term_id ) {
|
||||
$menu_slot = $this->get_slot( 'menus', $term_id );
|
||||
if ( $menu_slot->is_enabled() ) {
|
||||
return $menu_slot;
|
||||
}
|
||||
|
||||
if ( $term_id > 0 ) {
|
||||
$menu_element = new WPML_Menu_Element( $term_id, $this->sitepress );
|
||||
$default_lang = $this->sitepress->get_default_language();
|
||||
$source_language_code = $menu_element->get_source_language_code();
|
||||
|
||||
$findSettingsInLang = function ( $lang ) use ( $menu_element ) {
|
||||
return Maybe::of( $lang )
|
||||
->map( [ $menu_element, 'get_translation' ] )
|
||||
->map( invoke( 'get_wp_object' ) )
|
||||
->reject( 'is_wp_error' )
|
||||
->map( Obj::prop( 'term_id' ) )
|
||||
->map( partial( [ $this, 'get_slot' ], 'menus' ) )
|
||||
->filter( invoke( 'is_enabled' ) )
|
||||
->getOrElse( null );
|
||||
};
|
||||
|
||||
if ( $menu_element->get_language_code() !== $default_lang ) {
|
||||
$menu_slot = $findSettingsInLang( $default_lang ) ?: $menu_slot;
|
||||
}
|
||||
|
||||
if ( $source_language_code && $source_language_code !== $default_lang && $menu_element->get_language_code() !== $source_language_code ) {
|
||||
$menu_slot = $findSettingsInLang( $source_language_code ) ?: $menu_slot;
|
||||
}
|
||||
}
|
||||
|
||||
return $menu_slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_active_slots() {
|
||||
$ret = array();
|
||||
|
||||
foreach ( array( 'menus', 'sidebars', 'statics' ) as $group ) {
|
||||
$slots = $this->get_setting( $group );
|
||||
foreach ( $slots as $slot_slug => $slot ) {
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
if ( $slot->is_enabled() ) {
|
||||
$ret[] = $slot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_active_templates() {
|
||||
$ret = array();
|
||||
$active_slots = $this->get_active_slots();
|
||||
|
||||
foreach ( $active_slots as $slot ) {
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
if ( $slot->is_enabled() ) {
|
||||
$ret[] = $slot->template();
|
||||
}
|
||||
}
|
||||
|
||||
return array_unique( $ret );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @return mixed string|array|null
|
||||
*/
|
||||
public function get_setting( $key ) {
|
||||
$this->maybe_init_settings();
|
||||
|
||||
return Obj::propOr( null, $key, $this->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $new_settings
|
||||
*/
|
||||
public function save_settings( $new_settings ) {
|
||||
$this->maybe_init_settings();
|
||||
$new_settings = $this->sanitizer->sanitize_all_settings( $new_settings );
|
||||
$new_settings['menus'] = array_intersect_key( $new_settings['menus'], $this->get_available_menus() );
|
||||
$new_settings['sidebars'] = array_intersect_key( $new_settings['sidebars'], $this->get_registered_sidebars() );
|
||||
$new_settings = $this->convert_slot_settings_to_objects( $new_settings );
|
||||
|
||||
if ( $this->sitepress->is_setup_complete() ) {
|
||||
$this->strings->register_all( $new_settings, $this->settings );
|
||||
}
|
||||
|
||||
$this->synchronize_widget_instances( $new_settings['sidebars'] );
|
||||
$this->persist_settings( $new_settings );
|
||||
$this->settings = $new_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function convert_slot_settings_to_objects( array $settings ) {
|
||||
foreach ( array( 'menus', 'sidebars', 'statics' ) as $group ) {
|
||||
|
||||
if ( isset( $settings[ $group ] ) ) {
|
||||
|
||||
foreach ( $settings[ $group ] as $slot_slug => $slot_settings ) {
|
||||
|
||||
if ( is_array( $slot_settings ) ) {
|
||||
$slot_settings['slot_slug'] = $slot_slug;
|
||||
$slot_settings['slot_group'] = $group;
|
||||
}
|
||||
|
||||
$settings[ $group ][ $slot_slug ] = $this->slot_factory->get_slot( $slot_settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,\WPML_LS_Slot> $sidebar_slots
|
||||
*/
|
||||
private function synchronize_widget_instances( $sidebar_slots ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/widgets.php';
|
||||
$wpml_ls_widget = new WPML_LS_Widget();
|
||||
$sidebars_widgets = $this->get_refreshed_sidebars_widgets();
|
||||
|
||||
if ( is_array( $sidebars_widgets ) ) {
|
||||
|
||||
foreach ( $sidebars_widgets as $sidebar => $widgets ) {
|
||||
if ( 'wp_inactive_widgets' === $sidebar ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$found = false;
|
||||
if ( is_array( $widgets ) ) {
|
||||
foreach ( $widgets as $key => $widget_id ) {
|
||||
if ( strpos( $widget_id, WPML_LS_Widget::SLUG ) === 0 ) {
|
||||
|
||||
if ( $found ) { // Only synchronize the first LS widget instance per sidebar
|
||||
unset( $sidebars_widgets[ $sidebar ][ $key ] );
|
||||
continue;
|
||||
}
|
||||
|
||||
$found = true;
|
||||
|
||||
if ( ! isset( $sidebar_slots[ $sidebar ] ) ) {
|
||||
$wpml_ls_widget->delete_instance( $widget_id );
|
||||
unset( $sidebars_widgets[ $sidebar ][ $key ] );
|
||||
} else {
|
||||
$wpml_ls_widget->update_instance( $sidebar_slots[ $sidebar ], $widget_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $found ) {
|
||||
|
||||
if ( isset( $sidebar_slots[ $sidebar ] ) ) {
|
||||
$new_instance_id = $wpml_ls_widget->create_new_instance( $sidebar_slots[ $sidebar ] );
|
||||
$sidebars_widgets[ $sidebar ] = is_array( $sidebars_widgets[ $sidebar ] ) ? $sidebars_widgets[ $sidebar ] : array();
|
||||
array_unshift( $sidebars_widgets[ $sidebar ], $new_instance_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$is_hooked = has_action( 'update_option_sidebars_widgets', array( $this, 'update_option_sidebars_widgets_action' ) );
|
||||
|
||||
if ( $is_hooked ) {
|
||||
remove_action( 'update_option_sidebars_widgets', array( $this, 'update_option_sidebars_widgets_action' ), 10 );
|
||||
}
|
||||
|
||||
wp_set_sidebars_widgets( $sidebars_widgets );
|
||||
|
||||
if ( $is_hooked ) {
|
||||
add_action( 'update_option_sidebars_widgets', array( $this, 'update_option_sidebars_widgets_action' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_refreshed_sidebars_widgets() {
|
||||
global $_wp_sidebars_widgets;
|
||||
|
||||
// Clear cached value used in wp_get_sidebars_widgets().
|
||||
$_wp_sidebars_widgets = null;
|
||||
|
||||
return wp_get_sidebars_widgets();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $old_sidebars
|
||||
* @param array $sidebars
|
||||
*/
|
||||
public function update_option_sidebars_widgets_action( $old_sidebars, $sidebars ) {
|
||||
unset( $sidebars['wp_inactive_widgets'], $sidebars['array_version'] );
|
||||
$this->maybe_init_settings();
|
||||
|
||||
if ( is_array( $sidebars ) ) {
|
||||
foreach ( $sidebars as $sidebar_slug => $widgets ) {
|
||||
$this->synchronize_sidebar_settings( $sidebar_slug, $widgets );
|
||||
}
|
||||
}
|
||||
|
||||
$this->save_settings( $this->settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sidebar_slug
|
||||
* @param array $widgets
|
||||
*/
|
||||
private function synchronize_sidebar_settings( $sidebar_slug, $widgets ) {
|
||||
$this->settings['sidebars'][ $sidebar_slug ] = isset( $this->settings['sidebars'][ $sidebar_slug ] )
|
||||
? $this->settings['sidebars'][ $sidebar_slug ] : array();
|
||||
|
||||
$widget_id = $this->find_first_ls_widget( $widgets );
|
||||
|
||||
if ( $widget_id === false ) {
|
||||
unset( $this->settings['sidebars'][ $sidebar_slug ] );
|
||||
} else {
|
||||
$instance_number = str_replace( WPML_LS_Widget::SLUG . '-', '', $widget_id );
|
||||
$widget_class_options = get_option( 'widget_' . WPML_LS_Widget::SLUG );
|
||||
$widget_instance_options = isset( $widget_class_options[ $instance_number ] )
|
||||
? $widget_class_options[ $instance_number ] : array();
|
||||
|
||||
$this->settings['sidebars'][ $sidebar_slug ] = $this->get_slot_from_widget_instance( $widget_instance_options );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $instance
|
||||
* @param array $new_instance
|
||||
* @param array|null $old_instance
|
||||
* @param WP_Widget $widget
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function widget_update_callback_filter( array $instance, array $new_instance, $old_instance, WP_Widget $widget ) {
|
||||
|
||||
if ( strpos( $widget->id_base, WPML_LS_Widget::SLUG ) === 0 ) {
|
||||
$sidebar_id = Sanitize::stringProp( 'sidebar', $_POST );
|
||||
$sidebar_id = $sidebar_id ? $sidebar_id : $this->find_parent_sidebar( $widget->id );
|
||||
if ( $sidebar_id ) {
|
||||
$this->maybe_init_settings();
|
||||
if ( isset( $this->settings['sidebars'][ $sidebar_id ] ) ) {
|
||||
$this->settings['sidebars'][ $sidebar_id ] = $this->get_slot_from_widget_instance( $instance );
|
||||
}
|
||||
|
||||
$this->save_settings( $this->settings );
|
||||
}
|
||||
}
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $widget_instance
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
private function get_slot_from_widget_instance( $widget_instance ) {
|
||||
$slot = isset( $widget_instance['slot'] ) ? $widget_instance['slot'] : array();
|
||||
|
||||
if ( ! is_a( $slot, 'WPML_LS_Sidebar_Slot' ) ) {
|
||||
$slot = $this->slot_factory->get_default_slot_arguments( 'sidebars' );
|
||||
$slot = $this->slot_factory->get_slot( $slot );
|
||||
}
|
||||
|
||||
return $slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find in which sidebar a language switcher instance is set
|
||||
*
|
||||
* @param string $widget_to_find
|
||||
*
|
||||
* @return bool|string
|
||||
*/
|
||||
private function find_parent_sidebar( $widget_to_find ) {
|
||||
$sidebars_widgets = wp_get_sidebars_widgets();
|
||||
|
||||
if ( is_array( $sidebars_widgets ) ) {
|
||||
foreach ( $sidebars_widgets as $sidebar_id => $widgets ) {
|
||||
if ( is_array( $widgets ) ) {
|
||||
foreach ( $widgets as $widget ) {
|
||||
if ( $widget_to_find === $widget ) {
|
||||
return $sidebar_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first language switcher in an array of widgets
|
||||
*
|
||||
* @param array $widgets
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function find_first_ls_widget( $widgets ) {
|
||||
$ret = false;
|
||||
$widgets = is_array( $widgets ) ? $widgets : array();
|
||||
foreach ( $widgets as $widget_id ) {
|
||||
if ( strpos( $widget_id, WPML_LS_Widget::SLUG ) === 0 ) {
|
||||
$ret = $widget_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_ordered_languages() {
|
||||
$active_languages = $this->sitepress->get_active_languages();
|
||||
|
||||
foreach ( $active_languages as $code => $language ) {
|
||||
$active_languages[ $code ]['flag_img'] = $this->sitepress->get_flag_image( $code );
|
||||
}
|
||||
|
||||
return $this->sitepress->order_languages( $active_languages );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_default_color_schemes() {
|
||||
return $this->color_presets->get_defaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|null|string $slug
|
||||
*
|
||||
* @return mixed|array|string
|
||||
*/
|
||||
public function get_core_templates( $slug = null ) {
|
||||
$parameters = WPML_Language_Switcher::parameters();
|
||||
$core_templates = isset( $parameters['core_templates'] ) ? $parameters['core_templates'] : array();
|
||||
$return = $core_templates;
|
||||
|
||||
if ( ! empty( $slug ) ) {
|
||||
$return = isset( $return[ $slug ] ) ? $return[ $slug ] : null;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $template_slug
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function can_load_styles( $template_slug = null ) {
|
||||
if ( $template_slug ) {
|
||||
$template = $this->templates->get_template( $template_slug );
|
||||
$can_load = ! ( $template->is_core() && $this->sitepress->get_wp_api()->constant( 'ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS' ) );
|
||||
} else {
|
||||
$can_load = ! $this->sitepress->get_wp_api()->constant( 'ICL_DONT_LOAD_LANGUAGE_SELECTOR_CSS' );
|
||||
}
|
||||
|
||||
return $can_load;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $template_slug
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function can_load_script( $template_slug = null ) {
|
||||
if ( $template_slug ) {
|
||||
$template = $this->templates->get_template( $template_slug );
|
||||
$can_load = ! ( $template->is_core() && $this->sitepress->get_wp_api()->constant( 'ICL_DONT_LOAD_LANGUAGES_JS' ) );
|
||||
} else {
|
||||
$can_load = ! $this->sitepress->get_wp_api()->constant( 'ICL_DONT_LOAD_LANGUAGES_JS' );
|
||||
}
|
||||
|
||||
return $can_load;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Migration
|
||||
*/
|
||||
private function migration() {
|
||||
if ( ! $this->migration ) {
|
||||
$this->migration = new WPML_LS_Migration( $this, $this->sitepress, $this->slot_factory );
|
||||
}
|
||||
|
||||
return $this->migration;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Template extends WPML_Templates_Factory {
|
||||
|
||||
const FILENAME = 'template.twig';
|
||||
|
||||
/* @var array $template */
|
||||
private $template;
|
||||
|
||||
/* @var array $model */
|
||||
private $model;
|
||||
|
||||
/* @var string $prefix */
|
||||
private $prefix = 'wpml-ls-';
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Menu constructor.
|
||||
*
|
||||
* @param array $template_data
|
||||
* @param array $template_model
|
||||
*/
|
||||
public function __construct( $template_data, $template_model = array() ) {
|
||||
$this->template = $this->format_data($template_data);
|
||||
$this->template['js'] = self::remove_non_minified_duplicates( $this->template['js'] );
|
||||
$this->template['css'] = self::remove_non_minified_duplicates( $this->template['css'] );
|
||||
|
||||
if ( array_key_exists( 'template_string', $this->template ) ) {
|
||||
$this->template_string = $this->template['template_string'];
|
||||
}
|
||||
|
||||
$this->model = $template_model;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure some elements are of array type
|
||||
*
|
||||
* @param array $template_data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function format_data( $template_data ) {
|
||||
foreach ( array( 'path', 'js', 'css' ) as $k ) {
|
||||
$template_data[ $k ] = isset( $template_data[ $k ] ) ? $template_data[ $k ] : array();
|
||||
$template_data[ $k ] = is_array( $template_data[ $k ] ) ? $template_data[ $k ] : array( $template_data[ $k ] );
|
||||
}
|
||||
|
||||
return $template_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $model
|
||||
*/
|
||||
public function set_model( $model ) {
|
||||
$this->model = is_array( $model ) ? $model : array( $model );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
* @throws \WPML\Core\Twig\Error\LoaderError
|
||||
* @throws \WPML\Core\Twig\Error\RuntimeError
|
||||
* @throws \WPML\Core\Twig\Error\SyntaxError
|
||||
*/
|
||||
public function get_html() {
|
||||
$ret = '';
|
||||
if ( $this->template_paths || $this->template_string ) {
|
||||
$ret = parent::get_view();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $with_version
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_styles( $with_version = false ) {
|
||||
$styles = $with_version
|
||||
? array_map( array( $this, 'add_resource_version' ), $this->template['css'] )
|
||||
: $this->template['css'];
|
||||
|
||||
return array_values( $styles );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function has_styles() {
|
||||
return ! empty( $this->template['css'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $with_version
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_scripts( $with_version = false ) {
|
||||
$scripts = $with_version
|
||||
? array_map( array( $this, 'add_resource_version' ), $this->template['js'] )
|
||||
: $this->template['js'];
|
||||
|
||||
return array_values( $scripts );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function add_resource_version( $url ) {
|
||||
return $url . '?ver=' . $this->get_version();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $index
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_resource_handler( $index ) {
|
||||
$slug = isset( $this->template['slug'] ) ? $this->template['slug'] : '';
|
||||
$prefix = $this->is_core() ? '' : $this->prefix;
|
||||
return $prefix . $slug . '-' . $index;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string|bool
|
||||
*/
|
||||
public function get_inline_style_handler() {
|
||||
$count = count( $this->template['css'] );
|
||||
|
||||
return $count > 0 ? $this->get_resource_handler( $count - 1 ) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_version() {
|
||||
return $this->template['version'];
|
||||
}
|
||||
|
||||
protected function init_template_base_dir() {
|
||||
$this->template_paths = $this->template['path'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string Template filename
|
||||
*/
|
||||
public function get_template() {
|
||||
$template = self::FILENAME;
|
||||
|
||||
if ( isset( $this->template_string ) ) {
|
||||
$template = $this->template_string;
|
||||
} elseif ( array_key_exists( 'filename', $this->template ) ) {
|
||||
$template = $this->template['filename'];
|
||||
}
|
||||
|
||||
return $template;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_model() {
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_template_data() {
|
||||
return $this->template;
|
||||
}
|
||||
|
||||
/**
|
||||
* return bool
|
||||
*/
|
||||
public function is_core() {
|
||||
return isset( $this->template['is_core'] ) ? (bool) $this->template['is_core'] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function supported_slot_types() {
|
||||
return isset( $this->template['for'] ) ? $this->template['for'] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function force_settings() {
|
||||
return isset( $this->template['force_settings'] ) ? $this->template['force_settings'] : array();
|
||||
}
|
||||
|
||||
public function is_path_valid() {
|
||||
$valid = true;
|
||||
$this->template_paths = apply_filters( 'wpml_ls_template_paths', $this->template_paths );
|
||||
|
||||
foreach ( $this->template_paths as $path ) {
|
||||
if ( ! file_exists( $path ) ) {
|
||||
$valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template_string
|
||||
*/
|
||||
public function set_template_string( $template_string ) {
|
||||
if ( method_exists( $this, 'is_string_template' ) ) {
|
||||
$this->template_string = $template_string;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If an asset has a minified and a non-minified version,
|
||||
* we remove the non-minified version.
|
||||
*
|
||||
* @param array $assets
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function remove_non_minified_duplicates( array $assets ) {
|
||||
$hasMinifiedVersion = function( $url ) use ( $assets ) {
|
||||
$extension = pathinfo( $url, PATHINFO_EXTENSION );
|
||||
$basename = pathinfo( $url, PATHINFO_BASENAME );
|
||||
$filename = pathinfo( $url, PATHINFO_FILENAME );
|
||||
|
||||
$url_start = substr( $url, 0, strlen( $url ) - strlen( $basename ) );
|
||||
$minified_file = $filename . '.min.' . $extension;
|
||||
if ( in_array( $url_start . $minified_file, $assets, true ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
return wpml_collect( $assets )
|
||||
->reject( $hasMinifiedVersion )
|
||||
->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Templates {
|
||||
|
||||
const CONFIG_FILE = 'config.json';
|
||||
const OPTION_NAME = 'wpml_language_switcher_template_objects';
|
||||
|
||||
/** @var string $uploads_path */
|
||||
private $uploads_path;
|
||||
|
||||
/**
|
||||
* @var WPML_File
|
||||
*/
|
||||
private $wpml_file;
|
||||
|
||||
/* @var array $templates Collection of WPML_LS_Template */
|
||||
private $templates = false;
|
||||
|
||||
/* @var string $ds */
|
||||
private $ds = DIRECTORY_SEPARATOR;
|
||||
|
||||
public function __construct( WPML_File $wpml_file = null ) {
|
||||
if ( ! $wpml_file ) {
|
||||
$wpml_file = new WPML_File();
|
||||
}
|
||||
|
||||
$this->wpml_file = $wpml_file;
|
||||
}
|
||||
|
||||
public function init_hooks() {
|
||||
add_action( 'after_setup_theme', array( $this, 'after_setup_theme_action' ) );
|
||||
add_action( 'activated_plugin', array( $this, 'activated_plugin_action' ) );
|
||||
add_action( 'deactivated_plugin', array( $this, 'activated_plugin_action' ) );
|
||||
add_action( 'switch_theme', array( $this, 'activated_plugin_action' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function after_setup_theme_action() {
|
||||
return $this->init_available_templates();
|
||||
}
|
||||
|
||||
public function activated_plugin_action() {
|
||||
delete_option( self::OPTION_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null|array $in_array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_templates( $in_array = null ) {
|
||||
if ( null === $in_array ) {
|
||||
$ret = $this->templates;
|
||||
} else {
|
||||
// PHP 5.3 Bug https://bugs.php.net/bug.php?id=34857
|
||||
$in_array = $in_array ? array_combine( $in_array, $in_array ) : $in_array;
|
||||
$ret = array_intersect_key( $this->templates, $in_array );
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template_slug
|
||||
*
|
||||
* @return WPML_LS_Template
|
||||
*/
|
||||
public function get_template( $template_slug ) {
|
||||
$ret = new WPML_LS_Template( array() );
|
||||
if ( array_key_exists( $template_slug, $this->templates ) ) {
|
||||
$ret = $this->templates[ $template_slug ];
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
public function get_all_templates_data() {
|
||||
$ret = array();
|
||||
|
||||
foreach ( $this->get_templates() as $slug => $template ) {
|
||||
/* @var WPML_LS_Template $template */
|
||||
$ret[ $slug ] = $template->get_template_data();
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function init_available_templates() {
|
||||
$is_admin_ui_page = isset( $_GET['page'] ) && WPML_LS_Admin_UI::get_page_hook() === $_GET['page'];
|
||||
|
||||
if ( ! $is_admin_ui_page ) {
|
||||
$this->templates = $this->get_templates_from_transient();
|
||||
}
|
||||
|
||||
if ( $this->templates === false ) {
|
||||
|
||||
$this->templates = array();
|
||||
$dirs_to_scan = array();
|
||||
|
||||
/**
|
||||
* Filter the directories to scan
|
||||
*
|
||||
* @param array $dirs_to_scan
|
||||
*/
|
||||
$dirs_to_scan = apply_filters( 'wpml_ls_directories_to_scan', $dirs_to_scan );
|
||||
|
||||
$sub_dir = $this->ds . 'templates' . $this->ds . 'language-switchers';
|
||||
$wpml_core_path = WPML_PLUGIN_PATH . $sub_dir;
|
||||
$theme_path = get_template_directory() . $this->ds . 'wpml' . $sub_dir;
|
||||
$child_theme_path = get_stylesheet_directory() . $this->ds . 'wpml' . $sub_dir;
|
||||
$uploads_path = $this->get_uploads_path() . $this->ds . 'wpml' . $sub_dir;
|
||||
|
||||
array_unshift( $dirs_to_scan, $wpml_core_path, $theme_path, $child_theme_path, $uploads_path );
|
||||
|
||||
$templates_paths = $this->scan_template_paths( $dirs_to_scan );
|
||||
|
||||
foreach ( $templates_paths as $template_path ) {
|
||||
$template_path = $this->wpml_file->fix_dir_separator( $template_path );
|
||||
if ( file_exists( $template_path . $this->ds . WPML_LS_Template::FILENAME ) ) {
|
||||
$tpl = array();
|
||||
$config = $this->parse_template_config( $template_path );
|
||||
|
||||
$tpl['path'] = [ $wpml_core_path, $template_path ];
|
||||
$tpl['version'] = isset( $config['version'] ) ? $config['version'] : '1';
|
||||
$tpl['name'] = isset( $config['name'] ) ? $config['name'] : null;
|
||||
$tpl['name'] = $this->get_unique_name( $tpl['name'], $template_path );
|
||||
$tpl['slug'] = sanitize_title_with_dashes( $tpl['name'] );
|
||||
$tpl['base_uri'] = trailingslashit( $this->wpml_file->get_uri_from_path( $template_path ) );
|
||||
$tpl['css'] = $this->get_files( 'css', $template_path, $config );
|
||||
$tpl['js'] = $this->get_files( 'js', $template_path, $config );
|
||||
|
||||
$tpl['flags_base_uri'] = isset( $config['flags_dir'] ) // todo: check with ../
|
||||
? $this->wpml_file->get_uri_from_path( $template_path . $this->ds . $config['flags_dir'] ) : null;
|
||||
$tpl['flags_base_uri'] = ! isset( $tpl['flags_base_uri'] ) && file_exists( $template_path . $this->ds . 'flags' )
|
||||
? $this->wpml_file->get_uri_from_path( $template_path . $this->ds . 'flags' ) : $tpl['flags_base_uri'];
|
||||
|
||||
$tpl['flag_extension'] = isset( $config['flag_extension'] )
|
||||
? $config['flag_extension'] : null;
|
||||
|
||||
if ( $this->is_core_template( $template_path ) ) {
|
||||
$tpl['is_core'] = true;
|
||||
$tpl['slug'] = isset( $config['slug'] ) ? $config['slug'] : $tpl['slug'];
|
||||
}
|
||||
|
||||
$tpl['for'] = isset( $config['for'] )
|
||||
? $config['for'] : array( 'menus', 'sidebars', 'footer', 'post_translations', 'shortcode_actions' );
|
||||
$tpl['force_settings'] = isset( $config['settings'] )
|
||||
? $config['settings'] : array();
|
||||
|
||||
$this->templates[ $tpl['slug'] ] = new WPML_LS_Template( $tpl );
|
||||
}
|
||||
}
|
||||
update_option( self::OPTION_NAME, $this->templates );
|
||||
}
|
||||
|
||||
return $this->templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $dirs_to_scan
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function scan_template_paths( $dirs_to_scan ) {
|
||||
$templates_paths = array();
|
||||
|
||||
foreach ( $dirs_to_scan as $dir ) {
|
||||
if ( ! is_dir( $dir ) ) {
|
||||
continue;
|
||||
}
|
||||
$files = scandir( $dir );
|
||||
$files = array_diff( $files, array( '..', '.' ) );
|
||||
if ( count( $files ) > 0 ) {
|
||||
foreach ( $files as $file ) {
|
||||
$template_path = $dir . '/' . $file;
|
||||
if ( is_dir( $template_path )
|
||||
&& file_exists( $template_path . $this->ds . WPML_LS_Template::FILENAME )
|
||||
&& file_exists( $template_path . $this->ds . self::CONFIG_FILE )
|
||||
) {
|
||||
$templates_paths[] = $template_path;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $templates_paths;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $template_path
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parse_template_config( $template_path ) {
|
||||
$config = array();
|
||||
$configuration_file = $template_path . $this->ds . self::CONFIG_FILE;
|
||||
if ( file_exists( $configuration_file ) ) {
|
||||
$json_content = file_get_contents( $configuration_file );
|
||||
$config = json_decode( $json_content, true );
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $ext
|
||||
* @param string $template_path
|
||||
* @param array $config
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
private function get_files( $ext, $template_path, $config ) {
|
||||
$resources = array();
|
||||
|
||||
if ( isset( $config[ $ext ] ) ) {
|
||||
$config[ $ext ] = is_array( $config[ $ext ] ) ? $config[ $ext ] : array( $config[ $ext ] );
|
||||
foreach ( $config[ $ext ] as $file ) {
|
||||
$file = untrailingslashit( $template_path ) . $this->ds . $file;
|
||||
$resources[] = $this->wpml_file->get_uri_from_path( $file );
|
||||
}
|
||||
} else {
|
||||
$search_path = $template_path . $this->ds . '*.' . $ext;
|
||||
if ( glob( $search_path ) ) {
|
||||
foreach ( glob( $search_path ) as $file ) {
|
||||
$resources[] = $this->wpml_file->get_uri_from_path( $file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed|string|null $name
|
||||
* @param string $path
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_unique_name( $name, $path ) {
|
||||
if ( is_null( $name ) ) {
|
||||
$name = basename( $path );
|
||||
}
|
||||
|
||||
if ( strpos( $path, $this->wpml_file->fix_dir_separator( get_template_directory() ) ) === 0 ) {
|
||||
$theme = wp_get_theme();
|
||||
$name = $theme . ' - ' . $name;
|
||||
} elseif ( strpos( $path, $this->wpml_file->fix_dir_separator( $this->get_uploads_path() ) ) === 0 ) {
|
||||
$name = __( 'Uploads', 'sitepress' ) . ' - ' . $name;
|
||||
} elseif (
|
||||
strpos( $path, $this->wpml_file->fix_dir_separator( WPML_PLUGINS_DIR ) ) === 0
|
||||
&& ! $this->is_core_template( $path )
|
||||
) {
|
||||
$plugin_dir = $this->wpml_file->fix_dir_separator( WPML_PLUGINS_DIR );
|
||||
$plugin_dir = preg_replace( '#' . preg_quote( $plugin_dir ) . '#', '', $path, 1 );
|
||||
$plugin_dir = ltrim( $plugin_dir, $this->ds );
|
||||
$plugin_dir = explode( $this->ds, $plugin_dir );
|
||||
|
||||
if ( isset( $plugin_dir[0] ) ) {
|
||||
$require = ABSPATH . 'wp-admin' . $this->ds . 'includes' . $this->ds . 'plugin.php';
|
||||
require_once $require;
|
||||
foreach ( get_plugins() as $slug => $plugin ) {
|
||||
if ( strpos( $slug, $plugin_dir[0] ) === 0 ) {
|
||||
$name = $plugin['Name'] . ' - ' . $name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$name = substr( md5( $path ), 0, 8 ) . ' - ' . $name;
|
||||
}
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $path
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_core_template( $path ) {
|
||||
return strpos( $path, $this->wpml_file->fix_dir_separator( WPML_PLUGIN_PATH ) ) === 0;
|
||||
}
|
||||
|
||||
private function get_templates_from_transient() {
|
||||
$templates = get_option( self::OPTION_NAME );
|
||||
if ( $templates && ! $this->are_template_paths_valid( $templates ) ) {
|
||||
$templates = false;
|
||||
}
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Template[] $templates
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function are_template_paths_valid( $templates ) {
|
||||
$paths_are_valid = true;
|
||||
foreach ( $templates as $template ) {
|
||||
if ( ! method_exists( $template, 'is_path_valid' ) || ! $template->is_path_valid() ) {
|
||||
$paths_are_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return $paths_are_valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
private function get_uploads_path() {
|
||||
if ( ! $this->uploads_path ) {
|
||||
$uploads = wp_upload_dir( null, false );
|
||||
|
||||
if ( isset( $uploads['basedir'] ) ) {
|
||||
$this->uploads_path = $uploads['basedir'];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->uploads_path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Obj;
|
||||
|
||||
class WPML_LS_Widget extends WP_Widget {
|
||||
|
||||
const SLUG = 'icl_lang_sel_widget';
|
||||
const ANCHOR_BASE = '#sidebars/';
|
||||
|
||||
public function __construct() {
|
||||
parent::__construct(
|
||||
self::SLUG, // Base ID
|
||||
__( 'Language Switcher', 'sitepress' ), // Name
|
||||
array(
|
||||
'description' => __( 'Language Switcher', 'sitepress' ),
|
||||
)
|
||||
);
|
||||
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts_action' ) );
|
||||
}
|
||||
|
||||
public static function register() {
|
||||
register_widget( __CLASS__ );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hook
|
||||
*/
|
||||
public function admin_enqueue_scripts_action( $hook ) {
|
||||
global $sitepress;
|
||||
|
||||
if ( 'widgets.php' === $hook ) {
|
||||
$suffix = $sitepress->get_wp_api()->constant( 'SCRIPT_DEBUG' ) ? '' : '.min';
|
||||
wp_enqueue_script( 'wpml-widgets', ICL_PLUGIN_URL . '/res/js/widgets' . $suffix . '.js', array( 'jquery' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $args
|
||||
* @param array $instance
|
||||
*/
|
||||
public function widget( $args, $instance ) {
|
||||
/* @var WPML_Language_Switcher $wpml_language_switcher */
|
||||
global $wpml_language_switcher;
|
||||
|
||||
$sidebar = isset( $args['id'] ) ? $args['id'] : '';
|
||||
|
||||
/* @var WPML_LS_Slot $slot */
|
||||
$slot = $wpml_language_switcher->get_slot( 'sidebars', $sidebar );
|
||||
|
||||
if ( ! $slot instanceof WPML_LS_Sidebar_Slot ) {
|
||||
$instanceSlot = Obj::prop( 'slot', $instance );
|
||||
$slot = $instanceSlot instanceof WPML_LS_Sidebar_Slot ? $instanceSlot : $slot;
|
||||
}
|
||||
|
||||
$ret = $wpml_language_switcher->render( $slot );
|
||||
|
||||
if ( $ret ) {
|
||||
|
||||
if ( $slot->get( 'widget_title' ) ) {
|
||||
remove_filter( 'widget_title', 'icl_sw_filters_widget_title', 0 );
|
||||
|
||||
$ret = $args['before_title'] . apply_filters( 'widget_title', $slot->get( 'widget_title' ) )
|
||||
. $args['after_title'] . $ret;
|
||||
|
||||
if ( function_exists( 'icl_sw_filters_widget_title' ) ) {
|
||||
add_filter( 'widget_title', 'icl_sw_filters_widget_title', 0 );
|
||||
}
|
||||
}
|
||||
|
||||
echo $args['before_widget'] . $ret . $args['after_widget'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function form( $instance ) {
|
||||
/* @var WPML_Language_Switcher $wpml_language_switcher */
|
||||
global $wpml_language_switcher;
|
||||
|
||||
$slug = isset( $instance['slot'] ) ? $instance['slot']->slug() : '';
|
||||
echo $wpml_language_switcher->get_button_to_edit_slot( 'sidebars', $slug );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $new_instance
|
||||
* @param array $old_instance
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function update( $new_instance, $old_instance ) {
|
||||
if ( ! $new_instance && ! $old_instance ) {
|
||||
$slot_factory = new WPML_LS_Slot_Factory();
|
||||
$args = $slot_factory->get_default_slot_arguments( 'sidebars' );
|
||||
$args['slot_slug'] = isset( $_POST['sidebar'] ) ? $_POST['sidebar'] : '';
|
||||
|
||||
$new_instance = array(
|
||||
'slot' => $slot_factory->get_slot( $args ),
|
||||
);
|
||||
}
|
||||
|
||||
return $new_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function create_new_instance( WPML_LS_Slot $slot ) {
|
||||
require_once ABSPATH . '/wp-admin/includes/widgets.php';
|
||||
$number = next_widget_id_number( $this->id_base );
|
||||
$this->_set( $number );
|
||||
$this->_register_one( $number );
|
||||
$all_instances = $this->get_settings();
|
||||
$all_instances[ $number ] = $this->get_instance_options_from_slot( $slot );
|
||||
$this->save_settings( $all_instances );
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
* @param int $widget_id
|
||||
*/
|
||||
public function update_instance( WPML_LS_Slot $slot, $widget_id = null ) {
|
||||
$number = isset( $widget_id ) ? $this->get_number_from_widget_id( $widget_id ) : $this->number;
|
||||
$all_instances = $this->get_settings();
|
||||
$all_instances[ $number ] = $this->get_instance_options_from_slot( $slot );
|
||||
$this->save_settings( $all_instances );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $widget_id
|
||||
*/
|
||||
public function delete_instance( $widget_id = null ) {
|
||||
$number = isset( $widget_id ) ? $this->get_number_from_widget_id( $widget_id ) : $this->number;
|
||||
$all_instances = $this->get_settings();
|
||||
unset( $all_instances[ $number ] );
|
||||
$this->save_settings( $all_instances );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $widget_id
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function get_number_from_widget_id( $widget_id ) {
|
||||
return (int) preg_replace( '/^' . self::SLUG . '-/', '', $widget_id, 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_LS_Slot $slot
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_instance_options_from_slot( WPML_LS_Slot $slot ) {
|
||||
return array( 'slot' => $slot );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_settings_page_url( $slug ) {
|
||||
return admin_url( 'admin.php?page=' . WPML_LS_Admin_UI::get_page_hook() . self::ANCHOR_BASE . $slug );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Actions extends WPML_LS_Public_API {
|
||||
|
||||
public function init_hooks() {
|
||||
if ( $this->sitepress->get_setting( 'setup_complete' ) ) {
|
||||
add_action( 'wpml_language_switcher', array( $this, 'callback' ), 10, 2 );
|
||||
|
||||
/**
|
||||
* Backward compatibility
|
||||
*
|
||||
* @deprecated see 'wpml_language_switcher'
|
||||
*/
|
||||
add_action( 'icl_language_selector', array( $this, 'callback' ) );
|
||||
add_action( 'wpml_add_language_selector', array( $this, 'callback' ) );
|
||||
add_action( 'wpml_footer_language_selector', array( $this, 'callback' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string|null $twig_template
|
||||
*/
|
||||
public function callback( $args, $twig_template = null ) {
|
||||
if ( '' === $args ) {
|
||||
$args = array();
|
||||
}
|
||||
|
||||
$args = $this->parse_legacy_actions( $args );
|
||||
$args = $this->convert_shortcode_args_aliases( $args );
|
||||
echo $this->render( $args, $twig_template );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function parse_legacy_actions( $args ) {
|
||||
$current_filter = current_filter();
|
||||
|
||||
if ( in_array( $current_filter, array( 'icl_language_selector', 'wpml_add_language_selector' ) ) ) {
|
||||
$args['type'] = 'custom';
|
||||
} elseif ( 'wpml_footer_language_selector' === $current_filter ) {
|
||||
$args['type'] = 'footer';
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Class WPML_LS_Public_API
|
||||
*/
|
||||
class WPML_LS_Public_API {
|
||||
|
||||
/** @var WPML_LS_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/** @var WPML_LS_Render $render */
|
||||
private $render;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
protected $sitepress;
|
||||
|
||||
/** @var WPML_LS_Slot_Factory */
|
||||
private $slot_factory;
|
||||
|
||||
/**
|
||||
* WPML_LS_Public_API constructor.
|
||||
*
|
||||
* @param WPML_LS_Settings $settings
|
||||
* @param WPML_LS_Render $render
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_LS_Slot_Factory $slot_factory
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_LS_Settings $settings,
|
||||
WPML_LS_Render $render,
|
||||
SitePress $sitepress,
|
||||
WPML_LS_Slot_Factory $slot_factory = null
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->render = $render;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->slot_factory = $slot_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string|null $twig_template
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function render( $args, $twig_template = null ) {
|
||||
$defaults_slot_args = $this->get_default_slot_args( $args );
|
||||
$slot_args = array_merge( $defaults_slot_args, $args );
|
||||
|
||||
$slot = $this->get_slot_factory()->get_slot( $slot_args );
|
||||
$slot->set( 'show', 1 );
|
||||
$slot->set( 'template_string', $twig_template );
|
||||
|
||||
if ( $slot->is_post_translations() ) {
|
||||
$output = $this->render->post_translations_label( $slot );
|
||||
} else {
|
||||
$output = $this->render->render( $slot );
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_default_slot_args( $args ) {
|
||||
$type = 'custom';
|
||||
|
||||
if ( isset( $args['type'] ) ) {
|
||||
$type = $args['type'];
|
||||
}
|
||||
|
||||
switch ( $type ) {
|
||||
case 'footer':
|
||||
$default_slot = $this->settings->get_slot( 'statics', 'footer' );
|
||||
break;
|
||||
|
||||
case 'post_translations':
|
||||
$default_slot = $this->settings->get_slot( 'statics', 'post_translations' );
|
||||
break;
|
||||
|
||||
case 'widget':
|
||||
$default_slot = $this->get_slot_factory()->get_default_slot( 'sidebars' );
|
||||
break;
|
||||
|
||||
case 'custom':
|
||||
default:
|
||||
$default_slot = $this->settings->get_slot( 'statics', 'shortcode_actions' );
|
||||
break;
|
||||
}
|
||||
|
||||
return $default_slot->get_model();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function convert_shortcode_args_aliases( $args ) {
|
||||
$aliases_map = self::get_argument_aliases();
|
||||
|
||||
foreach ( $aliases_map as $alias => $key ) {
|
||||
if ( array_key_exists( $alias, $args ) ) {
|
||||
$args[ $key ] = $args[ $alias ];
|
||||
unset( $args[ $alias ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function get_argument_aliases() {
|
||||
return array(
|
||||
'flags' => 'display_flags',
|
||||
'link_current' => 'display_link_for_current_lang',
|
||||
'native' => 'display_names_in_native_lang',
|
||||
'translated' => 'display_names_in_current_lang',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_LS_Slot_Factory
|
||||
*/
|
||||
private function get_slot_factory() {
|
||||
if ( ! $this->slot_factory ) {
|
||||
$this->slot_factory = new WPML_LS_Slot_Factory();
|
||||
}
|
||||
|
||||
return $this->slot_factory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Class WPML_LS_Shortcodes
|
||||
*/
|
||||
class WPML_LS_Shortcodes extends WPML_LS_Public_API {
|
||||
|
||||
public function init_hooks() {
|
||||
if ( $this->sitepress->get_setting( 'setup_complete' ) ) {
|
||||
add_shortcode( 'wpml_language_switcher', array( $this, 'callback' ) );
|
||||
|
||||
// Backward compatibility
|
||||
add_shortcode( 'wpml_language_selector_widget', array( $this, 'callback' ) );
|
||||
add_shortcode( 'wpml_language_selector_footer', array( $this, 'callback' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|string $args
|
||||
* @param string|null $content
|
||||
* @param string $tag
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function callback( $args, $content = null, $tag = '' ) {
|
||||
$args = (array) $args;
|
||||
$args = $this->parse_legacy_shortcodes( $args, $tag );
|
||||
$args = $this->convert_shortcode_args_aliases( $args );
|
||||
|
||||
return $this->render( $args, $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
* @param string $tag
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function parse_legacy_shortcodes( $args, $tag ) {
|
||||
if ( 'wpml_language_selector_widget' === $tag ) {
|
||||
$args['type'] = 'custom';
|
||||
} elseif ( 'wpml_language_selector_footer' === $tag ) {
|
||||
$args['type'] = 'footer';
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Footer_Slot extends WPML_LS_Slot {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_allowed_properties() {
|
||||
$allowed_properties = array(
|
||||
'template' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => $this->get_core_template( 'list-horizontal' ),
|
||||
),
|
||||
'slot_group' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'statics',
|
||||
),
|
||||
'slot_slug' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'footer',
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( parent::get_allowed_properties(), $allowed_properties );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Menu_Slot extends WPML_LS_Slot {
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_allowed_properties() {
|
||||
$allowed_properties = array(
|
||||
'position_in_menu' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'after',
|
||||
),
|
||||
'is_hierarchical' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 1,
|
||||
),
|
||||
'show' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 1,
|
||||
),
|
||||
'template' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => $this->get_core_template( 'menu-item' ),
|
||||
),
|
||||
'slot_group' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'menus',
|
||||
),
|
||||
'slot_slug' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( parent::get_allowed_properties(), $allowed_properties );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Post_Translations_Slot extends WPML_LS_Slot {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_allowed_properties() {
|
||||
$allowed_properties = array(
|
||||
'display_before_content' => array( 'type' => 'int', 'force_missing_to' => 0 ),
|
||||
'display_after_content' => array( 'type' => 'int', 'force_missing_to' => 0 ),
|
||||
'availability_text' => array( 'type' => 'string', 'stripslashes' => true ),
|
||||
'template' => array( 'type' => 'string', 'force_missing_to' => $this->get_core_template( 'post-translations' ) ),
|
||||
'slot_group' => array( 'type' => 'string', 'force_missing_to' => 'statics' ),
|
||||
'slot_slug' => array( 'type' => 'string', 'force_missing_to' => 'post_translations' ),
|
||||
);
|
||||
|
||||
return array_merge( parent::get_allowed_properties(), $allowed_properties );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Shortcode_Actions_Slot extends WPML_LS_Slot {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_allowed_properties() {
|
||||
$allowed_properties = array(
|
||||
'show' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'template' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => $this->get_core_template( 'list-horizontal' ),
|
||||
),
|
||||
'slot_group' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'statics',
|
||||
),
|
||||
'slot_slug' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'shortcode_actions',
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( parent::get_allowed_properties(), $allowed_properties );
|
||||
}
|
||||
|
||||
public function is_enabled() {
|
||||
/**
|
||||
* This filter allows to programmatically enable/disable the custom language switcher.
|
||||
*
|
||||
* @since 4.3.0
|
||||
*
|
||||
* @param bool The original status.
|
||||
*/
|
||||
return apply_filters( 'wpml_custom_language_switcher_is_enabled', parent::is_enabled() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Sidebar_Slot extends WPML_LS_Slot {
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_allowed_properties() {
|
||||
$allowed_properties = array(
|
||||
'widget_title' => array(
|
||||
'type' => 'string',
|
||||
'stripslashes' => true,
|
||||
),
|
||||
'show' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 1,
|
||||
),
|
||||
'template' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => $this->get_core_template( 'dropdown' ),
|
||||
),
|
||||
'slot_group' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => 'sidebars',
|
||||
),
|
||||
);
|
||||
|
||||
return array_merge( parent::get_allowed_properties(), $allowed_properties );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
class WPML_LS_Slot_Factory {
|
||||
|
||||
/**
|
||||
* @param array|WPML_LS_Slot $args
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
public function get_slot( $args ) {
|
||||
|
||||
if ( is_array( $args ) ) {
|
||||
|
||||
$args['slot_group'] = isset( $args['slot_group'] ) ? $args['slot_group'] : null;
|
||||
$args['slot_slug'] = isset( $args['slot_slug'] ) ? $args['slot_slug'] : null;
|
||||
$slot = new WPML_LS_Slot( $args );
|
||||
|
||||
switch ( $args['slot_group'] ) {
|
||||
case 'menus':
|
||||
$slot = new WPML_LS_Menu_Slot( $args );
|
||||
break;
|
||||
|
||||
case 'sidebars':
|
||||
$slot = new WPML_LS_Sidebar_Slot( $args );
|
||||
break;
|
||||
|
||||
case 'statics':
|
||||
switch ( $args['slot_slug'] ) {
|
||||
case 'footer':
|
||||
$slot = new WPML_LS_Footer_Slot( $args );
|
||||
break;
|
||||
|
||||
case 'post_translations':
|
||||
$slot = new WPML_LS_Post_Translations_Slot( $args );
|
||||
break;
|
||||
|
||||
case 'shortcode_actions':
|
||||
$slot = new WPML_LS_Shortcode_Actions_Slot( $args );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
$slot = $args;
|
||||
}
|
||||
|
||||
return $slot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slot_group
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_default_slot_arguments( $slot_group ) {
|
||||
$args = array(
|
||||
'slot_group' => $slot_group,
|
||||
'display_link_for_current_lang' => 1,
|
||||
'display_names_in_native_lang' => 1,
|
||||
'display_names_in_current_lang' => 1,
|
||||
);
|
||||
|
||||
if ( $slot_group === 'menus' ) {
|
||||
$args['template'] = $this->get_core_templates( 'menu-item' );
|
||||
$args['is_hierarchical'] = 1;
|
||||
} elseif ( $slot_group === 'sidebars' ) {
|
||||
$args['template'] = $this->get_core_templates( 'dropdown' );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slot_group
|
||||
*
|
||||
* @return WPML_LS_Slot
|
||||
*/
|
||||
public function get_default_slot( $slot_group ) {
|
||||
$slot_args = $this->get_default_slot_arguments( $slot_group );
|
||||
return $this->get_slot( $slot_args );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_core_templates( $slug ) {
|
||||
$parameters = WPML_Language_Switcher::parameters();
|
||||
$templates = isset( $parameters['core_templates'] ) ? $parameters['core_templates'] : array();
|
||||
return isset( $templates[ $slug ] ) ? $templates[ $slug ] : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_LS_Slot
|
||||
*/
|
||||
class WPML_LS_Slot {
|
||||
|
||||
/* @var array $properties */
|
||||
private $properties = array();
|
||||
|
||||
/* @var array $protected_properties */
|
||||
private $protected_properties = array(
|
||||
'slot_group',
|
||||
'slot_slug',
|
||||
);
|
||||
|
||||
/**
|
||||
* WPML_Language_Switcher_Slot constructor.
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( array $args = array() ) {
|
||||
$this->set_properties( $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get( $property ) {
|
||||
return isset( $this->properties[ $property ] ) ? $this->properties[ $property ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function set( $property, $value ) {
|
||||
if ( ! in_array( $property, $this->protected_properties ) ) {
|
||||
$allowed_properties = $this->get_allowed_properties();
|
||||
if ( array_key_exists( $property, $allowed_properties ) ) {
|
||||
$meta_data = $allowed_properties[ $property ];
|
||||
$this->properties[ $property ] = $this->sanitize( $value, $meta_data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string|null
|
||||
*/
|
||||
public function group() {
|
||||
return $this->get( 'slot_group' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|string|null
|
||||
*/
|
||||
public function slug() {
|
||||
return $this->get( 'slot_slug' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_menu() {
|
||||
return $this->group() === 'menus';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_sidebar() {
|
||||
return $this->group() === 'sidebars';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_footer() {
|
||||
return $this->group() === 'statics' && $this->slug() === 'footer';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_post_translations() {
|
||||
return $this->group() === 'statics' && $this->slug() === 'post_translations';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_shortcode_actions() {
|
||||
return $this->group() === 'statics' && $this->slug() === 'shortcode_actions';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
return $this->get( 'show' ) ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function template() {
|
||||
return $this->get( 'template' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function template_string() {
|
||||
return $this->get( 'template_string' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*/
|
||||
private function set_properties( array $args ) {
|
||||
foreach ( $this->get_allowed_properties() as $allowed_property => $meta_data ) {
|
||||
$value = null;
|
||||
if ( isset( $args[ $allowed_property ] ) ) {
|
||||
$value = $args[ $allowed_property ];
|
||||
} elseif ( isset( $meta_data['set_missing_to'] ) ) {
|
||||
$value = $meta_data['set_missing_to'];
|
||||
}
|
||||
$this->properties[ $allowed_property ] = $this->sanitize( $value, $meta_data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
protected function get_allowed_properties() {
|
||||
return array(
|
||||
'slot_group' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => '',
|
||||
),
|
||||
'slot_slug' => array(
|
||||
'type' => 'string',
|
||||
'force_missing_to' => '',
|
||||
),
|
||||
'show' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'template' => array( 'type' => 'string' ),
|
||||
'display_flags' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'display_link_for_current_lang' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'display_names_in_native_lang' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'display_names_in_current_lang' => array(
|
||||
'type' => 'int',
|
||||
'force_missing_to' => 0,
|
||||
),
|
||||
'include_flag_width' => array(
|
||||
'type' => 'int',
|
||||
'set_missing_to' => \WPML_LS_Settings::DEFAULT_FLAG_WIDTH,
|
||||
),
|
||||
'include_flag_height' => array(
|
||||
'type' => 'int',
|
||||
'set_missing_to' => \WPML_LS_Settings::DEFAULT_FLAG_HEIGHT,
|
||||
),
|
||||
// Colors
|
||||
'background_normal' => array( 'type' => 'string' ),
|
||||
'border_normal' => array( 'type' => 'string' ),
|
||||
'font_current_normal' => array( 'type' => 'string' ),
|
||||
'font_current_hover' => array( 'type' => 'string' ),
|
||||
'background_current_normal' => array( 'type' => 'string' ),
|
||||
'background_current_hover' => array( 'type' => 'string' ),
|
||||
'font_other_normal' => array( 'type' => 'string' ),
|
||||
'font_other_hover' => array( 'type' => 'string' ),
|
||||
'background_other_normal' => array( 'type' => 'string' ),
|
||||
'background_other_hover' => array( 'type' => 'string' ),
|
||||
'template_string' => array(
|
||||
'type' => 'string',
|
||||
'twig_string' => 1,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param array $meta_data
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function sanitize( $value, array $meta_data ) {
|
||||
if ( ! is_null( $value ) ) {
|
||||
switch ( $meta_data['type'] ) {
|
||||
case 'string':
|
||||
$value = (string) $value;
|
||||
if ( array_key_exists( 'stripslashes', $meta_data ) && $meta_data['stripslashes'] ) {
|
||||
$value = stripslashes( $value );
|
||||
}
|
||||
if ( array_key_exists( 'twig_string', $meta_data ) ) {
|
||||
$value = preg_replace( '/<br\W*?\/>/', '', $value );
|
||||
} else {
|
||||
$value = sanitize_text_field( $value );
|
||||
}
|
||||
break;
|
||||
case 'bool':
|
||||
$value = (bool) $value;
|
||||
break;
|
||||
case 'int':
|
||||
$value = (int) $value;
|
||||
break;
|
||||
}
|
||||
} elseif ( array_key_exists( 'force_missing_to', $meta_data ) ) {
|
||||
$value = $meta_data['force_missing_to'];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The use of a plain object does not work in Twig
|
||||
* e.g: slot_settings[ option.name ~ "_normal" ] (see in panel-colors.twig)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_model() {
|
||||
$model = array();
|
||||
|
||||
foreach ( $this->properties as $property => $value ) {
|
||||
$model[ $property ] = $value;
|
||||
}
|
||||
|
||||
return $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $slug
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
protected function get_core_template( $slug ) {
|
||||
$parameters = WPML_Language_Switcher::parameters();
|
||||
$core_templates = isset( $parameters['core_templates'] ) ? $parameters['core_templates'] : array();
|
||||
return isset( $core_templates[ $slug ] ) ? $core_templates[ $slug ] : null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user