PluginProbe
Polylang / 1.5.2
Polylang v1.5.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.5.2, at include/links-directory.php

224 lines 8.0 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_Model {
11 protected $index = 'index.php'; // need this before $wp_rewrite is created, also harcoded in wp-includes/rewrite.php
12 protected $root;
13 protected $rewrite_rules = array();
14 protected $always_rewrite = array('date', 'root', 'comments', 'search', 'author', 'post_format', 'language');
15
16 /*
17 * constructor
18 *
19 * @since 1.2
20 *
21 * @param object $model PLL_Model instance
22 */
23 public function __construct(&$model) {
24 parent::__construct($model);
25
26 static $done = false;
27 if ($done)
28 return;
29
30 $done = true; // avoid duplicating rewrite rules when switching blog thanks to @ScreenFeedFr
31
32 // inspired by wp-includes/rewrite.php
33 $this->root = preg_match('#^/*' . $this->index . '#', get_option('permalink_structure')) ? $this->index . '/' : '';
34
35 add_action('setup_theme', array(&$this, 'add_permastruct'));
36
37 // refresh rewrite rules if the 'page_on_front' option is modified
38 add_action('update_option_page_on_front', 'flush_rewrite_rules');
39
40 // make sure to prepare rewrite rules when flushing
41 add_action('pre_option_rewrite_rules', array(&$this, 'prepare_rewrite_rules'));
42 }
43
44 /*
45 * adds the language code in url
46 * links_model interface
47 *
48 * @since 1.2
49 *
50 * @param string $url url to modify
51 * @param object $lang language
52 * @return string modified url
53 */
54 public function add_language_to_link($url, $lang) {
55 if (!empty($lang)) {
56 $base = $this->options['rewrite'] ? '' : 'language/';
57 $slug = $this->options['default_lang'] == $lang->slug && $this->options['hide_default'] ? '' : $base . $lang->slug . '/';
58 return str_replace($this->home . '/' . $this->root, $this->home . '/' . $this->root . $slug, $url);
59 }
60 return $url;
61 }
62
63 /*
64 * returns the url without language code
65 * links_model interface
66 *
67 * @since 1.2
68 *
69 * @param string $url url to modify
70 * @return string modified url
71 */
72 function remove_language_from_link($url) {
73 foreach ($this->model->get_languages_list() as $language)
74 if (!$this->options['hide_default'] || $this->options['default_lang'] != $language->slug)
75 $languages[] = $language->slug;
76
77 if (!empty($languages)) {
78 $pattern = str_replace('/', '\/', $this->home . '/' . $this->root);
79 $pattern = '#' . $pattern . ($this->options['rewrite'] ? '' : 'language\/') . '('.implode('|', $languages).')(\/|$)#';
80 $url = preg_replace($pattern, $this->home . '/' . $this->root, $url);
81 }
82 return $url;
83 }
84
85 /*
86 * returns the language based on language code in url
87 * links_model interface
88 *
89 * @since 1.2
90 *
91 * @return string language slug
92 */
93 public function get_language_from_url() {
94 $requested_url = (is_ssl() ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
95 $pattern = str_replace('/', '\/', $this->home . '/' . $this->root . ($this->options['rewrite'] ? '' : 'language/'));
96 $pattern = '#' . $pattern . '('. implode('|', $this->model->get_languages_list(array('fields' => 'slug'))) . ')(\/|$)#';
97 return preg_match($pattern, trailingslashit($requested_url), $matches) ? $matches[1] : ''; // $matches[1] is the slug of the requested language
98 }
99
100 /*
101 * returns the home url
102 * links_model interface
103 *
104 * @since 1.3.1
105 *
106 * @param object $lang PLL_Language object
107 * @return string
108 */
109 public function home_url($lang) {
110 return $this->options['hide_default'] && $lang->slug == $this->options['default_lang'] ? $this->home : get_term_link($lang, 'language');
111 }
112
113 /*
114 * optionaly removes 'language' in permalinks so that we get http://www.myblog/en/ instead of http://www.myblog/language/en/
115 *
116 * @since 1.2
117 */
118 function add_permastruct() {
119 // language information always in front of the uri ('with_front' => false)
120 // the 3rd parameter structure has been modified in WP 3.4
121 add_permastruct('language', $this->options['rewrite'] ? '%language%' : 'language/%language%', array('with_front' => false));
122 }
123
124 /*
125 * prepares rewrite rules filters
126 *
127 * @since 0.8.1
128 *
129 * @param array $pre not used
130 * @return unmodified $pre
131 */
132 public function prepare_rewrite_rules($pre) {
133 //clean filters which could have been set in a previous call (may occur when changing Polylang settings)
134 foreach ($this->rewrite_rules as $type)
135 remove_filter($type . '_rewrite_rules', array(&$this, 'rewrite_rules'));
136
137 // don't modify the rules if there is no languages created yet
138 if ($this->model->get_languages_list()) {
139 // make sure we have the right post types and taxonomies
140 $types = array_values(array_merge($this->model->get_translated_post_types(), $this->model->get_translated_taxonomies()));
141 $types = array_merge($this->always_rewrite, $types);
142 $this->rewrite_rules = apply_filters('pll_rewrite_rules', $types); // allow plugins to add rewrite rules to the language filter
143
144 foreach ($this->rewrite_rules as $type)
145 add_filter($type . '_rewrite_rules', array(&$this, 'rewrite_rules'));
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 // suppress the rules created by WordPress for our taxonomy
166 if ($filter == 'language')
167 return array();
168
169 global $wp_rewrite;
170 $newrules = array();
171
172 $languages = $this->model->get_languages_list(array('fields' => 'slug'));
173 if ($this->options['hide_default'])
174 $languages = array_diff($languages, array($this->options['default_lang']));
175
176 if (!empty($languages))
177 $slug = $wp_rewrite->root . ($this->options['rewrite'] ? '' : 'language/') . '('.implode('|', $languages).')/';
178
179 // for custom post type archives
180 $cpts = array_intersect($this->model->get_translated_post_types(), get_post_types(array('_builtin' => false)));
181 $cpts = $cpts ? '#post_type=('.implode('|', $cpts).')#' : '';
182
183 foreach ($rules as $key => $rule) {
184 // we don't need the lang parameter for post types and taxonomies
185 // moreover adding it would create issues for pages and taxonomies
186 if ($this->options['force_lang'] && in_array($filter, array_merge($this->model->get_translated_post_types(), $this->model->get_translated_taxonomies()))) {
187 if (isset($slug))
188 $newrules[$slug.str_replace($wp_rewrite->root, '', $key)] = str_replace(
189 array('[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]'),
190 array('[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]'),
191 $rule
192 ); // hopefully it is sufficient!
193
194 if ($this->options['hide_default']) {
195 $newrules[$key] = $rules[$key];
196 // unset only if we hide the code for the default language as check_language_code_in_url will do its job in other cases
197 unset($rules[$key]);
198 }
199 }
200
201 // rewrite rules filtered by language
202 elseif (in_array($filter, $this->always_rewrite) || ($cpts && preg_match($cpts, $rule) && !strpos($rule, 'name=')) || ($filter != 'rewrite_rules_array' && $this->options['force_lang'])) {
203 if (isset($slug))
204 $newrules[$slug.str_replace($wp_rewrite->root, '', $key)] = str_replace(
205 array('[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '[1]', '?'),
206 array('[9]', '[8]', '[7]', '[6]', '[5]', '[4]', '[3]', '[2]', '?lang=$matches[1]&'),
207 $rule
208 ); // should be enough!
209
210 if ($this->options['hide_default'])
211 $newrules[$key] = str_replace('?', '?lang='.$this->options['default_lang'].'&', $rule);
212
213 unset($rules[$key]); // now useless
214 }
215 }
216
217 // the home rewrite rule
218 if ($filter == 'root' && isset($slug))
219 $newrules[$slug.'?$'] = $wp_rewrite->index.'?lang=$matches[1]';
220
221 return $newrules + $rules;
222 }
223 }
224