PluginProbe
Polylang / 2.8
Polylang v2.8
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 / include / switcher.php

switcher.php in Polylang 2.8, at include/switcher.php

220 lines 8.8 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 /**
7 * A class to display a language switcher on frontend
8 *
9 * @since 1.2
10 */
11 class PLL_Switcher {
12
13 /**
14 * Returns options available for the language switcher - menu or widget
15 * either strings to display the options or default values
16 *
17 * @since 0.7
18 *
19 * @param string $type optional either 'menu', 'widget' or 'block', defaults to 'widget'
20 * @param string $key optional either 'string' or 'default', defaults to 'string'
21 * @return array list of switcher options strings or default values
22 */
23 public static function get_switcher_options( $type = 'widget', $key = 'string' ) {
24 $options = array(
25 'dropdown' => array( 'string' => __( 'Displays as a dropdown', 'polylang' ), 'default' => 0 ),
26 'show_names' => array( 'string' => __( 'Displays language names', 'polylang' ), 'default' => 1 ),
27 'show_flags' => array( 'string' => __( 'Displays flags', 'polylang' ), 'default' => 0 ),
28 'force_home' => array( 'string' => __( 'Forces link to front page', 'polylang' ), 'default' => 0 ),
29 'hide_current' => array( 'string' => __( 'Hides the current language', 'polylang' ), 'default' => 0 ),
30 'hide_if_no_translation' => array( 'string' => __( 'Hides languages with no translation', 'polylang' ), 'default' => 0 ),
31 );
32 return wp_list_pluck( $options, $key );
33 }
34
35 /**
36 * Get the language elements for use in a walker
37 *
38 * @see list of parameters accepted in $args documented for PLL_Switcher::the_languages
39 *
40 * @since 1.2
41 *
42 * @param object $links instance of PLL_Frontend_Links
43 * @param array $args
44 * @return array
45 */
46 protected function get_elements( $links, $args ) {
47 $first = true;
48 $out = array();
49
50 foreach ( $links->model->get_languages_list( array( 'hide_empty' => $args['hide_if_empty'] ) ) as $language ) {
51 $id = (int) $language->term_id;
52 $order = (int) $language->term_group;
53 $slug = $language->slug;
54 $locale = $language->get_locale( 'display' );
55 $classes = array( 'lang-item', 'lang-item-' . $id, 'lang-item-' . esc_attr( $slug ) );
56 $url = null; // Avoids potential notice
57 $curlang = 0 === $args['admin_render'] ? $links->curlang->slug : $args['admin_current_lang'];
58 $current_lang = $curlang == $slug;
59
60 if ( $current_lang ) {
61 if ( $args['hide_current'] && ! ( $args['dropdown'] && ! $args['raw'] ) ) {
62 continue; // Hide current language except for dropdown
63 } else {
64 $classes[] = 'current-lang';
65 }
66 }
67
68 if ( null !== $args['post_id'] && ( $tr_id = $links->model->post->get( $args['post_id'], $language ) ) && $links->model->post->current_user_can_read( $tr_id ) ) {
69 $url = get_permalink( $tr_id );
70 } elseif ( null === $args['post_id'] && 0 === $args['admin_render'] ) {
71 $url = $links->get_translation_url( $language );
72 }
73
74 if ( $no_translation = empty( $url ) ) {
75 $classes[] = 'no-translation';
76 }
77
78 /**
79 * Filter the link in the language switcher
80 *
81 * @since 0.7
82 *
83 * @param string $url the link
84 * @param string $slug language code
85 * @param string $locale language locale
86 */
87 $url = apply_filters( 'pll_the_language_link', $url, $slug, $language->locale );
88
89 // Hide if no translation exists
90 if ( empty( $url ) && $args['hide_if_no_translation'] ) {
91 continue;
92 }
93
94 $url = empty( $url ) || $args['force_home'] ? $links->get_home_url( $language ) : $url; // If the page is not translated, link to the home page
95
96 $name = $args['show_names'] || ! $args['show_flags'] || $args['raw'] ? ( 'slug' == $args['display_names_as'] ? $slug : $language->name ) : '';
97 $flag = $args['raw'] && ! $args['show_flags'] ? $language->get_display_flag_url() : ( $args['show_flags'] ? $language->get_display_flag() : '' );
98
99 if ( $first ) {
100 $classes[] = 'lang-item-first';
101 $first = false;
102 }
103
104 $out[ $slug ] = compact( 'id', 'order', 'slug', 'locale', 'name', 'url', 'flag', 'current_lang', 'no_translation', 'classes' );
105 }
106
107 return $out;
108 }
109
110 /**
111 * Displays a language switcher
112 * or returns the raw elements to build a custom language switcher
113 *
114 * List of parameters accepted in $args:
115 *
116 * dropdown => the list is displayed as dropdown if set, defaults to 0
117 * echo => echoes the list if set to 1, defaults to 1
118 * hide_if_empty => hides languages with no posts ( or pages ) if set to 1, defaults to 1
119 * show_flags => displays flags if set to 1, defaults to 0
120 * show_names => show language names if set to 1, defaults to 1
121 * display_names_as => whether to display the language name or its slug, valid options are 'slug' and 'name', defaults to name
122 * force_home => will always link to home in translated language if set to 1, defaults to 0
123 * hide_if_no_translation => hide the link if there is no translation if set to 1, defaults to 0
124 * hide_current => hide the current language if set to 1, defaults to 0
125 * post_id => returns links to translations of post defined by post_id if set, defaults not set
126 * raw => return a raw array instead of html markup if set to 1, defaults to 0
127 * item_spacing => whether to preserve or discard whitespace between list items, valid options are 'preserve' and 'discard', defaults to preserve
128 * admin_render => allows to force the current language code in an admin context if set, default to 0. Need to set the admin_current_lang argument below
129 * admin_current_lang => the current language code in an admin context. Need to set the admin_render to 1, defaults not set
130 *
131 * @since 0.1
132 *
133 * @param object $links instance of PLL_Frontend_Links
134 * @param array $args
135 * @return string|array either the html markup of the switcher or the raw elements to build a custom language switcher
136 */
137 public function the_languages( $links, $args = '' ) {
138 $defaults = array(
139 'dropdown' => 0, // display as list and not as dropdown
140 'echo' => 1, // echoes the list
141 'hide_if_empty' => 1, // hides languages with no posts ( or pages )
142 'menu' => 0, // not for nav menu ( this argument is deprecated since v1.1.1 )
143 'show_flags' => 0, // don't show flags
144 'show_names' => 1, // show language names
145 'display_names_as' => 'name', // valid options are slug and name
146 'force_home' => 0, // tries to find a translation
147 'hide_if_no_translation' => 0, // don't hide the link if there is no translation
148 'hide_current' => 0, // don't hide current language
149 'post_id' => null, // if not null, link to translations of post defined by post_id
150 'raw' => 0, // set this to true to build your own custom language switcher
151 'item_spacing' => 'preserve', // 'preserve' or 'discard' whitespace between list items
152 'admin_render' => 0, // make the switcher in an frontend context
153 'admin_current_lang' => null, // use when admin_render is set to 1, if not null use it instead of the current language
154 );
155 $args = wp_parse_args( $args, $defaults );
156
157 /**
158 * Filter the arguments of the 'pll_the_languages' template tag
159 *
160 * @since 1.5
161 *
162 * @param array $args
163 */
164 $args = apply_filters( 'pll_the_languages_args', $args );
165
166 // Prevents showing empty options in dropdown
167 if ( $args['dropdown'] ) {
168 $args['show_names'] = 1;
169 }
170
171 $elements = $this->get_elements( $links, $args );
172
173 if ( $args['raw'] ) {
174 return $elements;
175 }
176
177 if ( $args['dropdown'] ) {
178 $args['name'] = 'lang_choice_' . $args['dropdown'];
179 $walker = new PLL_Walker_Dropdown();
180 $args['selected'] = 0 === $args['admin_render'] ? $links->curlang->slug : $args['admin_current_lang'];
181 }
182 else {
183 $walker = new PLL_Walker_List();
184 }
185
186 /**
187 * Filter the whole html markup returned by the 'pll_the_languages' template tag
188 *
189 * @since 0.8
190 *
191 * @param string $html html returned/outputted by the template tag
192 * @param array $args arguments passed to the template tag
193 */
194 $out = apply_filters( 'pll_the_languages', $walker->walk( $elements, -1, $args ), $args );
195
196 // Javascript to switch the language when using a dropdown list
197 if ( $args['dropdown'] && 0 === $args['admin_render'] ) {
198 // Accept only few valid characters for the urls_x variable name ( as the widget id includes '-' which is invalid )
199 $out .= sprintf(
200 '<script type="text/javascript">
201 //<![CDATA[
202 var %1$s = %2$s;
203 document.getElementById( "%3$s" ).onchange = function() {
204 location.href = %1$s[this.value];
205 }
206 //]]>
207 </script>',
208 'urls_' . preg_replace( '#[^a-zA-Z0-9]#', '', $args['dropdown'] ),
209 wp_json_encode( wp_list_pluck( $elements, 'url' ) ),
210 esc_js( $args['name'] )
211 );
212 }
213
214 if ( $args['echo'] ) {
215 echo $out; // phpcs:ignore WordPress.Security.EscapeOutput
216 }
217 return $out;
218 }
219 }
220