PluginProbe
Polylang / 3.4
Polylang v3.4
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.4, at frontend/frontend.php

272 lines 7.9 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 // Static front page and page for posts.
92 // Early instantiated to be able to correctly initialize language properties.
93 if ( 'page' === get_option( 'show_on_front' ) ) {
94 $this->static_pages = new PLL_Frontend_Static_Pages( $this );
95 }
96
97 $this->model->set_languages_ready();
98 }
99
100 /**
101 * Setups the language chooser based on options
102 *
103 * @since 1.2
104 */
105 public function init() {
106 parent::init();
107
108 $this->links = new PLL_Frontend_Links( $this );
109
110 // Setup the language chooser
111 $c = array( 'Content', 'Url', 'Url', 'Domain' );
112 $class = 'PLL_Choose_Lang_' . $c[ $this->options['force_lang'] ];
113 $this->choose_lang = new $class( $this );
114 $this->choose_lang->init();
115
116 // Need to load nav menu class early to correctly define the locations in the customizer when the language is set from the content
117 $this->nav_menu = new PLL_Frontend_Nav_Menu( $this );
118 }
119
120 /**
121 * Setups filters and nav menus once the language has been defined
122 *
123 * @since 1.2
124 *
125 * @return void
126 */
127 public function pll_language_defined() {
128 // Filters
129 $this->filters_links = new PLL_Frontend_Filters_Links( $this );
130 $this->filters = new PLL_Frontend_Filters( $this );
131 $this->filters_search = new PLL_Frontend_Filters_Search( $this );
132 $this->filters_widgets = new PLL_Frontend_Filters_Widgets( $this );
133
134 /*
135 * Redirects to canonical url before WordPress redirect_canonical
136 * but after Nextgen Gallery which hacks $_SERVER['REQUEST_URI'] !!!
137 * and restores it in 'template_redirect' with priority 1.
138 */
139 $this->canonical = new PLL_Canonical( $this );
140 add_action( 'template_redirect', array( $this->canonical, 'check_canonical_url' ), 4 );
141
142 // Auto translate for Ajax
143 if ( ( ! defined( 'PLL_AUTO_TRANSLATE' ) || PLL_AUTO_TRANSLATE ) && wp_doing_ajax() ) {
144 $this->auto_translate();
145 }
146 }
147
148 /**
149 * When querying multiple taxonomies, makes sure that the language is not the queried object.
150 *
151 * @since 1.8
152 *
153 * @param WP_Query $query WP_Query object.
154 * @return void
155 */
156 public function parse_tax_query( $query ) {
157 $pll_query = new PLL_Query( $query, $this->model );
158 $queried_taxonomies = $pll_query->get_queried_taxonomies();
159
160 if ( ! empty( $queried_taxonomies ) && 'language' == reset( $queried_taxonomies ) ) {
161 $query->tax_query->queried_terms['language'] = array_shift( $query->tax_query->queried_terms );
162 }
163 }
164
165 /**
166 * Modifies some query vars to "hide" that the language is a taxonomy and avoid conflicts.
167 *
168 * @since 1.2
169 *
170 * @param WP_Query $query WP_Query object.
171 * @return void
172 */
173 public function parse_query( $query ) {
174 $qv = $query->query_vars;
175 $pll_query = new PLL_Query( $query, $this->model );
176 $taxonomies = $pll_query->get_queried_taxonomies();
177
178 // Allow filtering recent posts and secondary queries by the current language
179 if ( ! empty( $this->curlang ) ) {
180 $pll_query->filter_query( $this->curlang );
181 }
182
183 // Modifies query vars when the language is queried
184 if ( ! empty( $qv['lang'] ) || ( ! empty( $taxonomies ) && array( 'language' ) == array_values( $taxonomies ) ) ) {
185 // Do we query a custom taxonomy?
186 $taxonomies = array_diff( $taxonomies, array( 'language', 'category', 'post_tag' ) );
187
188 // Remove pages query when the language is set unless we do a search
189 // Take care not to break the single page, attachment and taxonomies queries!
190 if ( empty( $qv['post_type'] ) && ! $query->is_search && ! $query->is_singular && empty( $taxonomies ) && ! $query->is_category && ! $query->is_tag ) {
191 $query->set( 'post_type', 'post' );
192 }
193
194 // Unset the is_archive flag for language pages to prevent loading the archive template
195 // Keep archive flag for comment feed otherwise the language filter does not work
196 if ( empty( $taxonomies ) && ! $query->is_comment_feed && ! $query->is_post_type_archive && ! $query->is_date && ! $query->is_author && ! $query->is_category && ! $query->is_tag ) {
197 $query->is_archive = false;
198 }
199
200 // Unset the is_tax flag except if another custom tax is queried
201 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 ) ) {
202 $query->is_tax = false;
203 unset( $query->queried_object ); // FIXME useless?
204 }
205 }
206 }
207
208 /**
209 * Auto translate posts and terms ids
210 *
211 * @since 1.2
212 *
213 * @return void
214 */
215 public function auto_translate() {
216 $this->auto_translate = new PLL_Frontend_Auto_Translate( $this );
217 }
218
219 /**
220 * Resets some variables when the blog is switched.
221 * Overrides the parent method.
222 *
223 * @since 1.5.1
224 *
225 * @param int $new_blog_id New blog ID.
226 * @param int $prev_blog_id Previous blog ID.
227 * @return void
228 */
229 public function switch_blog( $new_blog_id, $prev_blog_id ) {
230 parent::switch_blog( $new_blog_id, $prev_blog_id );
231
232 // Need to check that some languages are defined when user is logged in, has several blogs, some without any languages.
233 if ( $this->is_active_on_new_blog( $new_blog_id, $prev_blog_id ) && did_action( 'pll_language_defined' ) && $this->model->has_languages() ) {
234 static $restore_curlang;
235 if ( empty( $restore_curlang ) ) {
236 $restore_curlang = $this->curlang->slug; // To always remember the current language through blogs.
237 }
238
239 $lang = $this->model->get_language( $restore_curlang );
240 $this->curlang = $lang ? $lang : $this->model->get_default_language();
241
242 if ( isset( $this->static_pages ) ) {
243 $this->static_pages->init();
244 }
245
246 $this->load_strings_translations();
247 }
248 }
249
250 /**
251 * Remove the customize admin bar on front-end when using a block theme.
252 *
253 * WordPress removes the Customizer menu if a block theme is activated and no other plugins interact with it.
254 * As Polylang interacts with the Customizer, we have to delete this menu ourselves in the case of a block theme,
255 * unless another plugin than Polylang interacts with the Customizer.
256 *
257 * @since 3.2
258 *
259 * @return void
260 */
261 public function remove_customize_admin_bar() {
262 if ( ! $this->should_customize_menu_be_removed() ) {
263 return;
264 }
265
266 global $wp_admin_bar;
267
268 remove_action( 'wp_before_admin_bar_render', 'wp_customize_support_script' ); // To avoid the script launch.
269 $wp_admin_bar->remove_menu( 'customize' );
270 }
271 }
272