PluginProbe
Polylang / 2.6.2
Polylang v2.6.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-static-pages.php

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

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