PluginProbe
Polylang / 3.3.2
Polylang v3.3.2
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 / frontend / frontend.php

frontend.php in Polylang 3.3.2, at frontend/frontend.php

269 lines 7.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 * Main Polylang class when on frontend, accessible from @see PLL().
8 *
9 * @since 1.2
10 */
11 class PLL_Frontend extends PLL_Base {
12 /**
13 * Current language.
14 *
15 * @var PLL_Language|null
16 */
17 public $curlang;
18
19 /**
20 * @var PLL_Frontend_Auto_Translate|null
21 */
22 public $auto_translate;
23
24 /**
25 * The class selecting the current language.
26 *
27 * @var PLL_Choose_Lang|null
28 */
29 public $choose_lang;
30
31 /**
32 * @var PLL_Frontend_Filters|null
33 */
34 public $filters;
35
36 /**
37 * @var PLL_Frontend_Filters_Links|null
38 */
39 public $filters_links;
40
41 /**
42 * @var PLL_Frontend_Filters_Search|null
43 */
44 public $filters_search;
45
46 /**
47 * @var PLL_Frontend_Links|null
48 */
49 public $links;
50
51 /**
52 * @var PLL_Frontend_Nav_Menu|null
53 */
54 public $nav_menu;
55
56 /**
57 * @var PLL_Frontend_Static_Pages|null
58 */
59 public $static_pages;
60
61 /**
62 * @var PLL_Frontend_Filters_Widgets|null
63 */
64 public $filters_widgets;
65
66 /**
67 * Constructor.
68 *
69 * @since 1.2
70 *
71 * @param PLL_Links_Model $links_model Reference to the links model.
72 */
73 public function __construct( &$links_model ) {
74 parent::__construct( $links_model );
75
76 add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ), 1 );
77
78 // Avoids the language being the queried object when querying multiple taxonomies
79 add_action( 'parse_tax_query', array( $this, 'parse_tax_query' ), 1 );
80
81 // Filters posts by language
82 add_action( 'parse_query', array( $this, 'parse_query' ), 6 );
83
84 // Not before 'check_canonical_url'
85 if ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) {
86 add_action( 'template_redirect', array( $this, 'auto_translate' ), 7 );
87 }
88
89 add_action( 'admin_bar_menu', array( $this, 'remove_customize_admin_bar' ), 41 ); // After WP_Admin_Bar::add_menus
90 }
91
92 /**
93 * Setups the language chooser based on options
94 *
95 * @since 1.2
96 */
97 public function init() {
98 parent::init();
99
100 $this->links = new PLL_Frontend_Links( $this );
101
102 // Static front page and page for posts
103 if ( 'page' === get_option( 'show_on_front' ) ) {
104 $this->static_pages = new PLL_Frontend_Static_Pages( $this );
105 }
106
107 // Setup the language chooser
108 $c = array( 'Content', 'Url', 'Url', 'Domain' );
109 $class = 'PLL_Choose_Lang_' . $c[ $this->options['force_lang'] ];
110 $this->choose_lang = new $class( $this );
111 $this->choose_lang->init();
112
113 // Need to load nav menu class early to correctly define the locations in the customizer when the language is set from the content
114 $this->nav_menu = new PLL_Frontend_Nav_Menu( $this );
115 }
116
117 /**
118 * Setups filters and nav menus once the language has been defined
119 *
120 * @since 1.2
121 *
122 * @return void
123 */
124 public function pll_language_defined() {
125 // Filters
126 $this->filters_links = new PLL_Frontend_Filters_Links( $this );
127 $this->filters = new PLL_Frontend_Filters( $this );
128 $this->filters_search = new PLL_Frontend_Filters_Search( $this );
129 $this->filters_widgets = new PLL_Frontend_Filters_Widgets( $this );
130
131 /*
132 * Redirects to canonical url before WordPress redirect_canonical
133 * but after Nextgen Gallery which hacks $_SERVER['REQUEST_URI'] !!!
134 * and restores it in 'template_redirect' with priority 1.
135 */
136 $this->canonical = new PLL_Canonical( $this );
137 add_action( 'template_redirect', array( $this->canonical, 'check_canonical_url' ), 4 );
138
139 // Auto translate for Ajax
140 if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
141 $this->auto_translate();
142 }
143 }
144
145 /**
146 * When querying multiple taxonomies, makes sure that the language is not the queried object.
147 *
148 * @since 1.8
149 *
150 * @param WP_Query $query WP_Query object.
151 * @return void
152 */
153 public function parse_tax_query( $query ) {
154 $pll_query = new PLL_Query( $query, $this->model );
155 $queried_taxonomies = $pll_query->get_queried_taxonomies();
156
157 if ( ! empty( $queried_taxonomies ) && 'language' == reset( $queried_taxonomies ) ) {
158 $query->tax_query->queried_terms['language'] = array_shift( $query->tax_query->queried_terms );
159 }
160 }
161
162 /**
163 * Modifies some query vars to "hide" that the language is a taxonomy and avoid conflicts.
164 *
165 * @since 1.2
166 *
167 * @param WP_Query $query WP_Query object.
168 * @return void
169 */
170 public function parse_query( $query ) {
171 $qv = $query->query_vars;
172 $pll_query = new PLL_Query( $query, $this->model );
173 $taxonomies = $pll_query->get_queried_taxonomies();
174
175 // Allow filtering recent posts and secondary queries by the current language
176 if ( ! empty( $this->curlang ) ) {
177 $pll_query->filter_query( $this->curlang );
178 }
179
180 // Modifies query vars when the language is queried
181 if ( ! empty( $qv['lang'] ) || ( ! empty( $taxonomies ) && array( 'language' ) == array_values( $taxonomies ) ) ) {
182 // Do we query a custom taxonomy?
183 $taxonomies = array_diff( $taxonomies, array( 'language', 'category', 'post_tag' ) );
184
185 // Remove pages query when the language is set unless we do a search
186 // Take care not to break the single page, attachment and taxonomies queries!
187 if ( empty( $qv['post_type'] ) && ! $query->is_search && ! $query->is_singular && empty( $taxonomies ) && ! $query->is_category && ! $query->is_tag ) {
188 $query->set( 'post_type', 'post' );
189 }
190
191 // Unset the is_archive flag for language pages to prevent loading the archive template
192 // Keep archive flag for comment feed otherwise the language filter does not work
193 if ( empty( $taxonomies ) && ! $query->is_comment_feed && ! $query->is_post_type_archive && ! $query->is_date && ! $query->is_author && ! $query->is_category && ! $query->is_tag ) {
194 $query->is_archive = false;
195 }
196
197 // Unset the is_tax flag except if another custom tax is queried
198 if ( empty( $taxonomies ) && ( $query->is_category || $query->is_tag || $query->is_author || $query->is_post_type_archive || $query->is_date || $query->is_search || $query->is_feed ) ) {
199 $query->is_tax = false;
200 unset( $query->queried_object ); // FIXME useless?
201 }
202 }
203 }
204
205 /**
206 * Auto translate posts and terms ids
207 *
208 * @since 1.2
209 *
210 * @return void
211 */
212 public function auto_translate() {
213 $this->auto_translate = new PLL_Frontend_Auto_Translate( $this );
214 }
215
216 /**
217 * Resets some variables when the blog is switched.
218 * Overrides the parent method.
219 *
220 * @since 1.5.1
221 *
222 * @param int $new_blog_id New blog ID.
223 * @param int $prev_blog_id Previous blog ID.
224 * @return void
225 */
226 public function switch_blog( $new_blog_id, $prev_blog_id ) {
227 parent::switch_blog( $new_blog_id, $prev_blog_id );
228
229 // Need to check that some languages are defined when user is logged in, has several blogs, some without any languages.
230 if ( $this->is_active_on_new_blog( $new_blog_id, $prev_blog_id ) && did_action( 'pll_language_defined' ) && $this->model->get_languages_list() ) {
231 static $restore_curlang;
232 if ( empty( $restore_curlang ) ) {
233 $restore_curlang = $this->curlang->slug; // To always remember the current language through blogs.
234 }
235
236 $lang = $this->model->get_language( $restore_curlang );
237 $this->curlang = $lang ? $lang : $this->model->get_language( $this->options['default_lang'] );
238
239 if ( isset( $this->static_pages ) ) {
240 $this->static_pages->init();
241 }
242
243 $this->load_strings_translations();
244 }
245 }
246
247 /**
248 * Remove the customize admin bar on front-end when using a block theme.
249 *
250 * WordPress removes the Customizer menu if a block theme is activated and no other plugins interact with it.
251 * As Polylang interacts with the Customizer, we have to delete this menu ourselves in the case of a block theme,
252 * unless another plugin than Polylang interacts with the Customizer.
253 *
254 * @since 3.2
255 *
256 * @return void
257 */
258 public function remove_customize_admin_bar() {
259 if ( ! $this->should_customize_menu_be_removed() ) {
260 return;
261 }
262
263 global $wp_admin_bar;
264
265 remove_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' ); // To avoid the script launch.
266 $wp_admin_bar->remove_menu( 'customize' );
267 }
268 }
269