PluginProbe
Polylang / 2.9.2
Polylang v2.9.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 2.9.2, at frontend/frontend-links.php

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