PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 2.2.7.3
Permalink Manager Lite v2.2.7.3
2.6.0 2.5.5 2.5.4 2.5.3.4 2.2.18 2.2.19.2 2.2.19.3 2.2.19.3.1 2.2.2 2.2.20 2.2.20.1 2.2.20.3 2.2.4 2.2.5 2.2.6 2.2.7.2 2.2.7.3 2.2.7.5 2.2.7.6 2.2.8.4 2.2.8.5 2.2.8.6 2.2.8.7 2.2.8.9 2.2.9.1 2.2.9.2 2.2.9.2.1 2.2.9.3 2.2.9.4 2.2.9.6 2.2.9.7 2.2.9.9 2.3.0 2.3.1.1 2.4.0 2.4.1 2.4.1.2 2.4.1.3 2.4.1.4 2.4.1.5 2.4.1.6 2.4.2 2.4.2.1 2.4.3 2.4.3.1 2.4.3.2 2.4.3.3 2.4.3.4 2.4.4 2.4.4.1 2.4.4.2 2.4.4.3 2.5.0 2.5.1 2.5.1.1 2.5.1.2 2.5.1.3 2.5.1.4 2.5.2 2.5.2.1 2.5.2.2 2.5.2.3 2.5.2.4 2.5.3 2.5.3.1 2.5.3.2 2.5.3.3 trunk 0.2 0.3 0.3.1 0.3.2 0.3.3 0.3.4 0.4 0.4.1 0.4.2 0.4.3 0.4.4 0.4.6 0.4.7 0.4.8 0.4.9 0.5.3 0.5.4 1.0.0 1.0.1 1.0.4 1.1.0 1.1.1 1.1.2 1.11.6.3 2.0.0 2.0.3 2.0.4 2.0.4.3 2.0.5.1 2.0.5.2 2.0.5.3 2.0.5.3.1 2.0.5.4 2.0.5.4a 2.0.5.5 2.0.5.6 2.0.5.6.1 2.0.5.7 2.0.5.9a 2.0.6.2.1 2.0.6.2a 2.0.6.3 2.1.0 2.1.1 2.1.2.4 2.2.0 2.2.1.1 2.2.1.2 2.2.11 2.2.12 2.2.13.1 2.2.14 2.2.15.1 2.2.16 2.2.17
permalink-manager / includes / core / permalink-manager-third-parties.php
permalink-manager / includes / core Last commit date
permalink-manager-actions.php 6 years ago permalink-manager-admin-functions.php 6 years ago permalink-manager-core-functions.php 6 years ago permalink-manager-debug.php 6 years ago permalink-manager-gutenberg.php 6 years ago permalink-manager-helper-functions.php 6 years ago permalink-manager-third-parties.php 6 years ago permalink-manager-uri-functions-post.php 6 years ago
permalink-manager-third-parties.php
1006 lines
1 <?php
2
3 /**
4 * Third parties integration
5 */
6 class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
7
8 public function __construct() {
9 add_action('init', array($this, 'init_hooks'), 99);
10 add_action('plugins_loaded', array($this, 'init_early_hooks'), 99);
11 }
12
13 function init_hooks() {
14 global $sitepress_settings, $permalink_manager_options, $polylang, $translate_press_settings;
15
16 // 0. Stop redirect
17 add_action('wp', array($this, 'stop_redirect'), 0);
18
19 // 1. WPML, Polylang & TranslatePress
20 if($sitepress_settings || !empty($polylang->links_model->options) || class_exists('TRP_Translate_Press')) {
21 // Detect Post/Term function
22 if(!empty($permalink_manager_options['general']['fix_language_mismatch'])) {
23 add_filter('permalink_manager_detected_post_id', array($this, 'fix_language_mismatch'), 9, 3);
24 add_filter('permalink_manager_detected_term_id', array($this, 'fix_language_mismatch'), 9, 3);
25 }
26
27 // URI Editor
28 add_filter('permalink_manager_uri_editor_extra_info', array($this, 'language_column_uri_editor'), 9, 3);
29
30 // Adjust front page ID
31 add_filter('permalink_manager_is_front_page', array($this, 'wpml_is_front_page'), 9, 3);
32
33 // Get translation mode
34 $mode = 0;
35
36 // A. WPML
37 if(isset($sitepress_settings['language_negotiation_type'])) {
38 $url_settings = $sitepress_settings['language_negotiation_type'];
39
40 if(in_array($sitepress_settings['language_negotiation_type'], array(1, 2))) {
41 $mode = 'prepend';
42 } else if($sitepress_settings['language_negotiation_type'] == 3) {
43 $mode = 'append';
44 }
45 }
46 // B. Polylang
47 else if(isset($polylang->links_model->options['force_lang'])) {
48 $url_settings = $polylang->links_model->options['force_lang'];
49
50 if(in_array($url_settings, array(1, 2, 3))) {
51 $mode = 'prepend';
52 }
53 }
54 // C. TranslatePress
55 else if(class_exists('TRP_Translate_Press')) {
56 $translate_press_settings = get_option('trp_settings');
57
58 $mode = 'prepend';
59 }
60
61 if($mode === 'prepend') {
62 add_filter('permalink_manager_detect_uri', array($this, 'detect_uri_language'), 9, 3);
63 add_filter('permalink_manager_filter_permalink_base', array($this, 'prepend_lang_prefix'), 9, 2);
64 add_filter('template_redirect', array($this, 'wpml_redirect'), 0, 998 );
65 } else if($mode === 'append') {
66 add_filter('permalink_manager_filter_final_post_permalink', array($this, 'append_lang_prefix'), 5, 2);
67 add_filter('permalink_manager_filter_final_term_permalink', array($this, 'append_lang_prefix'), 5, 2);
68 add_filter('permalink_manager_detect_uri', array($this, 'wpml_ignore_lang_query_parameter'), 9);
69 }
70
71 // Translate slugs
72 if(class_exists('WPML_Slug_Translation')) {
73 add_filter('permalink_manager_filter_post_type_slug', array($this, 'wpml_translate_post_type_slug'), 9, 3);
74 // add_filter('permalink_manager_filter_taxonomy_slug', array($this, 'wpml_translate_taxonomy_slug'), 9, 3);
75 }
76
77 // Translate permastructure
78 add_filter('permalink_manager_filter_permastructure', array($this, 'translate_permastructure'), 9, 2);
79 }
80
81 // 2. AMP
82 if(defined('AMP_QUERY_VAR')) {
83 // Detect AMP endpoint
84 add_filter('permalink_manager_detect_uri', array($this, 'detect_amp'), 10, 2);
85 add_filter('request', array($this, 'enable_amp'), 10, 1);
86 }
87
88 // 4. WooCommerce
89 if(class_exists('WooCommerce')) {
90 add_filter('request', array($this, 'woocommerce_detect'), 20, 1);
91 add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
92
93 if(class_exists('WooCommerce') && class_exists('Permalink_Manager_Pro_Functions')) {
94 if(is_admin()){
95 add_filter('woocommerce_coupon_data_tabs', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_tabs');
96 add_action('woocommerce_coupon_data_panels', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_panel');
97 add_action('woocommerce_coupon_options_save', 'Permalink_Manager_Pro_Functions::woocommerce_save_coupon_uri', 9, 2);
98 }
99 add_filter('request', 'Permalink_Manager_Pro_Functions::woocommerce_detect_coupon_code', 1, 1);
100 add_filter('permalink_manager_disabled_post_types', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_uris', 9, 1);
101 }
102
103 add_action('woocommerce_product_import_inserted_product_object', array($this, 'woocommerce_generate_permalinks_after_import'), 9, 2);
104 }
105
106 // 5. Theme My Login
107 if(class_exists('Theme_My_Login')) {
108 add_filter('permalink_manager_filter_final_post_permalink', array($this, 'tml_keep_query_parameters'), 9, 3);
109 }
110
111 // 6. Yoast SEO
112 add_filter('wpseo_xml_sitemap_post_url', array($this, 'yoast_fix_sitemap_urls'), 9);
113 add_filter('wpseo_breadcrumb_links', array($this, 'yoast_fix_breadcrumbs'), 9);
114
115 // 7. WooCommerce Wishlist Plugin
116 if(function_exists('tinv_get_option')) {
117 add_filter('permalink_manager_detect_uri', array($this, 'ti_woocommerce_wishlist_uris'), 15, 3);
118 }
119
120 // 8. Revisionize
121 if(defined('REVISIONIZE_ROOT')) {
122 add_action('revisionize_after_create_revision', array($this, 'revisionize_keep_post_uri'), 9, 2);
123 add_action('revisionize_before_publish', array($this,'revisionize_clone_uri'), 9, 2);
124 }
125
126 // 9. WP All Import
127 if(class_exists('PMXI_Plugin') && (empty($permalink_manager_options['general']['pmxi_import_support']))) {
128 add_action('pmxi_extend_options_featured', array($this, 'wpaiextra_uri_display'), 9, 2);
129 add_filter('pmxi_options_options', array($this, 'wpai_api_options'));
130 add_filter('pmxi_addons', array($this, 'wpai_api_register'));
131 add_filter('wp_all_import_addon_parse', array($this, 'wpai_api_parse'));
132 add_filter('wp_all_import_addon_import', array($this, 'wpai_api_import'));
133
134 add_action('pmxi_saved_post', array($this, 'wpai_save_redirects'));
135
136 add_action('pmxi_after_xml_import', array($this, 'wpai_schedule_regenerate_uris_after_xml_import'), 10, 1);
137 add_action('wpai_regenerate_uris_after_import_event', array($this, 'wpai_regenerate_uris_after_import'), 10, 1);
138 }
139 }
140
141 /**
142 * Some of the hooks must be called shortly after all the plugins are loaded
143 */
144 public function init_early_hooks() {
145 // 1. WP Store Locator
146 if(class_exists('WPSL_CSV')) {
147 add_action('added_post_meta', array($this, 'wpsl_regenerate_after_import'), 10, 4);
148 add_action('updated_post_meta', array($this, 'wpsl_regenerate_after_import'), 10, 4);
149 }
150 }
151
152 /**
153 * 0. Stop redirect
154 */
155 public static function stop_redirect() {
156 global $wp_query;
157
158 if(!empty($wp_query->query)) {
159 $query_vars = $wp_query->query;
160
161 // WordPress Photo Seller Plugin
162 if(!empty($query_vars['image_id']) && !empty($query_vars['gallery_id'])) {
163 $wp_query->query_vars['do_not_redirect'] = 1;
164 }
165 // Ultimate Member
166 else if(!empty($query_vars['um_user']) && !empty($query_vars['um_user'])) {
167 $wp_query->query_vars['do_not_redirect'] = 1;
168 }
169 // Mailster
170 else if(!empty($query_vars['_mailster_page'])) {
171 $wp_query->query_vars['do_not_redirect'] = 1;
172 }
173 // WP Route
174 else if(!empty($query_vars['WP_Route'])) {
175 $wp_query->query_vars['do_not_redirect'] = 1;
176 }
177 // WooCommerce Wishlist
178 else if(!empty($query_vars['wishlist-action'])) {
179 $wp_query->query_vars['do_not_redirect'] = 1;
180 }
181 }
182 }
183
184 /**
185 * 1. WPML/Polylang/TranslatePress filters
186 */
187 public static function get_language_code($element) {
188 global $TRP_LANGUAGE, $translate_press_settings;
189
190 // Fallback
191 if(is_string($element) && strpos($element, 'tax-') !== false) {
192 $element_id = intval(preg_replace("/[^0-9]/", "", $element));
193 $element = get_term($element_id);
194 } else if(is_numeric($element)) {
195 $element = get_post($element);
196 }
197
198 // A. TranslatePress
199 if(!empty($TRP_LANGUAGE)) {
200 $lang_code = self::get_translatepress_language_code($TRP_LANGUAGE);
201 }
202 // B. WPML & Polylang
203 else {
204 if(isset($element->post_type)) {
205 $element_id = $element->ID;
206 $element_type = $element->post_type;
207 } else if(isset($element->taxonomy)) {
208 $element_id = $element->term_taxonomy_id;
209 $element_type = $element->taxonomy;
210 } else {
211 return false;
212 }
213
214 $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
215 }
216
217 // Use default language if nothing detected
218 return ($lang_code) ? $lang_code : self::get_default_language();
219 }
220
221 public static function get_translatepress_language_code($lang) {
222 global $translate_press_settings;
223
224 if(!empty($translate_press_settings['url-slugs'])) {
225 $lang_code = (!empty($translate_press_settings['url-slugs'][$lang])) ? $translate_press_settings['url-slugs'][$lang] : '';
226 }
227
228 return (!empty($lang_code)) ? $lang_code : false;
229 }
230
231 public static function get_default_language() {
232 global $sitepress, $translate_press_settings;
233
234 if(function_exists('pll_default_language')) {
235 $def_lang = pll_default_language('slug');
236 } else if(is_object($sitepress)) {
237 $def_lang = $sitepress->get_default_language();
238 } else if(!empty($translate_press_settings['default-language'])) {
239 $def_lang = self::get_translatepress_language_code($translate_press_settings['default-language']);
240 } else {
241 $def_lang = '';
242 }
243
244 return $def_lang;
245 }
246
247 public static function get_all_languages($exclude_default_language = false) {
248 global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
249
250 $languages_array = $active_languages = array();
251 $default_language = self::get_default_language();
252
253 if(!empty($sitepress_settings['active_languages'])) {
254 $languages_array = $sitepress_settings['active_languages'];
255 } elseif(function_exists('pll_languages_list')) {
256 $languages_array = pll_languages_list(array('fields' => null));
257 } if(!empty($translate_press_settings['url-slugs'])) {
258 // $languages_array = $translate_press_settings['url-slugs'];
259 }
260
261 // Get native language names as value
262 if($languages_array) {
263 foreach($languages_array as $val) {
264 if(!empty($sitepress)) {
265 $lang = $val;
266 $lang_details = $sitepress->get_language_details($lang);
267 $language_name = $lang_details['native_name'];
268 } else if(!empty($val->name)) {
269 $lang = $val->slug;
270 $language_name = $val->name;
271 }
272
273 $active_languages[$lang] = (!empty($language_name)) ? sprintf('%s <span>(%s)</span>', $language_name, $lang) : '-';
274 }
275
276 // Exclude default language if needed
277 if($exclude_default_language && $default_language && !empty($active_languages[$default_language])) {
278 unset($active_languages[$default_language]);
279 }
280 }
281
282 return (array) $active_languages;
283 }
284
285 function fix_language_mismatch($item_id, $uri_parts, $is_term = false) {
286 global $wp, $language_code;
287
288 if($is_term) {
289 $element = get_term($item_id);
290 if(!empty($element) && !is_wp_error($element)) {
291 $element_id = $element->term_taxonomy_id;
292 $element_type = $element->taxonomy;
293 } else {
294 return false;
295 }
296 } else {
297 $element = get_post($item_id);
298
299 if(!empty($element->post_type)) {
300 $element_id = $item_id;
301 $element_type = $element->post_type;
302 }
303 }
304
305 // Stop if no term or post is detected
306 if(empty($element)) { return false; }
307
308 $language_code = self::get_language_code($element);
309
310 if(!empty($uri_parts['lang']) && ($uri_parts['lang'] != $language_code)) {
311 $wpml_item_id = apply_filters('wpml_object_id', $element_id, $element_type);
312 $item_id = (is_numeric($wpml_item_id)) ? $wpml_item_id : $item_id;
313 }
314
315 return $item_id;
316 }
317
318 function detect_uri_language($uri_parts, $request_url, $endpoints) {
319 global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
320
321 if(!empty($sitepress_settings['active_languages'])) {
322 $languages_list = (array) $sitepress_settings['active_languages'];
323 } elseif(function_exists('pll_languages_list')) {
324 $languages_array = pll_languages_list();
325 $languages_list = (is_array($languages_array)) ? (array) $languages_array : "";
326 } elseif($translate_press_settings['url-slugs']) {
327 $languages_list = $translate_press_settings['url-slugs'];
328 }
329
330 if(is_array($languages_list)) {
331 $languages_list = implode("|", $languages_list);
332 } else {
333 return $uri_parts;
334 }
335
336 $default_language = self::get_default_language();
337
338 // Fix for multidomain language configuration
339 if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
340 if(!empty($polylang->options['domains'])) {
341 $domains = (array) $polylang->options['domains'];
342 } else if(!empty($sitepress_settings['language_domains'])) {
343 $domains = (array) $sitepress_settings['language_domains'];
344 }
345
346 foreach($domains as &$domain) {
347 $domain = preg_replace('/((http(s)?:\/\/(www\.)?)|(www\.))?(.+?)\/?$/', 'http://$6', $domain);
348 }
349
350 $request_url = trim(str_replace($domains, "", $request_url), "/");
351 }
352
353 if(!empty($languages_list)) {
354 //preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})[\/$]([^\/]*)|\/()([\d+]))?\/?$/i", $request_url, $regex_parts);
355 preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i", $request_url, $regex_parts);
356
357 $uri_parts['lang'] = (!empty($regex_parts[1])) ? $regex_parts[1] : $default_language;
358 $uri_parts['uri'] = (!empty($regex_parts[2])) ? $regex_parts[2] : "";
359 $uri_parts['endpoint'] = (!empty($regex_parts[3])) ? $regex_parts[3] : "";
360 $uri_parts['endpoint_value'] = (!empty($regex_parts[4])) ? $regex_parts[4] : "";
361 }
362
363 return $uri_parts;
364 }
365
366 function prepend_lang_prefix($base, $element) {
367 global $sitepress_settings, $polylang, $permalink_manager_uris, $translate_press_settings;
368
369 $language_code = self::get_language_code($element);
370 $default_language_code = self::get_default_language();
371 $home_url = get_home_url();
372
373 // Hide language code if "Use directory for default language" option is enabled
374 $hide_prefix_for_default_lang = ((isset($sitepress_settings['urls']['directory_for_default_language']) && $sitepress_settings['urls']['directory_for_default_language'] != 1) || !empty($polylang->links_model->options['hide_default']) || !empty($translate_press_settings['add-subdirectory-to-default-language'])) ? true : false;
375
376 // Last instance - use language paramater from &_GET array
377 if(is_admin()) {
378 $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
379 }
380
381 // Adjust URL base
382 if(!empty($language_code)) {
383 // A. Different domain per language
384 if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
385
386 if(!empty($polylang->options['domains'])) {
387 $domains = $polylang->options['domains'];
388 } else if(!empty($sitepress_settings['language_domains'])) {
389 $domains = $sitepress_settings['language_domains'];
390 }
391
392 $is_term = (!empty($element->term_taxonomy_id)) ? true : false;
393 $element_id = ($is_term) ? "tax-{$element->term_taxonomy_id}" : $element->ID;
394
395 // Filter only custom permalinks
396 if(empty($permalink_manager_uris[$element_id]) || empty($domains)) { return $base; }
397
398 // Replace the domain name
399 if(!empty($domains[$language_code])) {
400 $base = trim($domains[$language_code], "/");
401
402 // Append URL scheme
403 if(!preg_match("~^(?:f|ht)tps?://~i", $base)) {
404 $scehme = parse_url($home_url, PHP_URL_SCHEME);
405 $base = "{$scehme}://{$base}";
406 }
407 }
408 }
409 // B. Prepend language code
410 else if(!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 2) {
411 if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
412 return $base;
413 } else {
414 $base = preg_replace('/(https?:\/\/)/', "$1{$language_code}.", $home_url);
415 }
416 }
417 // C. Append prefix
418 else {
419 if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
420 return $base;
421 } else {
422 $base .= "/{$language_code}";
423 }
424 }
425 }
426
427 return $base;
428 }
429
430 function append_lang_prefix($permalink, $element) {
431 global $sitepress_settings, $polylang, $permalink_manager_uris;
432
433 $language_code = self::get_language_code($element);
434 $default_language_code = self::get_default_language();
435
436 // Last instance - use language paramater from &_GET array
437 if(is_admin()) {
438 $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
439 }
440
441 // B. Append ?lang query parameter
442 if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 3) {
443 if($default_language_code == $language_code) {
444 return $permalink;
445 } else {
446 $permalink .= "?lang={$language_code}";
447 }
448 }
449
450 return $permalink;
451 }
452
453 function translate_permastructure($permastructure, $element) {
454 global $permalink_manager_permastructs, $pagenow;;
455
456 // Get element language code
457 if(!empty($_REQUEST['data']) && strpos($_REQUEST['data'], "target_lang")) {
458 $language_code = preg_replace('/(.*target_lang=)([^=&]+)(.*)/', '$2', $_REQUEST['data']);
459 } else if(in_array($pagenow, array('post.php', 'post-new.php')) && !empty($_GET['lang'])) {
460 $language_code = $_GET['lang'];
461 } else if(!empty($_REQUEST['icl_post_language'])) {
462 $language_code = $_REQUEST['icl_post_language'];
463 } else if(!empty($_POST['action']) && $_POST['action'] == 'pm_save_permalink' && defined('ICL_LANGUAGE_CODE')) {
464 $language_code = ICL_LANGUAGE_CODE;
465 } else {
466 $language_code = self::get_language_code($element);
467 }
468
469 if(!empty($element->ID)) {
470 $translated_permastructure = (!empty($permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"])) ? $permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"] : '';
471 } else if(!empty($element->term_id)) {
472 $translated_permastructure = (!empty($permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"])) ? $permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"] : '';
473 }
474
475 return (!empty($translated_permastructure)) ? $translated_permastructure : $permastructure;
476 }
477
478
479 function language_column_uri_editor($output, $column, $element) {
480 $language_code = self::get_language_code($element);
481 $output .= (!empty($language_code)) ? sprintf(" | <span><strong>%s:</strong> %s</span>", __("Language"), $language_code) : "";
482
483 return $output;
484 }
485
486 function wpml_translate_post_type_slug($post_type_slug, $element, $post_type) {
487 $post = (is_integer($element)) ? get_post($element) : $element;
488 $language_code = self::get_language_code($post);
489
490 $post_type_slug = apply_filters('wpml_get_translated_slug', $post_type_slug, $post_type, $language_code);
491
492 // Translate %post_type% tag in custom permastructures
493 return $post_type_slug;
494 }
495
496 function wpml_is_front_page($bool, $page_id, $front_page_id) {
497 $default_language_code = self::get_default_language();
498 $page_id = apply_filters('wpml_object_id', $page_id, 'page', true, $default_language_code);
499
500 return (!empty($page_id) && $page_id == $front_page_id) ? true : $bool;
501 }
502
503 function wpml_ignore_lang_query_parameter($uri_parts) {
504 global $permalink_manager_uris;
505
506 foreach($permalink_manager_uris as &$uri) {
507 $uri = trim(strtok($uri, '?'), "/");
508 }
509
510 return $uri_parts;
511 }
512
513 function wpml_redirect() {
514 global $language_code, $wp_query;
515
516 if(!empty($language_code) && defined('ICL_LANGUAGE_CODE') && ICL_LANGUAGE_CODE != $language_code && !empty($wp_query->query['do_not_redirect'])) {
517 unset($wp_query->query['do_not_redirect']);
518 }
519 }
520
521 /**
522 * 2. AMP hooks
523 */
524 function detect_amp($uri_parts, $request_url) {
525 global $amp_enabled;
526 $amp_query_var = AMP_QUERY_VAR;
527
528 // Check if AMP should be triggered
529 preg_match("/^(.+?)\/({$amp_query_var})?\/?$/i", $uri_parts['uri'], $regex_parts);
530 if(!empty($regex_parts[2])) {
531 $uri_parts['uri'] = $regex_parts[1];
532 $amp_enabled = true;
533 }
534
535 return $uri_parts;
536 }
537
538 function enable_amp($query) {
539 global $amp_enabled;
540
541 if(!empty($amp_enabled)) {
542 $query[AMP_QUERY_VAR] = 1;
543 }
544
545 return $query;
546 }
547
548 /**
549 * 3. Parse Custom Permalinks import
550 */
551 public static function custom_permalinks_uris() {
552 global $wpdb;
553
554 $custom_permalinks_uris = array();
555
556 // 1. List tags/categories
557 $table = get_option('custom_permalink_table');
558 if($table && is_array($table)) {
559 foreach ( $table as $permalink => $info ) {
560 $custom_permalinks_uris[] = array(
561 'id' => "tax-" . $info['id'],
562 'uri' => trim($permalink, "/")
563 );
564 }
565 }
566
567 // 2. List posts/pages
568 $query = "SELECT p.ID, m.meta_value FROM $wpdb->posts AS p LEFT JOIN $wpdb->postmeta AS m ON (p.ID = m.post_id) WHERE m.meta_key = 'custom_permalink' AND m.meta_value != '';";
569 $posts = $wpdb->get_results($query);
570 foreach($posts as $post) {
571 $custom_permalinks_uris[] = array(
572 'id' => $post->ID,
573 'uri' => trim($post->meta_value, "/"),
574 );
575 }
576
577 return $custom_permalinks_uris;
578 }
579
580 static public function import_custom_permalinks_uris() {
581 global $permalink_manager_uris, $permalink_manager_before_sections_html;
582
583 $custom_permalinks_plugin = 'custom-permalinks/custom-permalinks.php';
584
585 if(is_plugin_active($custom_permalinks_plugin) && !empty($_POST['disable_custom_permalinks'])) {
586 deactivate_plugins($custom_permalinks_plugin);
587 }
588
589 // Get a list of imported URIs
590 $custom_permalinks_uris = self::custom_permalinks_uris();
591
592 if(!empty($custom_permalinks_uris) && count($custom_permalinks_uris) > 0) {
593 foreach($custom_permalinks_uris as $item) {
594 $permalink_manager_uris[$item['id']] = $item['uri'];
595 }
596
597 $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message(__( '"Custom Permalinks" URIs were imported!', 'permalink-manager' ), 'updated');
598 update_option('permalink-manager-uris', $permalink_manager_uris);
599 } else {
600 $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message(__( 'No "Custom Permalinks" URIs were imported!', 'permalink-manager' ), 'error');
601 }
602 }
603
604 /**
605 * 4. WooCommerce
606 */
607 function woocommerce_detect($query) {
608 global $woocommerce, $pm_query;
609
610 $shop_page_id = get_option('woocommerce_shop_page_id');
611
612 // WPML - translate shop page id
613 $shop_page_id = apply_filters('wpml_object_id', $shop_page_id, 'page', TRUE);
614
615 // Fix shop page
616 if(!empty($pm_query['id']) && is_numeric($pm_query['id']) && $shop_page_id == $pm_query['id']) {
617 $query['post_type'] = 'product';
618 unset($query['pagename']);
619 }
620
621 // Fix WooCommerce pages
622 if(!empty($woocommerce->query->query_vars)) {
623 $query_vars = $woocommerce->query->query_vars;
624
625 foreach($query_vars as $key => $val) {
626 if(isset($query[$key])) {
627 $woocommerce_page = true;
628 $query['do_not_redirect'] = 1;
629 break;
630 }
631 }
632 }
633
634 return $query;
635 }
636
637 function woocommerce_checkout_fix() {
638 global $wp_query, $pm_query, $permalink_manager_options;
639
640 // Redirect from Shop archive to selected page
641 if(is_shop() && empty($pm_query['id'])) {
642 $redirect_mode = (!empty($permalink_manager_options['general']['redirect'])) ? $permalink_manager_options['general']['redirect'] : false;
643 $redirect_shop = apply_filters('permalink-manager-redirect-shop-archive', false);
644 $shop_page = get_option('woocommerce_shop_page_id');
645
646 if($redirect_mode && $redirect_shop && $shop_page && empty($wp_query->query_vars['s'])) {
647 $shop_url = get_permalink($shop_page);
648 wp_safe_redirect($shop_url, $redirect_mode);
649 exit();
650 }
651 }
652
653 // Do not redirect "thank you" & another WooCommerce pages
654 if(is_checkout() || (function_exists('is_wc_endpoint_url') && is_wc_endpoint_url())) {
655 $wp_query->query_vars['do_not_redirect'] = 1;
656 }
657 }
658
659 function woocommerce_generate_permalinks_after_import($object, $data) {
660 global $permalink_manager_uris;
661
662 if(!empty($object)) {
663 $product_id = $object->get_id();
664
665 // Ignore variations
666 if(empty($permalink_manager_uris[$product_id]) && $object->get_type() !== 'variation') {
667 $permalink_manager_uris[$product_id] = Permalink_Manager_URI_Functions_Post::get_default_post_uri($product_id, false, true);
668
669 update_option('permalink-manager-uris', $permalink_manager_uris);
670 }
671 }
672 }
673
674 /**
675 * 5. Theme My Login
676 */
677 function tml_keep_query_parameters($permalink, $post, $old_permalink) {
678 // Get the query string from old permalink
679 $get_parameters = (($pos = strpos($old_permalink, "?")) !== false) ? substr($old_permalink, $pos) : "";
680
681 return $permalink . $get_parameters;
682 }
683
684 /**
685 * 6. Yoast SEO hooks
686 */
687 function yoast_fix_sitemap_urls($permalink) {
688 if(class_exists('WPSEO_Utils')) {
689 $home_url = WPSEO_Utils::home_url();
690 $home_protocol = parse_url($home_url, PHP_URL_SCHEME);
691
692 $permalink = preg_replace("/^http(s)?/", $home_protocol, $permalink);
693 }
694
695 return $permalink;
696 }
697
698 function yoast_fix_breadcrumbs($links) {
699 // Get post type permastructure settings
700 global $permalink_manager_uris, $permalink_manager_options, $post, $wpdb, $wp;
701
702 // Check if the filter should be activated
703 if(empty($permalink_manager_options['general']['yoast_breadcrumbs']) || empty($permalink_manager_uris)) { return $links; }
704
705 // Get current post/page/term (if available)
706 $queried_element = get_queried_object();
707 if(!empty($queried_element->ID)) {
708 $element_id = $queried_element->ID;
709 } else if(!empty($queried_element->term_id)) {
710 $element_id = "tax-{$queried_element->term_id}";
711 }
712
713 // Get the custom permalink (if available) or the current request URL (if unavailable)
714 if(!empty($element_id) && !empty($permalink_manager_uris[$element_id])) {
715 $custom_uri = preg_replace("/([^\/]+)$/", '', $permalink_manager_uris[$element_id]);
716 } else {
717 $custom_uri = trim(preg_replace("/([^\/]+)$/", '', $wp->request), "/");
718 }
719
720 $all_uris = array_flip($permalink_manager_uris);
721 $custom_uri_parts = explode('/', trim($custom_uri));
722 $breadcrumbs = array();
723 $snowball = '';
724 $available_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
725 $available_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
726
727 // Get Yoast Meta (the breadcrumbs titles can be changed in Yoast metabox)
728 $yoast_meta_terms = get_option('wpseo_taxonomy_meta');
729
730 // Get internal breadcrumb elements
731 foreach($custom_uri_parts as $slug) {
732 if(empty($slug)) { continue; }
733
734 $snowball = (empty($snowball)) ? $slug : "{$snowball}/{$slug}";
735
736 // 1A. Try to match any custom URI
737 if($snowball) {
738 $uri = trim($snowball, "/");
739 $element = (!empty($all_uris[$uri])) ? $all_uris[$uri] : false;
740
741 if(!empty($element) && strpos($element, 'tax-') !== false) {
742 $element_id = intval(preg_replace("/[^0-9]/", "", $element));
743 $element = get_term($element_id);
744 } else if(is_numeric($element)) {
745 $element = get_post($element);
746 }
747 }
748
749 // 1B. Try to get term
750 if(empty($element) && !empty($available_taxonomies)) {
751 $sql = sprintf("SELECT t.term_id, t.name, tt.taxonomy FROM {$wpdb->terms} AS t LEFT JOIN {$wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE slug = '%s' AND tt.taxonomy IN ('%s') LIMIT 1", $slug, implode("','", array_keys($available_taxonomies)));
752
753 $element = $wpdb->get_row($sql);
754 }
755
756 // 1C. Try to get page/post
757 if(empty($element) && !empty($available_post_types)) {
758 $sql = sprintf("SELECT ID, post_title FROM {$wpdb->posts} WHERE post_name = '%s' AND post_status = 'publish' AND post_type IN ('%s') AND post_type != 'attachment' LIMIT 1", $slug, implode("','", array_keys($available_post_types)));
759
760 $element = $wpdb->get_row($sql);
761 }
762
763 // 2A. When the term is found, we can add it to the breadcrumbs
764 if(!empty($element->term_id)) {
765 $title = (!empty($yoast_meta_terms[$element->taxonomy][$element->term_id]['wpseo_bctitle'])) ? $yoast_meta_terms[$element->taxonomy][$element->term_id]['wpseo_bctitle'] : $element->name;
766
767 $breadcrumbs[] = array(
768 'text' => $title,
769 'url' => get_term_link((int) $element->term_id, $element->taxonomy),
770 );
771 }
772 // 2B. When the post/page is found, we can add it to the breadcrumbs
773 else if(!empty($element->ID)) {
774 $title = get_post_meta($element->ID, '_yoast_wpseo_bctitle', true);
775 $title = (!empty($title)) ? $title : $element->post_title;
776
777 $breadcrumbs[] = array(
778 'text' => $title,
779 'url' => get_permalink($element->ID),
780 );
781 }
782 }
783
784 // Add new links to current breadcrumbs array
785 if(!empty($links) && is_array($links)) {
786 $first_element = reset($links);
787 $last_element = end($links);
788 $breadcrumbs = (!empty($breadcrumbs)) ? $breadcrumbs : array();
789
790 $links = array_merge(array($first_element), $breadcrumbs, array($last_element));
791 }
792
793 return array_filter($links);
794 }
795
796 /**
797 * 7. Support WooCommerce Wishlist Plugin
798 */
799 function ti_woocommerce_wishlist_uris($uri_parts, $request_url, $endpoints) {
800 global $permalink_manager_uris, $wp;
801
802 $wishlist_pid = tinv_get_option('general', 'page_wishlist');
803
804 // Find the Wishlist page URI
805 if(is_numeric($wishlist_pid) && !empty($permalink_manager_uris[$wishlist_pid])) {
806 $wishlist_uri = preg_quote($permalink_manager_uris[$wishlist_pid], '/');
807
808 // Extract the Wishlist ID
809 preg_match("/^({$wishlist_uri})\/([^\/]+)\/?$/", $uri_parts['uri'], $output_array);
810
811 if(!empty($output_array[2])) {
812 $uri_parts['uri'] = $output_array[1];
813 $uri_parts['endpoint'] = 'tinvwlID';
814 $uri_parts['endpoint_value'] = $output_array[2];
815 }
816 }
817
818 return $uri_parts;
819 }
820
821 /**
822 * 8. Revisionize
823 */
824 function revisionize_keep_post_uri($old_id, $new_id) {
825 global $permalink_manager_uris;
826
827 // Copy the custom URI from original post and apply it to the new temp. revision post
828 if(!empty($permalink_manager_uris[$old_id])) {
829 $permalink_manager_uris[$new_id] = $permalink_manager_uris[$old_id];
830
831 update_option('permalink-manager-uris', $permalink_manager_uris);
832 }
833 }
834
835 function revisionize_clone_uri($old_id, $new_id) {
836 global $permalink_manager_uris;
837
838 if(!empty($permalink_manager_uris[$new_id])) {
839 // Copy the custom URI from revision post and apply it to the original post
840 $permalink_manager_uris[$old_id] = $permalink_manager_uris[$new_id];
841 unset($permalink_manager_uris[$new_id]);
842
843 update_option('permalink-manager-uris', $permalink_manager_uris);
844 }
845 }
846
847 /**
848 * 9. WP All Import
849 */
850 function wpaiextra_uri_display($post_type, $current_values) {
851
852 // Check if post type is supported
853 if(Permalink_Manager_Helper_Functions::is_disabled($post_type)) { return; }
854
855 // Get custom URI format
856 $custom_uri = (!empty($current_values['custom_uri'])) ? sanitize_text_field($current_values['custom_uri']) : "";
857
858 $html = '<div class="wpallimport-collapsed closed wpallimport-section">';
859 $html .= '<div class="wpallimport-content-section">';
860 $html .= sprintf('<div class="wpallimport-collapsed-header"><h3>%s</h3></div>', __('Permalink Manager', 'permalink-manager'));
861 $html .= '<div class="wpallimport-collapsed-content">';
862
863 $html .= '<div class="template_input">';
864 $html .= Permalink_Manager_Admin_Functions::generate_option_field('custom_uri', array('extra_atts' => 'style="width:100%; line-height: 25px;"', 'placeholder' => __('Custom URI', 'permalink-manager'), 'value' => $custom_uri));
865 $html .= wpautop(sprintf(__('If empty, a default permalink based on your current <a href="%s" target="_blank">permastructure settings</a> will be used.', 'permalink-manager'), Permalink_Manager_Admin_Functions::get_admin_url('&section=permastructs')));
866 $html .= '</div>';
867
868 // $html .= print_r($current_values, true);
869
870 $html .= '</div>';
871 $html .= '</div>';
872 $html .= '</div>';
873
874 echo $html;
875 }
876
877 function wpai_api_options($all_options) {
878 return $all_options + array('custom_uri' => null);
879 }
880
881 function wpai_api_register($addons) {
882 if(empty($addons[PERMALINK_MANAGER_PLUGIN_SLUG])) {
883 $addons[PERMALINK_MANAGER_PLUGIN_SLUG] = 1;
884 }
885 return $addons;
886 }
887
888 function wpai_api_parse($functions) {
889 $functions[PERMALINK_MANAGER_PLUGIN_SLUG] = array($this, 'wpai_api_parse_function');
890 return $functions;
891 }
892 function wpai_api_import($functions) {
893 $functions[PERMALINK_MANAGER_PLUGIN_SLUG] = array($this, 'wpai_api_import_function');
894 return $functions;
895 }
896
897 function wpai_api_parse_function($data) {
898 extract($data);
899
900 $data = array(); // parsed data
901 $option_name = 'custom_uri';
902
903 if(!empty($import->options[$option_name])) {
904 $this->logger = $data['logger'];
905 $cxpath = $xpath_prefix . $import->xpath;
906 $tmp_files = array();
907
908 if(isset($import->options[$option_name]) && $import->options[$option_name] != '') {
909 if($import->options[$option_name] == "xpath") {
910 if ($import->options[$this->slug]['xpaths'][$option_name] == "") {
911 $count and $this->data[$option_name] = array_fill(0, $count, "");
912 } else {
913 $data[$option_name] = XmlImportParser::factory($xml, $cxpath, (string) $import->options['xpaths'][$option_name], $file)->parse();
914 $tmp_files[] = $file;
915 }
916 } else {
917 $data[$option_name] = XmlImportParser::factory($xml, $cxpath, (string) $import->options[$option_name], $file)->parse();
918 $tmp_files[] = $file;
919 }
920 } else {
921 $data[$option_name] = array_fill(0, $count, "");
922 }
923
924 foreach ($tmp_files as $file) {
925 unlink($file);
926 }
927 }
928
929 return $data;
930 }
931
932 function wpai_api_import_function($importData, $parsedData) {
933 global $permalink_manager_uris;
934
935 // Check if post type is disabled
936 if(empty($parsedData) || Permalink_Manager_Helper_Functions::is_disabled($importData['post_type'], 'post_type')) { return; }
937
938 // Get the parsed custom URI
939 $index = (isset($importData['i'])) ? $importData['i'] : false;
940 $pid = (!empty($importData['pid'])) ? $importData['pid'] : false;
941
942 if(isset($index) && isset($pid) && !empty($parsedData['custom_uri'][$index])) {
943 $custom_uri = Permalink_Manager_Helper_Functions::sanitize_title($parsedData['custom_uri'][$index]);
944
945 if(!empty($custom_uri)) {
946 $permalink_manager_uris[$pid] = $custom_uri;
947 update_option('permalink-manager-uris', $permalink_manager_uris);
948 }
949 }
950 }
951
952 function wpai_save_redirects($pid) {
953 global $permalink_manager_external_redirects, $permalink_manager_uris;
954
955 $external_url = get_post_meta($pid, '_external_redirect', true);
956 $external_url = (empty($external_url)) ? get_post_meta($pid, 'external_redirect', true) : $external_url;
957
958 if($external_url && class_exists('Permalink_Manager_Pro_Functions')) {
959 Permalink_Manager_Pro_Functions::save_external_redirect($external_url, $pid);
960 }
961 }
962
963 function wpai_schedule_regenerate_uris_after_xml_import($import_id) {
964 global $wpdb;
965
966 $post_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->prefix}pmxi_posts WHERE import_id = {$import_id}");
967 $chunks = array_chunk($post_ids, 200);
968
969 // Schedule URI regenerate and split into bulks
970 foreach($chunks as $i => $chunk) {
971 wp_schedule_single_event(time() + ($i * 30), 'wpai_regenerate_uris_after_import_event', array($chunk));
972 }
973 }
974
975 function wpai_regenerate_uris_after_import($post_ids) {
976 global $permalink_manager_uris;
977
978 if(!is_array($post_ids)) { return; }
979
980 foreach($post_ids as $id) {
981 if(!empty($permalink_manager_uris[$id])) { continue; }
982 $permalink_manager_uris[$id] = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
983 }
984
985 update_option('permalink-manager-uris', $permalink_manager_uris);
986 }
987
988 /**
989 * 10. Store Locator - CSV Manager
990 */
991 public function wpsl_regenerate_after_import($meta_id, $post_id, $meta_key, $meta_value) {
992 global $permalink_manager_uris;
993
994 if(strpos($meta_key, 'wpsl_') !== false && isset($_POST['wpsl_csv_import_nonce'])) {
995 $default_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($post_id);
996
997 if($default_uri) {
998 $permalink_manager_uris[$post_id] = $default_uri;
999 update_option('permalink-manager-uris', $permalink_manager_uris);
1000 }
1001 }
1002 }
1003
1004 }
1005 ?>
1006