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 / Abstract_Block.php

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

214 lines 5.4 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;
7
8 use PLL_Language;
9 use WP_Block_Type_Registry;
10 use WP_HTML_Tag_Processor;
11
12 /**
13 * Abstract class for language switcher block.
14 *
15 * @since 3.2
16 * @since 3.8 Moved to Polylang Core and renamed to Language_Switcher\Abstract_Block.
17 */
18 abstract class Abstract_Block {
19 /**
20 * @var \PLL_Links
21 */
22 protected $links;
23
24 /**
25 * @var \PLL_Model
26 */
27 protected $model;
28
29 /**
30 * Current language.
31 *
32 * @var PLL_Language|false|null
33 */
34 private $current_language;
35
36 /**
37 * Constructor
38 *
39 * @since 2.8
40 *
41 * @param \PLL_Base $polylang Polylang object.
42 */
43 public function __construct( &$polylang ) {
44 $this->model = &$polylang->model;
45 $this->links = &$polylang->links;
46 $this->current_language = &$polylang->curlang;
47 }
48
49 /**
50 * Adds the required hooks.
51 *
52 * @since 3.2
53 *
54 * @return self
55 */
56 public function init() {
57 // Register language switcher block.
58 add_action( 'init', array( $this, 'register' ) );
59
60 return $this;
61 }
62
63 /**
64 * Returns the block name with the Polylang's namespace.
65 *
66 * @since 3.2
67 *
68 * @return string The block name.
69 */
70 abstract protected function get_block_name();
71
72 /**
73 * Renders the Polylang's block on server.
74 *
75 * @since 3.2
76 * @since 3.3 Accepts two new parameters, $content and $block.
77 *
78 * @param array $attributes The block attributes.
79 * @param string $content The saved content.
80 * @param \WP_Block $block The parsed block.
81 * @return string The HTML string output to serve.
82 */
83 abstract public function render( $attributes, $content, $block );
84
85 /**
86 * Returns the path to the block JSON file directory.
87 * The directory name being used to register a block.
88 *
89 * @since 3.8
90 *
91 * @return string The path to the block.
92 */
93 abstract protected function get_path(): string;
94
95 /**
96 * Registers the Polylang's block.
97 *
98 * @since 2.8
99 * @since 3.2 Renamed and now handle any type of block registration based on a dynamic name.
100 *
101 * @return void
102 */
103 public function register() {
104 if ( WP_Block_Type_Registry::get_instance()->is_registered( $this->get_block_name() ) ) {
105 // Don't register a block more than once or WordPress send an error. See https://github.com/WordPress/wordpress-develop/blob/5.9/src/wp-includes/class-wp-block-type-registry.php#L82-L90
106 return;
107 }
108
109 if ( ! register_block_type(
110 $this->get_path(),
111 array(
112 'render_callback' => array( $this, 'render' ),
113 )
114 ) ) {
115 return;
116 }
117
118 $script_handle = 'pll_blocks';
119 pll_register_script(
120 'blocks',
121 array(
122 'wp-block-editor',
123 'wp-blocks',
124 'wp-components',
125 'wp-element',
126 'wp-i18n',
127 ),
128 array(
129 'in_footer' => true,
130 ),
131 'pll_'
132 );
133
134 // Translated strings used in JS code
135 wp_set_script_translations( $script_handle, 'polylang' );
136
137 // Fallback to default language if current language is not set, usually happens in Site Editor.
138 $current_language = $this->current_language;
139
140 if ( ! $current_language ) {
141 $current_language = $this->model->get_default_language();
142 }
143
144 if ( ! $current_language ) {
145 // Should not happen since the module is loaded only if there are languages.
146 return;
147 }
148
149 if ( str_contains( wp_scripts()->get_inline_script_data( $script_handle, 'after' ), 'pllEditorCurrentLanguageSlug' ) ) {
150 return;
151 }
152
153 wp_add_inline_script(
154 $script_handle,
155 'let pllEditorCurrentLanguageSlug = ' . wp_json_encode( $current_language->slug ) . ';',
156 'after'
157 );
158 }
159
160 /**
161 * Applies flag block attributes to switcher markup.
162 *
163 * Uses WP_HTML_Tag_Processor so the dropdown SVG toggle can stay in the markup
164 * (WP_HTML_Processor aborts on foreign content).
165 *
166 * @since 3.9
167 *
168 * @param string $html Switcher HTML.
169 * @param array $attributes Block attributes.
170 * @return string
171 */
172 protected function apply_flag_styles_to_markup( string $html, array $attributes ): string {
173 if ( empty( $attributes['show_flags'] ) ) {
174 return $html;
175 }
176
177 $border_radius = max( 0, min( 100, (int) ( $attributes['flag_border_radius'] ?? 0 ) ) );
178 $flag_width = $attributes['flag_width'] ?? '18px';
179 $flag_style = safecss_filter_attr(
180 sprintf(
181 '--pll-flag-border-radius:%1$d;--pll-flag-width:%2$s',
182 $border_radius,
183 $flag_width
184 )
185 );
186
187 $label_style = '';
188 if ( ! empty( $attributes['show_labels'] ) ) {
189 $label_style = safecss_filter_attr(
190 sprintf(
191 '--pll-flag-label-spacing:%1$s',
192 $attributes['flag_label_spacing'] ?? '0.3em'
193 )
194 );
195 }
196
197 $processor = new WP_HTML_Tag_Processor( $html );
198
199 while ( $processor->next_tag( array( 'tag_name' => 'SPAN', 'class_name' => 'pll-switcher-flag' ) ) ) {
200 $style = $processor->get_attribute( 'style' ) ?? '';
201 /** @var string $style `WP_HTML_Tag_Processor::get_attribute()` returns string|null for non-boolean attributes. */
202 $processor->set_attribute( 'style', '' === $style ? $flag_style : rtrim( $style, ';' ) . ';' . $flag_style );
203
204 if ( '' !== $label_style && $processor->next_tag( array( 'tag_name' => 'SPAN', 'class_name' => 'pll-switcher-label' ) ) ) {
205 $style = $processor->get_attribute( 'style' ) ?? '';
206 /** @var string $style `WP_HTML_Tag_Processor::get_attribute()` returns string|null for non-boolean attributes. */
207 $processor->set_attribute( 'style', '' === $style ? $label_style : rtrim( $style, ';' ) . ';' . $label_style );
208 }
209 }
210
211 return $processor->get_updated_html();
212 }
213 }
214