* @phpstan-template T of array */ class Languages extends WP_Widget { /** * @var PLL_Links|null */ private ?PLL_Links $links; /** * Constructor. * * @since 3.9 * * @param PLL_Base $polylang The Polylang object. */ public function __construct( PLL_Base &$polylang ) { $this->links = &$polylang->links; parent::__construct( 'polylang', __( 'Language switcher', 'polylang' ), array( 'description' => __( 'Displays a language switcher', 'polylang' ), 'customize_selective_refresh' => true, ) ); if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) { add_action( 'wp_enqueue_scripts', array( Assets::class, 'enqueue_frontend_styles' ) ); } add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'filter_legacy_widgets' ) ); } /** * Hides this legacy widget in the block widgets screen. * * @since 3.9 * * @param array $widget_ids An array of hidden widget ids. * @return array */ public function filter_legacy_widgets( $widget_ids ) { return array_merge( $widget_ids, array( $this->id_base ) ); } /** * Displays the widget. * * @since 3.9 * * @param array $args Arguments, including `before_title`, `after_title`, `before_widget`, and `after_widget`. * @param array $instance The settings for the particular instance of the widget. * @return void * * @phpstan-param array{ * name: string, * id: string, * description: string, * class: string, * before_widget: string, * after_widget: string, * before_title: string, * after_title: string, * before_sidebar: string, * after_sidebar: string, * show_in_rest: boolean, * widget_id: string, * widget_name: string * } $args * @phpstan-param NewInstance|OldInstance $instance */ public function widget( $args, $instance ): void { if ( empty( $this->links ) ) { return; } $instance['unique_id'] = "pll-switcher-widget-{$this->number}"; $instance = Fields::remove_legacy_settings( $instance ); $settings = new Settings( $instance ); $list = ( new Switcher( $settings, $this->links ) )->get(); if ( empty( $list ) ) { return; } echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */ $title = apply_filters( 'widget_title', $instance['title'] ?? '', $instance, $this->id_base ); if ( ! empty( $title ) ) { echo $args['before_title'] . $title . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput } echo $list; // phpcs:ignore WordPress.Security.EscapeOutput echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput } /** * Updates the widget options. * * @since 3.9 * * @param array $new_instance New settings for this instance as input by the user via `form()`. * @param array $old_instance Old settings for this instance. * @return array|bool Settings to save or bool false to cancel saving. * * @phpstan-param NewInstance $new_instance * @phpstan-param OldInstance $old_instance */ public function update( $new_instance, $old_instance ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable $validated = Fields::filter( new Settings( $new_instance ) ); $validated = Fields::add_legacy_settings( $validated ); $validated['title'] = ! empty( $new_instance['title'] ) && is_string( $new_instance['title'] ) ? sanitize_text_field( $new_instance['title'] ) : ''; return $validated; } /** * Displays the widget form. * * @since 3.9 * * @param array $instance Current settings. * @return null * * @phpstan-param NewInstance|OldInstance $instance */ public function form( $instance ) { $settings = new Settings( Fields::remove_legacy_settings( $instance ) ); $title = ! empty( $instance['title'] ) && is_string( $instance['title'] ) ? $instance['title'] : ''; // Title. printf( '
', esc_attr( $this->get_field_id( 'title' ) ), esc_html__( 'Title:', 'polylang' ), esc_attr( $this->get_field_name( 'title' ) ), esc_attr( $title ) ); echo '