PluginProbe
Polylang / 3.1.4
Polylang v3.1.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-static-pages.php

frontend-static-pages.php in Polylang 3.1.4, at frontend/frontend-static-pages.php

285 lines 9.3 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 * Manages the static front page and the page for posts on frontend
8 *
9 * @since 1.8
10 */
11 class PLL_Frontend_Static_Pages extends PLL_Static_Pages {
12 /**
13 * Instance of a child class of PLL_Links_Model.
14 *
15 * @var PLL_Links_Model
16 */
17 protected $links_model;
18
19 /**
20 * @var PLL_Frontend_Links
21 */
22 protected $links;
23
24 /**
25 * Constructor: setups filters and actions
26 *
27 * @since 1.8
28 *
29 * @param object $polylang
30 */
31 public function __construct( &$polylang ) {
32 parent::__construct( $polylang );
33
34 $this->links_model = &$polylang->links_model;
35 $this->links = &$polylang->links;
36
37 add_action( 'pll_language_defined', array( $this, 'pll_language_defined' ) );
38 add_action( 'pll_home_requested', array( $this, 'pll_home_requested' ) );
39
40 // Manages the redirection of the homepage
41 add_filter( 'redirect_canonical', array( $this, 'redirect_canonical' ) );
42
43 add_filter( 'pll_pre_translation_url', array( $this, 'pll_pre_translation_url' ), 10, 3 );
44 add_filter( 'pll_check_canonical_url', array( $this, 'pll_check_canonical_url' ) );
45
46 add_filter( 'pll_set_language_from_query', array( $this, 'page_on_front_query' ), 10, 2 );
47 add_filter( 'pll_set_language_from_query', array( $this, 'page_for_posts_query' ), 10, 2 );
48 }
49
50 /**
51 * Init the filters
52 *
53 * @since 1.8
54 *
55 * @return void
56 */
57 public function pll_language_defined() {
58 // Translates our page on front and page for posts properties
59 $this->init();
60
61 // Translates page for posts and page on front
62 add_filter( 'option_page_on_front', array( $this, 'translate_page_on_front' ) );
63 add_filter( 'option_page_for_posts', array( $this, 'translate_page_for_posts' ) );
64
65 // Support theme customizer
66 if ( isset( $_POST['wp_customize'], $_POST['customized'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification
67 add_filter( 'pre_option_page_on_front', 'pll_get_post', 20 );
68 add_filter( 'pre_option_page_for_post', 'pll_get_post', 20 );
69 }
70 }
71
72 /**
73 * Translates the page_id query var when the site root page is requested
74 *
75 * @since 1.8
76 *
77 * @return void
78 */
79 public function pll_home_requested() {
80 set_query_var( 'page_id', $this->curlang->page_on_front );
81 }
82
83 /**
84 * Translates page on front
85 *
86 * @since 1.8
87 *
88 * @param int $v page on front page id
89 * @return int
90 */
91 public function translate_page_on_front( $v ) {
92 // Don't attempt to translate in a 'switch_blog' action as there is a risk to call this function while initializing the languages cache
93 return isset( $this->curlang->page_on_front ) && ( $this->curlang->page_on_front ) && ! doing_action( 'switch_blog' ) ? $this->curlang->page_on_front : $v;
94 }
95
96 /**
97 * Manages canonical redirection of the homepage when using page on front
98 *
99 * @since 0.1
100 *
101 * @param string $redirect_url
102 * @return bool|string modified url, false if redirection is canceled
103 */
104 public function redirect_canonical( $redirect_url ) {
105 if ( is_page() && ! is_feed() && get_queried_object_id() == $this->curlang->page_on_front ) {
106 $url = is_paged() ? $this->links_model->add_paged_to_link( $this->links->get_home_url(), get_query_var( 'page' ) ) : $this->links->get_home_url();
107
108 // Don't forget additional query vars
109 $query = wp_parse_url( $redirect_url, PHP_URL_QUERY );
110 if ( ! empty( $query ) ) {
111 parse_str( $query, $query_vars );
112 $query_vars = rawurlencode_deep( $query_vars ); // WP encodes query vars values
113 $url = add_query_arg( $query_vars, $url );
114 }
115
116 return $url;
117 }
118
119 return $redirect_url;
120 }
121
122 /**
123 * Translates the url of the page on front and page for posts.
124 *
125 * @since 1.8
126 *
127 * @param string $url Not used.
128 * @param PLL_Language $language Language in which we want the translation.
129 * @param int $queried_object_id Id of the queried object.
130 * @return string The translation url.
131 */
132 public function pll_pre_translation_url( $url, $language, $queried_object_id ) {
133 if ( ! empty( $queried_object_id ) ) {
134 // Page for posts
135 if ( $GLOBALS['wp_query']->is_posts_page && ( $id = $this->model->post->get( $queried_object_id, $language ) ) ) {
136 $url = get_permalink( $id );
137 }
138
139 // Page on front
140 elseif ( is_front_page() && $language->page_on_front && ( $language->page_on_front == $this->model->post->get( $queried_object_id, $language ) ) ) {
141 $url = $language->home_url;
142 }
143 }
144
145 return $url;
146 }
147
148 /**
149 * Prevents canonical redirection if we are on a static front page
150 *
151 * @since 1.8
152 *
153 * @param string $redirect_url
154 * @return bool|string
155 */
156 public function pll_check_canonical_url( $redirect_url ) {
157 return $this->options['redirect_lang'] && ! $this->options['force_lang'] && ! empty( $this->curlang->page_on_front ) && is_page( $this->curlang->page_on_front ) ? false : $redirect_url;
158 }
159
160 /**
161 * Is the query for a the static front page (redirected from the language page)?
162 *
163 * @since 2.3
164 *
165 * @param WP_Query $query The WP_Query object.
166 * @return bool
167 */
168 protected function is_front_page( $query ) {
169 $query = array_diff( array_keys( $query->query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) );
170 return 1 === count( $query ) && in_array( 'lang', $query );
171 }
172
173 /**
174 * Setups query vars when requesting a static front page
175 *
176 * @since 1.8
177 *
178 * @param PLL_Language|false $lang The current language, false if it is not set yet.
179 * @param WP_Query $query The main WP query.
180 * @return PLL_Language|false
181 */
182 public function page_on_front_query( $lang, $query ) {
183 if ( ! empty( $lang ) || ! $this->page_on_front ) {
184 return $lang;
185 }
186
187 // The home page is requested
188 if ( did_action( 'home_requested' ) ) {
189 $query->set( 'page_id', $lang->page_on_front );
190 }
191
192 // Redirect the language page to the homepage when using a static front page
193 elseif ( ( $this->options['redirect_lang'] || $this->options['hide_default'] ) && $this->is_front_page( $query ) && $lang = $this->model->get_language( get_query_var( 'lang' ) ) ) {
194 $query->is_archive = $query->is_tax = false;
195 if ( ! empty( $lang->page_on_front ) ) {
196 $query->set( 'page_id', $lang->page_on_front );
197 $query->is_singular = $query->is_page = true;
198 unset( $query->query_vars['lang'], $query->queried_object ); // Reset queried object
199 } else {
200 // Handle case where the static front page hasn't be translated to avoid a possible infinite redirect loop.
201 $query->is_home = true;
202 }
203 }
204
205 // Fix paged static front page in plain permalinks when Settings > Reading doesn't match the default language
206 elseif ( ! $this->links_model->using_permalinks && count( $query->query ) === 1 && ! empty( $query->query['page'] ) ) {
207 $lang = $this->model->get_language( $this->options['default_lang'] );
208 $query->set( 'page_id', $lang->page_on_front );
209 $query->is_singular = $query->is_page = true;
210 $query->is_archive = $query->is_tax = false;
211 unset( $query->query_vars['lang'], $query->queried_object ); // Reset queried object
212 }
213
214 // Set the language when requesting a static front page
215 else {
216 $page_id = $this->get_page_id( $query );
217 $languages = $this->model->get_languages_list();
218 $pages = wp_list_pluck( $languages, 'page_on_front' );
219
220 if ( ! empty( $page_id ) && false !== $n = array_search( $page_id, $pages ) ) {
221 $lang = $languages[ $n ];
222 }
223 }
224
225 // Fix <!--nextpage--> for page_on_front
226 if ( ( $this->options['force_lang'] < 2 || ! $this->options['redirect_lang'] ) && $this->links_model->using_permalinks && ! empty( $lang ) && isset( $query->query['paged'] ) ) {
227 $query->set( 'page', $query->query['paged'] );
228 unset( $query->query['paged'] );
229 } elseif ( ! $this->links_model->using_permalinks && ! empty( $query->query['page'] ) ) {
230 $query->is_paged = true;
231 }
232
233 return $lang;
234 }
235
236 /**
237 * Setups query vars when requesting a posts page
238 *
239 * @since 1.8
240 *
241 * @param PLL_Language|false $lang The current language, false if it is not set yet.
242 * @param WP_Query $query The main WP query.
243 * @return PLL_Language|false
244 */
245 public function page_for_posts_query( $lang, $query ) {
246 if ( empty( $lang ) && $this->page_for_posts ) {
247 $page_id = $this->get_page_id( $query );
248
249 if ( ! empty( $page_id ) && in_array( $page_id, $pages = $this->model->get_languages_list( array( 'fields' => 'page_for_posts' ) ) ) ) {
250 // Fill the cache with all pages for posts to avoid one query per page later
251 // The posts_per_page limit is a trick to avoid splitting the query
252 get_posts( array( 'posts_per_page' => 999, 'post_type' => 'page', 'post__in' => $pages, 'lang' => '' ) );
253
254 $lang = $this->model->post->get_language( $page_id );
255 $query->is_singular = $query->is_page = false;
256 $query->is_home = $query->is_posts_page = true;
257 }
258 }
259 return $lang;
260 }
261
262 /**
263 * Get the queried page_id (if it exists ).
264 *
265 * If permalinks are used, WordPress does set and use `$query->queried_object_id` and sets `$query->query_vars['page_id']` to 0,
266 * and does set and use `$query->query_vars['page_id']` if permalinks are not used :(.
267 *
268 * @since 1.5
269 *
270 * @param WP_Query $query Instance of WP_Query.
271 * @return int The page_id.
272 */
273 protected function get_page_id( $query ) {
274 if ( ! empty( $query->query_vars['pagename'] ) && isset( $query->queried_object_id ) ) {
275 return $query->queried_object_id;
276 }
277
278 if ( isset( $query->query_vars['page_id'] ) ) {
279 return $query->query_vars['page_id'];
280 }
281
282 return 0; // No page queried.
283 }
284 }
285