Files
doitinpoland.com/wp-content/plugins/sitepress-multilingual-cms/classes/language-switcher/class-wpml-ls-render.php
2023-09-12 21:41:04 +02:00

355 lines
9.3 KiB
PHP

<?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 );
}
}
}