PluginProbe
Polylang / 1.9.2
Polylang v1.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 / include / links-directory.php

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

246 lines 8.3 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 *
94 * @return string language slug
95 */
96 public function get_language_from_url() {
97 $requested_url = ( is_ssl() ? 'https://' : 'http://' ) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
98 $pattern = str_replace( '/', '\/', $this->home . '/' . $this->root . ( $this->options['rewrite'] ? '' : 'language/' ) );
99 $pattern = '#' . $pattern . '('. implode( '|', $this->model->get_languages_list( array( 'fields' => 'slug' ) ) ) . ')(\/|$)#';
100 return preg_match( $pattern, trailingslashit( $requested_url ), $matches ) ? $matches[1] : ''; // $matches[1] is the slug of the requested language
101 }
102
103 /**
104 * Returns the home url
105 * links_model interface
106 *
107 * @since 1.3.1
108 *
109 * @param object $lang PLL_Language object
110 * @return string
111 */
112 public function home_url( $lang ) {
113 $base = $this->options['rewrite'] ? '' : 'language/';
114 $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : '/' . $this->root . $base . $lang->slug;
115 return trailingslashit( $this->home . $slug );
116 }
117
118 /**
119 * Optionaly removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/
120 *
121 * @since 1.2
122 */
123 function add_permastruct() {
124 // Language information always in front of the uri ( 'with_front' => false )
125 // The 3rd parameter structure has been modified in WP 3.4
126 add_permastruct( 'language', $this->options['rewrite'] ? '%language%' : 'language/%language%', array( 'with_front' => false ) );
127 }
128
129 /**
130 * Prepares rewrite rules filters
131 *
132 * @since 0.8.1
133 *
134 * @param array $pre not used
135 * @return unmodified $pre
136 */
137 public function prepare_rewrite_rules( $pre ) {
138 // Don't modify the rules if there is no languages created yet
139 if ( $this->model->get_languages_list() && ! has_filter( 'language_rewrite_rules', '__return_empty_array' ) ) {
140 // Suppress the rules created by WordPress for our taxonomy
141 add_filter( 'language_rewrite_rules', '__return_empty_array' );
142
143 foreach ( $this->get_rewrite_rules_filters() as $type ) {
144 add_filter( $type . '_rewrite_rules', array( &$this, 'rewrite_rules' ) );
145 }
146
147 add_filter( 'rewrite_rules_array', array( &$this, 'rewrite_rules' ) ); // needed for post type archives
148 }
149 return $pre;
150 }
151
152 /**
153 * The rewrite rules !
154 * always make sure the default language is at the end in case the language information is hidden for default language
155 * thanks to brbrbr http://wordpress.org/support/topic/plugin-polylang-rewrite-rules-not-correct
156 *
157 * @since 0.8.1
158 *
159 * @param array $rules rewrite rules
160 * @return array modified rewrite rules
161 */
162 public function rewrite_rules( $rules ) {
163 $filter = str_replace( '_rewrite_rules', '', current_filter() );
164
165 global $wp_rewrite;
166 $newrules = array();
167
168 $languages = $this->model->get_languages_list( array( 'fields' => 'slug' ) );
169 if ( $this->options['hide_default'] ) {
170 $languages = array_diff( $languages, array( $this->options['default_lang'] ) );
171 }
172
173 if ( ! empty( $languages ) ) {
174 $slug = $wp_rewrite->root . ( $this->options['rewrite'] ? '' : 'language/' ) . '(' . implode( '|', $languages ) . ')/';
175 }
176
177 // For custom post type archives
178 $cpts = array_intersect( $this->model->get_translated_post_types(), get_post_types( array( '_builtin' => false ) ) );
179 $cpts = $cpts ? '#post_type=(' . implode( '|', $cpts ) . ')#' : '';
180
181 foreach ( $rules as $key => $rule ) {
182 // Special case for translated post types and taxonomies to allow canonical redirection
183 if ( $this->options['force_lang'] && in_array( $filter, array_merge( $this->model->get_translated_post_types(), $this->model->get_translated_taxonomies() ) ) ) {
184
185 /**
186 * Filters the rewrite rules to modify
187 *
188 * @since 1.9.1
189 *
190 * @param bool $modify whether to modify or not the rule, defaults to true
191 * @param array $rule original rewrite rule
192 * @param string $filter current set of rules being modified
193 * @param string|bool $archive custom post post type archive name or false if it is not a cpt archive
194 */
195 if ( ! apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, false ) ) {
196 continue;
197 }
198
199 if ( isset( $slug ) ) {
200 $newrules[ $slug . str_replace( $wp_rewrite->root, '', $key ) ] = str_replace(
201 array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),
202 array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),
203 $rule
204 ); // Should be enough!
205 }
206
207 if ( $this->options['hide_default'] ) {
208 $newrules[ $key ] = $rules[ $key ];
209 // Unset only if we hide the code for the default language as check_language_code_in_url will do its job in other cases
210 unset( $rules[ $key ] );
211 }
212 }
213
214 // Rewrite rules filtered by language
215 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'] ) ) {
216
217 /** This filter is documented in include/links-directory.php */
218 if ( ! apply_filters( 'pll_modify_rewrite_rule', true, array( $key => $rule ), $filter, empty( $matches[1] ) ? false : $matches[1] ) ) {
219 continue;
220 }
221
222 if ( isset( $slug ) ) {
223 $newrules[ $slug . str_replace( $wp_rewrite->root, '', $key ) ] = str_replace(
224 array( '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?' ),
225 array( '[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&' ),
226 $rule
227 ); // Should be enough!
228 }
229
230 if ( $this->options['hide_default'] ) {
231 $newrules[ $key ] = str_replace( '?', '?lang=' . $this->options['default_lang'] . '&', $rule );
232 }
233
234 unset( $rules[ $key ] ); // Now useless
235 }
236 }
237
238 // The home rewrite rule
239 if ( 'root' == $filter && isset( $slug ) ) {
240 $newrules[ $slug . '?$' ] = $wp_rewrite->index.'?lang=$matches[1]';
241 }
242
243 return $newrules + $rules;
244 }
245 }
246