PluginProbe
Polylang / 3.7.1
Polylang v3.7.1
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-links.php

frontend-links.php in Polylang 3.7.1, at frontend/frontend-links.php

229 lines 7.7 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 links filters and url of translations on frontend
8 *
9 * @since 1.2
10 */
11 class PLL_Frontend_Links extends PLL_Links {
12
13 /**
14 * Internal non persistent cache object.
15 *
16 * @var PLL_Cache<string>
17 */
18 public $cache;
19
20 /**
21 * Constructor
22 *
23 * @since 1.2
24 *
25 * @param object $polylang The Polylang object.
26 */
27 public function __construct( &$polylang ) {
28 parent::__construct( $polylang );
29
30 $this->curlang = &$polylang->curlang;
31 $this->cache = new PLL_Cache();
32 }
33
34 /**
35 * Returns the url of the translation (if it exists) of the current page.
36 *
37 * @since 0.1
38 *
39 * @param PLL_Language $language Language object.
40 * @return string
41 */
42 public function get_translation_url( $language ) {
43 global $wp_query;
44
45 if ( false !== $translation_url = $this->cache->get( 'translation_url:' . $language->slug ) ) {
46 return $translation_url;
47 }
48
49 // Make sure that we have the queried object
50 // See https://wordpress.org/support/topic/patch-for-fixing-a-notice
51 $queried_object_id = $wp_query->get_queried_object_id();
52
53 /**
54 * Filters the translation url before Polylang attempts to find one.
55 * Internally used by Polylang for the static front page and posts page.
56 *
57 * @since 1.8
58 *
59 * @param string $url Empty string or the url of the translation of the current page.
60 * @param PLL_Language $language Language of the translation.
61 * @param int $queried_object_id Queried object ID.
62 */
63 if ( ! $url = apply_filters( 'pll_pre_translation_url', '', $language, $queried_object_id ) ) {
64 $qv = $wp_query->query_vars;
65
66 // Post and attachment
67 if ( is_single() && ( $this->options['media_support'] || ! is_attachment() ) && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->model->post->current_user_can_read( $id ) ) {
68 $url = get_permalink( $id );
69 }
70
71 // Page
72 elseif ( is_page() && ( $id = $this->model->post->get( $queried_object_id, $language ) ) && $this->model->post->current_user_can_read( $id ) ) {
73 $url = get_page_link( $id );
74 }
75
76 elseif ( is_search() ) {
77 $url = $this->get_archive_url( $language );
78
79 // Special case for search filtered by translated taxonomies: taxonomy terms are translated in the translation url
80 if ( ! empty( $wp_query->tax_query->queries ) ) {
81 foreach ( $wp_query->tax_query->queries as $tax_query ) {
82 if ( ! empty( $tax_query['taxonomy'] ) && $this->model->is_translated_taxonomy( $tax_query['taxonomy'] ) ) {
83
84 $tax = get_taxonomy( $tax_query['taxonomy'] );
85 $terms = get_terms( array( 'taxonomy' => $tax->name, 'fields' => 'id=>slug' ) ); // Filtered by current language
86
87 foreach ( $tax_query['terms'] as $slug ) {
88 $term_id = array_search( $slug, $terms ); // What is the term_id corresponding to taxonomy term?
89 if ( $term_id && $term_id = $this->model->term->get_translation( $term_id, $language ) ) { // Get the translated term_id
90 $term = get_term( $term_id, $tax->name );
91
92 if ( ! $term instanceof WP_Term ) {
93 continue;
94 }
95
96 $url = str_replace( $slug, $term->slug, $url );
97 }
98 }
99 }
100 }
101 }
102 }
103
104 // Translated taxonomy
105 // Take care that is_tax() is false for categories and tags
106 elseif ( ( is_category() || is_tag() || is_tax() ) && ( $term = get_queried_object() ) && $this->model->is_translated_taxonomy( $term->taxonomy ) ) {
107 $lang = $this->model->term->get_language( $term->term_id );
108
109 if ( ! $lang || $language->slug == $lang->slug ) {
110 $url = get_term_link( $term, $term->taxonomy ); // Self link
111 }
112
113 elseif ( $tr_id = $this->model->term->get_translation( $term->term_id, $language ) ) {
114 $tr_term = get_term( $tr_id, $term->taxonomy );
115 if ( $tr_term instanceof WP_Term ) {
116 // Check if translated term ( or children ) have posts
117 $count = $tr_term->count || ( is_taxonomy_hierarchical( $term->taxonomy ) && array_sum( wp_list_pluck( get_terms( array( 'taxonomy' => $term->taxonomy, 'child_of' => $tr_term->term_id, 'lang' => $language->slug ) ), 'count' ) ) );
118
119 /**
120 * Filter whether to hide an archive translation url
121 *
122 * @since 2.2.4
123 *
124 * @param bool $hide True to hide the translation url.
125 * defaults to true when the translated archive is empty, false otherwise.
126 * @param string $lang The language code of the translation
127 * @param array $args Arguments used to evaluated the number of posts in the archive
128 */
129 if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, array( 'taxonomy' => $term->taxonomy ) ) ) {
130 $url = get_term_link( $tr_term, $term->taxonomy );
131 }
132 }
133 }
134 }
135
136 // Post type archive
137 elseif ( is_post_type_archive() ) {
138 if ( $this->model->is_translated_post_type( $qv['post_type'] ) ) {
139 $args = array( 'post_type' => $qv['post_type'] );
140 $count = $this->model->count_posts( $language, $args );
141
142 /** This filter is documented in frontend/frontend-links.php */
143 if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, $args ) ) {
144 $url = $this->get_archive_url( $language );
145 }
146 }
147 }
148
149 // Other archives
150 elseif ( is_archive() ) {
151 $keys = array( 'post_type', 'm', 'year', 'monthnum', 'day', 'author', 'author_name' );
152 $keys = array_merge( $keys, $this->model->get_filtered_taxonomies_query_vars() );
153 $args = array_intersect_key( $qv, array_flip( $keys ) );
154 $count = $this->model->count_posts( $language, $args );
155
156 /** This filter is documented in frontend/frontend-links.php */
157 if ( ! apply_filters( 'pll_hide_archive_translation_url', ! $count, $language->slug, $args ) ) {
158 $url = $this->get_archive_url( $language );
159 }
160 }
161
162 // Front page when it is the list of posts
163 elseif ( is_front_page() ) {
164 $url = $this->get_home_url( $language );
165 }
166 }
167
168 $url = ! empty( $url ) && ! is_wp_error( $url ) ? $url : null;
169
170 /**
171 * Filter the translation url of the current page before Polylang caches it
172 *
173 * @since 1.1.2
174 *
175 * @param null|string $url The translation url, null if none was found
176 * @param string $language The language code of the translation
177 */
178 $translation_url = (string) apply_filters( 'pll_translation_url', $url, $language->slug );
179
180 // Don't cache before template_redirect to avoid a conflict with Barrel + WP Bakery Page Builder
181 if ( did_action( 'template_redirect' ) ) {
182 $this->cache->set( 'translation_url:' . $language->slug, $translation_url );
183 }
184
185 return $translation_url;
186 }
187
188 /**
189 * Get the translation of the current archive url
190 * used also for search
191 *
192 * @since 1.2
193 *
194 * @param PLL_Language $language An object representing a language.
195 * @return string
196 */
197 public function get_archive_url( $language ) {
198 $url = pll_get_requested_url();
199 $url = $this->links_model->switch_language_in_link( $url, $language );
200 $url = $this->links_model->remove_paged_from_link( $url );
201
202 /**
203 * Filter the archive url
204 *
205 * @since 1.6
206 *
207 * @param string $url Url of the archive
208 * @param object $language Language of the archive
209 */
210 return apply_filters( 'pll_get_archive_url', $url, $language );
211 }
212
213 /**
214 * Returns the home url in the right language.
215 *
216 * @since 0.1
217 *
218 * @param PLL_Language|string $language Optional, defaults to current language.
219 * @param bool $is_search Optional, whether we need the home url for a search form, defaults to false.
220 */
221 public function get_home_url( $language = '', $is_search = false ) {
222 if ( empty( $language ) ) {
223 $language = $this->curlang;
224 }
225
226 return parent::get_home_url( $language, $is_search );
227 }
228 }
229