PluginProbe
Polylang / 3.0.2
Polylang v3.0.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-links.php

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

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