PluginProbe
Polylang / trunk
Polylang vtrunk
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
polylang / src / modules / Blocks / Language_Switcher / Standard / Block.php

Block.php in Polylang trunk, at src/modules/Blocks/Language_Switcher/Standard/Block.php

184 lines 5.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package Polylang
4 */
5
6 namespace WP_Syntex\Polylang\Blocks\Language_Switcher\Standard;
7
8 use WP_Syntex\Polylang\Switcher\Assets;
9 use WP_Syntex\Polylang\Switcher\Switcher;
10 use WP_Syntex\Polylang\Switcher\Settings\Settings;
11 use WP_Syntex\Polylang\Blocks\Language_Switcher\Abstract_Block;
12
13 /**
14 * Language switcher block.
15 *
16 * @since 2.8
17 * @since 3.2 Extends now the PLL_Abstract_Language_Switcher_Block abstract class.
18 * @since 3.8 Moved to Polylang Core and renamed to Language_Switcher\Standard\Block.
19 */
20 class Block extends Abstract_Block {
21 /**
22 * Adds the required hooks.
23 *
24 * @since 3.9
25 *
26 * @return self
27 */
28 public function init() {
29 parent::init();
30
31 add_action( 'init', array( $this, 'register_styles' ) );
32 add_action( 'init', array( Assets::class, 'register_scripts' ) );
33
34 return $this;
35 }
36
37 /**
38 * Registers the styles for the language switcher block.
39 *
40 * @since 3.9
41 *
42 * @return void
43 */
44 public function register_styles(): void {
45 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
46
47 Assets::register_styles();
48 wp_register_style(
49 'pll-language-switcher-editor', // Matches `block.json`'s `editorStyle` handle.
50 plugins_url( "/css/build/language-switcher-editor{$suffix}.css", POLYLANG_ROOT_FILE ),
51 array( ASSETS::FRONTEND_ASSET_HANDLE ),
52 POLYLANG_VERSION
53 );
54 }
55
56 /**
57 * Returns the language switcher block name with the Polylang's namespace.
58 *
59 * @since 3.2
60 *
61 * @return string The block name.
62 */
63 protected function get_block_name() {
64 return 'polylang/language-switcher';
65 }
66
67 /**
68 * Renders the `polylang/language-switcher` block on server.
69 *
70 * @since 2.8
71 * @since 3.2 Renamed according to its parent abstract class.
72 * @since 3.3 Accepts two new parameters, $content and $block.
73 *
74 * @param array $attributes The block attributes.
75 * @param string $content The saved content. Unused.
76 * @param \WP_Block $block The parsed block. Unused.
77 * @return string Returns the language switcher.
78 */
79 public function render( $attributes, $content, $block ) { //phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
80 static $dropdown_id = 0;
81 ++$dropdown_id;
82
83 $attributes['unique_id'] = 'select' === $attributes['layout'] ? 'lang_choice_' . $dropdown_id : '';
84 $attributes['show_wrapper'] = true; // Blocks always display a wrapper. Legacy `dropdown` attributes would otherwise set it to false.
85
86 if ( ! empty( $attributes['style']['typography']['textAlign'] ) ) {
87 $attributes['alignment'] = $attributes['style']['typography']['textAlign'];
88 }
89
90 $settings = new Settings( $attributes );
91 $switcher_output = ( new Switcher( $settings, $this->links ) )->get();
92
93 if ( empty( $switcher_output ) ) {
94 return '';
95 }
96
97 $switcher_output = $this->apply_flag_styles_to_markup( $switcher_output, $attributes );
98
99 return $this->apply_block_wrapper_attributes(
100 $switcher_output,
101 get_block_wrapper_attributes()
102 );
103 }
104
105 /**
106 * Returns the path to the block JSON file directory.
107 * The directory name being used to register a block.
108 *
109 * @since 3.8
110 *
111 * @return string The path to the block.
112 */
113 protected function get_path(): string {
114 return __DIR__;
115 }
116
117 /**
118 * Merges block wrapper attributes onto the switcher root element.
119 *
120 * Block supports (background, spacing, etc.) must apply to the switcher
121 * wrapper itself — not to an extra full-width `<div>` around it.
122 *
123 * @since 3.9
124 *
125 * @param string $html Switcher HTML.
126 * @param string $wrapper_attributes Attributes from `get_block_wrapper_attributes()`.
127 * @return string
128 */
129 private function apply_block_wrapper_attributes( string $html, string $wrapper_attributes ): string {
130 if ( '' === trim( $wrapper_attributes ) ) {
131 return $html;
132 }
133
134 $processor = new \WP_HTML_Tag_Processor( $html );
135
136 if ( ! $processor->next_tag() ) {
137 return sprintf( '<div %1$s>%2$s</div>', $wrapper_attributes, $html );
138 }
139
140 foreach ( $this->parse_html_attributes( $wrapper_attributes ) as $name => $value ) {
141 if ( 'class' === $name ) {
142 $existing = $processor->get_attribute( 'class' ) ?? '';
143 $value = trim( $existing . ' ' . $value );
144 } elseif ( 'style' === $name ) {
145 $existing = $processor->get_attribute( 'style' ) ?? '';
146 /** @var string $existing `WP_HTML_Tag_Processor::get_attribute()` returns string|null for non-boolean attributes */
147 $value = '' === $existing ? $value : rtrim( $existing, ';' ) . ';' . $value;
148 }
149
150 $processor->set_attribute( $name, $value );
151 }
152
153 return $processor->get_updated_html();
154 }
155
156 /**
157 * Parses an HTML attributes string.
158 *
159 * @since 3.9
160 *
161 * @param string $attributes_string HTML attributes.
162 * @return array<string, string>
163 */
164 private function parse_html_attributes( string $attributes_string ): array {
165 $attributes = array();
166 $processor = new \WP_HTML_Tag_Processor( '<div ' . $attributes_string . '></div>' );
167
168 if ( ! $processor->next_tag() ) {
169 return $attributes;
170 }
171
172 foreach ( array( 'class', 'style', 'id' ) as $name ) {
173 /** @var string|null $value `WP_HTML_Tag_Processor::get_attribute()` returns string|null for non-boolean attributes */
174 $value = $processor->get_attribute( $name );
175
176 if ( null !== $value && '' !== $value ) {
177 $attributes[ $name ] = $value;
178 }
179 }
180
181 return $attributes;
182 }
183 }
184