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 / Switcher / Element / Abstract_Element.php

Abstract_Element.php in Polylang trunk, at src/Switcher/Element/Abstract_Element.php

318 lines 6.1 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\Switcher\Element;
7
8 use WP_Post;
9 use PLL_Links;
10 use PLL_Language;
11 use PLL_Frontend_Links;
12 use PLL_Translated_Post;
13 use WP_HTML_Tag_Processor;
14 use WP_Syntex\Polylang\Switcher\Settings\Settings;
15
16 defined( 'ABSPATH' ) || exit;
17
18 /**
19 * Data representing an item.
20 *
21 * @since 3.9
22 */
23 abstract class Abstract_Element {
24 /**
25 * @since 3.9
26 *
27 * @var int
28 */
29 public int $id;
30
31 /**
32 * @since 3.9
33 *
34 * @var string
35 *
36 * @phpstan-var non-empty-string
37 */
38 public string $slug;
39
40 /**
41 * @since 3.9
42 *
43 * @var string
44 *
45 * @phpstan-var non-empty-string
46 */
47 public string $locale;
48
49 /**
50 * @since 3.9
51 *
52 * @var string
53 */
54 public string $url = '';
55
56 /**
57 * @since 3.9
58 *
59 * @var string
60 */
61 public string $label = '';
62
63 /**
64 * @since 3.9
65 *
66 * @var string
67 */
68 public string $flag = '';
69
70 /**
71 * @since 3.9
72 *
73 * @var string
74 *
75 * @phpstan-var 'ltr'|'rtl'
76 */
77 public string $direction;
78
79 /**
80 * @since 3.9
81 *
82 * @var int
83 */
84 public int $order;
85
86 /**
87 * @since 3.9
88 *
89 * @var bool
90 */
91 public bool $has_translations;
92
93 /**
94 * @since 3.9
95 *
96 * @var bool
97 */
98 public bool $is_empty;
99
100 /**
101 * @since 3.9
102 *
103 * @var bool
104 */
105 public bool $is_current;
106
107 /**
108 * @since 3.9
109 *
110 * @var string[]
111 */
112 public array $item_classes;
113
114 /**
115 * @since 3.9
116 *
117 * @var string[]
118 */
119 public array $link_classes;
120
121 /**
122 * @var PLL_Language
123 */
124 private PLL_Language $language;
125
126 /**
127 * @var Settings
128 */
129 protected Settings $settings;
130
131 /**
132 * @var PLL_Links
133 */
134 private PLL_Links $links;
135
136 /**
137 * @var PLL_Translated_Post
138 */
139 private PLL_Translated_Post $post_model;
140
141 /**
142 * Constructor.
143 *
144 * @since 3.9
145 *
146 * @param PLL_Language $language Instance of `PLL_Language`.
147 * @param Settings $settings Instance of `Settings`.
148 * @param PLL_Links $links Instance of `PLL_Links`.
149 */
150 public function __construct( PLL_Language $language, Settings $settings, PLL_Links $links ) {
151 $this->language = $language;
152 $this->settings = $settings;
153 $this->links = $links;
154 $this->post_model = $links->model->post;
155
156 $this->id = (int) $language->term_id;
157 $this->slug = $language->slug;
158 $this->locale = $language->get_locale( 'display' );
159 $this->direction = $language->is_rtl ? 'rtl' : 'ltr';
160 $this->order = (int) $language->term_group;
161 $this->has_translations = true;
162 $this->is_empty = $language->get_tax_prop( 'language', 'count' ) <= 0;
163 $this->is_current = $this->get_current_language_slug() === $language->slug;
164 $this->item_classes = array_merge(
165 array( 'lang-item', "lang-item-{$language->term_id}", "lang-item-{$language->slug}" ),
166 $settings->item_classes
167 );
168 $this->link_classes = $settings->link_classes;
169
170 if ( $this->is_current ) {
171 $this->item_classes[] = 'current-lang';
172 }
173 if ( $this->settings->show_labels ) {
174 $this->label = 'codes' === $this->settings->show_labels ? strtoupper( $this->language->slug ) : $this->language->name;
175 }
176
177 $this->set_flag();
178 $this->set_url();
179 }
180
181 /**
182 * Returns the markup of a row.
183 *
184 * @since 3.9
185 *
186 * @return string
187 */
188 abstract public function get(): string;
189
190 /**
191 * Returns the markup of the label of a row.
192 *
193 * @since 3.9
194 *
195 * @return string
196 */
197 public function get_label(): string {
198 return esc_html( $this->label );
199 }
200
201 /**
202 * Returns the current language code.
203 *
204 * @since 3.9
205 *
206 * @return string
207 */
208 private function get_current_language_slug(): string {
209 if ( ! empty( $this->links->curlang ) ) {
210 return $this->links->curlang->slug;
211 }
212
213 return $this->links->options['default_lang'];
214 }
215
216 /**
217 * Sets the flag of the element.
218 *
219 * @since 3.9
220 *
221 * @return void
222 */
223 private function set_flag(): void {
224 if ( ! $this->settings->show_flags ) {
225 return;
226 }
227
228 $this->flag = $this->language->get_display_flag( $this->settings->show_labels ? 'no-alt' : 'alt' );
229
230 if ( empty( $this->flag ) ) {
231 return;
232 }
233
234 $flag = new WP_HTML_Tag_Processor( $this->flag );
235
236 if ( ! $flag->next_tag( array( 'tag_name' => 'img' ) ) ) {
237 return;
238 }
239
240 // Replaces the size set by `PLL_Language::get_flag_html()`. Keep in sync with `css/src/lib/switcher-flags.css`.
241 if ( ! $flag->set_attribute( 'style', 'display:block;object-fit:cover;object-position:center;width:100%;height:100%' ) ) {
242 return;
243 }
244
245 $this->flag = $flag->get_updated_html();
246 }
247
248 /**
249 * Sets the URL of the element.
250 *
251 * @since 3.9
252 *
253 * @return void
254 */
255 private function set_url(): void {
256 $url = $this->get_original_url();
257
258 if ( empty( $url ) ) {
259 $this->has_translations = false;
260 $this->item_classes[] = 'no-translation';
261 }
262
263 /**
264 * Filter the link in the language switcher.
265 *
266 * @since 0.7
267 * @since 3.9 Return an empty string instead of `null`.
268 *
269 * @param string $url The link URL, an empty string if no translation was found.
270 * @param string $slug The language code.
271 * @param string $locale The language locale.
272 */
273 $url = apply_filters( 'pll_the_language_link', $url, $this->language->slug, $this->language->locale );
274
275 if ( empty( $url ) || ! is_string( $url ) || $this->settings->force_home ) {
276 $this->url = $this->links->get_home_url( $this->language );
277 } else {
278 $this->url = $url;
279 }
280 }
281
282 /**
283 * Returns the original URL of the element.
284 *
285 * @since 3.9
286 *
287 * @return string
288 */
289 private function get_original_url(): string {
290 global $post;
291
292 // Priority to the post passed in parameters.
293 if ( $this->settings->post_id ) {
294 $tr_id = $this->post_model->get( $this->settings->post_id, $this->language );
295
296 if ( $tr_id && $this->post_model->current_user_can_read( $tr_id ) ) {
297 return (string) get_permalink( $tr_id );
298 }
299 }
300
301 // If we are on frontend.
302 if ( $this->links instanceof PLL_Frontend_Links ) {
303 return $this->links->get_translation_url( $this->language );
304 }
305
306 // For blocks in posts in REST requests.
307 if ( $post instanceof WP_Post ) {
308 $tr_id = $this->post_model->get( $post->ID, $this->language );
309
310 if ( $tr_id && $this->post_model->current_user_can_read( $tr_id ) ) {
311 return (string) get_permalink( $tr_id );
312 }
313 }
314
315 return '';
316 }
317 }
318