PluginProbe
Polylang / 2.0.3
Polylang v2.0.3
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 / include / links-directory.php

links-directory.php in Polylang 2.0.3, at include/links-directory.php

251 lines 8.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Links model for use when the language code is added in url as a directory
5 * for example mysite.com/en/something
6 * implements the "links_model interface"
7 *
8 * @since 1.2
9 */
10 class PLL_Links_Directory extends PLL_Links_Permalinks {
11
12 /**
13 * Constructor
14 *
15 * @since 1.2
16 *
17 * @param object $model PLL_Model instance
18 */
19 public function __construct( &$model ) {
20 parent::__construct( $model );
21
22 if ( did_action( 'pll_init' ) ) {
23 $this->init();
24 } else {
25 add_action( 'pll_init', array( $this, 'init' ) );
26 }
27 }
28
29 /**
30 * Called only at first object creation to avoid duplicating filters when switching blog
31 *
32 * @since 1.6
33 */
34 public function init() {
35 if ( did_action( 'setup_theme' ) ) {
36 $this->add_permastruct();
37 } else {
38 add_action( 'setup_theme', array( $this, 'add_permastruct' ), 2 );
39 }
40
41 // Make sure to prepare rewrite rules when flushing
42 add_action( 'pre_option_rewrite_rules', array( $this, 'prepare_rewrite_rules' ) );
43 }
44
45 /**
46 * Adds the language code in url
47 * links_model interface
48 *
49 * @since 1.2
50 *
51 * @param string $url url to modify
52 * @param object $lang language
53 * @return string modified url
54 */
55 public function add_language_to_link( $url, $lang ) {
56 if ( ! empty( $lang ) ) {
57 $base = $this->options['rewrite'] ? '' : 'language/';
58 $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base . $lang->slug . '/';
59 return str_replace( $this->home . '/' . $this->root, $this->home . '/' . $this->root . $slug, $url );
60 }
61 return $url;
62 }
63
64 /**
65 * Returns the url without language code
66 * links_model interface
67 *
68 * @since 1.2
69 *
70 * @param string $url url to modify
71 * @return string modified url
72 */
73 function remove_language_from_link( $url ) {
74 foreach ( $this->model->get_languages_list() as $language ) {
75 if ( ! $this->options['hide_default'] || $this->options['default_lang'] != $language->slug ) {
76 $languages[] = $language->slug;
77 }
78 }
79
80 if ( ! empty( $languages ) ) {
81 $pattern = str_replace( '/', '\/', $this->home . '/' . $this->root );
82 $pattern = '#' . $pattern . ( $this->options['rewrite'] ? '' : 'language\/' ) . '('.implode( '|', $languages ).')(\/|$)#';
83 $url = preg_replace( $pattern, $this->home . '/' . $this->root, $url );
84 }
85 return $url;
86 }
87
88 /**
89 * Returns the language based on language code in url
90 * links_model interface
91 *
92 * @since 1.2
93 * @since 2.0 add $url argument
94 *
95 * @param string $url optional, defaults to current url
96 * @return string language slug
97 */
98 public function get_language_from_url( $url = '' ) {
99 if ( empty( $url ) ) {
100 $url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
101 }
102
103 $pattern = str_replace( '/', '\/', $this->home . '/' . $this->root . ( $this->options['rewrite'] ? '' : 'language/' ) );
104 $pattern = '#' . $pattern . '('. implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(\/|$)#';
105 return preg_match( $pattern, trailingslashit( $url ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language
106 }
107
108 /**
109 * Returns the home url
110 * links_model interface
111 *
112 * @since 1.3.1
113 *
114 * @param object $lang PLL_Language object
115 * @return string
116 */
117 public function home_url( $lang ) {
118 $base = $this->options['rewrite'] ? '' : 'language/';
119 $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : '/' . $this->root . $base . $lang->slug;
120 return trailingslashit( $this->home . $slug );
121 }
122
123 /**
124 * Optionaly removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/
125 *
126 * @since 1.2
127 */
128 function add_permastruct() {
129 // Language information always in front of the uri ( 'with_front' => false )
130 // The 3rd parameter structure has been modified in WP 3.4
131 add_permastruct( 'language', $this->options['rewrite'] ? '%language%' : 'language/%language%', array( 'with_front' => false ) );
132 }
133
134 /**
135 * Prepares rewrite rules filters
136 *
137 * @since 0.8.1
138 *
139 * @param array $pre not used
140 * @return unmodified $pre
141 */
142 public function prepare_rewrite_rules( $pre ) {
143 // Don't modify the rules if there is no languages created yet
144 if ( $this->model->get_languages_list() && ! has_filter( 'language_rewrite_rules', '__return_empty_array' ) ) {
145 // Suppress the rules created by WordPress for our taxonomy
146 add_filter( 'language_rewrite_rules', '__return_empty_array' );
147
148 foreach ( $this->get_rewrite_rules_filters() as $type ) {
149 add_filter( $type . '_rewrite_rules', array( $this, 'rewrite_rules' ) );
150 }
151
152 add_filter( 'rewrite_rules_array', array( $this, 'rewrite_rules' ) ); // needed for post type archives
153 }
154 return $pre;
155 }
156
157 /**
158 * The rewrite rules !
159 * always make sure the default language is at the end in case the language information is hidden for default language
160 * thanks to brbrbr http://wordpress.org/support/topic/plugin-polylang-rewrite-rules-not-correct
161 *
162 * @since 0.8.1
163 *
164 * @param array $rules rewrite rules
165 * @return array modified rewrite rules
166 */
167 public function rewrite_rules( $rules ) {
168 $filter = str_replace( '_rewrite_rules', '', current_filter() );
169
170 global $wp_rewrite;
171 $newrules = array();
172
173 $languages = $this->model->get_languages_list( array( 'fields' => 'slug' ) );
174 if ( $this->options['hide_default'] ) {
175 $languages = array_diff( $languages, array( $this->options['default_lang'] ) );
176 }
177
178 if ( ! empty( $languages ) ) {
179 $slug = $wp_rewrite->root . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')/';
180 }
181
182 // For custom post type archives
183 $cpts = array_intersect( $this->model->get_translated_post_types(), get_post_types( array( '_builtin' => false ) ) );
184 $cpts = $cpts ? '#post_type=(' . implode( '|', $cpts ) . ')#' : '';
185
186 foreach ( $rules as $key => $rule ) {
187 // Special case for translated post types and taxonomies to allow canonical redirection
188 if ( $this->options['force_lang'] && in_array( $filter, array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies() ) ) ) {
189
190 /**
191 * Filters the rewrite rules to modify
192 *
193 * @since 1.9.1
194 *
195 * @param bool $modify whether to modify or not the rule, defaults to true
196 * @param array $rule original rewrite rule
197 * @param string $filter current set of rules being modified
198 * @param string|bool $archive custom post post type archive name or false if it is not a cpt archive
199 */
200 if ( ! apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, false ) ) {
201 continue;
202 }
203
204 if ( isset( $slug ) ) {
205 $newrules[ $slug . str_replace( $wp_rewrite->root, '', $key ) ] = str_replace(
206 array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),
207 array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),
208 $rule
209 ); // Should be enough!
210 }
211
212 if ( $this->options['hide_default'] ) {
213 $newrules[ $key ] = $rules[ $key ];
214 // Unset only if we hide the code for the default language as check_language_code_in_url will do its job in other cases
215 unset( $rules[ $key ] );
216 }
217 }
218
219 // Rewrite rules filtered by language
220 elseif ( in_array( $filter, $this->always_rewrite ) || in_array( $filter, $this->model->get_filtered_taxonomies() ) || ( $cpts && preg_match( $cpts, $rule, $matches ) && ! strpos( $rule, 'name=' ) ) || ( 'rewrite_rules_array' != $filter && $this->options['force_lang'] ) ) {
221
222 /** This filter is documented in include/links-directory.php */
223 if ( ! apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, empty( $matches[1] ) ? false : $matches[1] ) ) {
224 continue;
225 }
226
227 if ( isset( $slug ) ) {
228 $newrules[ $slug . str_replace( $wp_rewrite->root, '', $key ) ] = str_replace(
229 array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),
230 array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),
231 $rule
232 ); // Should be enough!
233 }
234
235 if ( $this->options['hide_default'] ) {
236 $newrules[ $key ] = str_replace( '?', '?lang=' . $this->options['default_lang'] . '&', $rule );
237 }
238
239 unset( $rules[ $key ] ); // Now useless
240 }
241 }
242
243 // The home rewrite rule
244 if ( 'root' == $filter && isset( $slug ) ) {
245 $newrules[ $slug . '?$' ] = $wp_rewrite->index.'?lang=$matches[1]';
246 }
247
248 return $newrules + $rules;
249 }
250 }
251