PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 2.2.12
Permalink Manager Lite v2.2.12
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 4 years ago permalink-manager-admin-functions.php 4 years ago permalink-manager-core-functions.php 4 years ago permalink-manager-debug.php 4 years ago permalink-manager-gutenberg.php 4 years ago permalink-manager-helper-functions.php 4 years ago permalink-manager-language-plugins.php 4 years ago permalink-manager-third-parties.php 4 years ago permalink-manager-uri-functions-post.php 4 years ago permalink-manager-uri-functions.php 4 years ago
permalink-manager-third-parties.php
1327 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 $permalink_manager_options;
15
16 // 0. Stop redirect
17 add_action('wp', array($this, 'stop_redirect'), 0);
18
19 // 2. AMP & AMP for WP
20 if(defined('AMP_QUERY_VAR')) {
21 add_filter('permalink_manager_detect_uri', array($this, 'detect_amp'), 10, 2);
22 add_filter('request', array($this, 'enable_amp'), 10, 1);
23 }
24
25 if(defined('AMPFORWP_AMP_QUERY_VAR')) {
26 add_filter('permalink_manager_filter_query', array($this, 'detect_amp_for_wp'), 5);
27 }
28
29 // 4. WooCommerce
30 if(class_exists('WooCommerce')) {
31 add_filter('request', array($this, 'woocommerce_detect'), 20, 1);
32 add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
33
34 if(class_exists('Permalink_Manager_Pro_Functions')) {
35 if(empty($permalink_manager_options['general']['partial_disable']['post_types']) || !in_array('shop_coupon', $permalink_manager_options['general']['partial_disable']['post_types'])) {
36 if(is_admin()) {
37 add_filter('woocommerce_coupon_data_tabs', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_tabs');
38 add_action('woocommerce_coupon_data_panels', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_panel');
39 add_action('woocommerce_coupon_options_save', 'Permalink_Manager_Pro_Functions::woocommerce_save_coupon_uri', 9, 2);
40 }
41
42 add_filter('request', 'Permalink_Manager_Pro_Functions::woocommerce_detect_coupon_code', 1, 1);
43 add_filter('permalink_manager_disabled_post_types', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_uris', 9, 1);
44 }
45 }
46
47 // WooCommerce Import/Export
48 add_filter('woocommerce_product_export_product_default_columns', array($this, 'woocommerce_csv_custom_uri_column'), 9);
49 add_filter('woocommerce_product_export_product_column_custom_uri', array($this, 'woocommerce_export_custom_uri_value'), 9, 3);
50
51 add_filter('woocommerce_csv_product_import_mapping_options', array($this, 'woocommerce_csv_custom_uri_column'), 9);
52 add_filter('woocommerce_csv_product_import_mapping_default_columns', array($this, 'woocommerce_csv_custom_uri_column'), 9);
53 add_action('woocommerce_product_import_inserted_product_object', array($this, 'woocommerce_csv_import_custom_uri'), 9, 2);
54
55 add_action('woocommerce_product_duplicate', array($this, 'woocommerce_generate_permalinks_after_duplicate'), 9, 2);
56 add_filter('permalink_manager_filter_default_post_uri', array($this, 'woocommerce_product_attributes'), 5, 5);
57
58 if(wp_doing_ajax() && class_exists('SitePress')) {
59 add_filter('permalink_manager_filter_final_post_permalink', array($this, 'woocommerce_translate_ajax_fragments_urls'), 9999, 3);
60 }
61 }
62
63 // 5. Theme My Login
64 if(class_exists('Theme_My_Login')) {
65 add_filter('permalink_manager_filter_final_post_permalink', array($this, 'tml_keep_query_parameters'), 9, 3);
66 }
67
68 // 6. Yoast SEO
69 add_filter('wpseo_xml_sitemap_post_url', array($this, 'yoast_fix_sitemap_urls'), 9);
70 if(defined('WPSEO_VERSION') && version_compare(WPSEO_VERSION, '14.0', '>=')) {
71 add_action('permalink_manager_updated_post_uri', array($this, 'yoast_update_indexable_permalink'), 10, 3);
72 add_action('permalink_manager_updated_term_uri', array($this, 'yoast_update_indexable_permalink'), 10, 3);
73 add_filter('wpseo_canonical', array($this, 'yoast_fix_canonical'), 10);
74 add_filter('wpseo_opengraph_url', array($this, 'yoast_fix_canonical'), 10);
75 }
76
77 // 7. Breadcrumbs
78 add_filter('wpseo_breadcrumb_links', array($this, 'filter_breadcrumbs'), 9);
79 add_filter('rank_math/frontend/breadcrumb/items', array($this, 'filter_breadcrumbs'), 9);
80 add_filter('seopress_pro_breadcrumbs_crumbs', array($this, 'filter_breadcrumbs'), 9);
81 add_filter('woocommerce_get_breadcrumb', array($this, 'filter_breadcrumbs'), 9);
82 add_filter('slim_seo_breadcrumbs_links', array($this, 'filter_breadcrumbs'), 9);
83
84 // 8. WooCommerce Wishlist Plugin
85 if(function_exists('tinv_get_option')) {
86 add_filter('permalink_manager_detect_uri', array($this, 'ti_woocommerce_wishlist_uris'), 15, 3);
87 }
88
89 // 9. Revisionize
90 if(defined('REVISIONIZE_ROOT')) {
91 add_action('revisionize_after_create_revision', array($this, 'revisionize_keep_post_uri'), 9, 2);
92 add_action('revisionize_before_publish', array($this,'revisionize_clone_uri'), 9, 2);
93 }
94
95 // 10. WP All Import
96 if(class_exists('PMXI_Plugin') && (!empty($permalink_manager_options['general']['pmxi_support']))) {
97 add_action('pmxi_extend_options_featured', array($this, 'wpaiextra_uri_display'), 9, 2);
98 add_filter('pmxi_options_options', array($this, 'wpai_api_options'));
99 add_filter('pmxi_addons', array($this, 'wpai_api_register'));
100 add_filter('wp_all_import_addon_parse', array($this, 'wpai_api_parse'));
101 add_filter('wp_all_import_addon_import', array($this, 'wpai_api_import'));
102
103 add_action('pmxi_saved_post', array($this, 'wpai_save_redirects'));
104
105 add_action('pmxi_after_xml_import', array($this, 'wpai_schedule_regenerate_uris_after_xml_import'), 10, 1);
106 add_action('wpai_regenerate_uris_after_import_event', array($this, 'wpai_regenerate_uris_after_import'), 10, 1);
107 }
108
109 // 11. WP All Export
110 if(class_exists('PMXE_Plugin') && (!empty($permalink_manager_options['general']['pmxi_support']))) {
111 add_filter('pmxe_available_sections', array($this, 'wpae_custom_uri_section'), 9);
112 add_filter('wp_all_export_available_data', array($this, 'wpae_custom_uri_section_fields'), 9);
113 add_filter('wp_all_export_csv_rows', array($this,'wpae_export_custom_uri'), 10, 2);
114 }
115
116 // 12. Duplicate Post
117 if(defined('DUPLICATE_POST_CURRENT_VERSION')) {
118 add_action('dp_duplicate_post', array($this, 'duplicate_custom_uri'), 100, 2);
119 add_action('dp_duplicate_page', array($this, 'duplicate_custom_uri'), 100, 2);
120 }
121
122 // 13. My Listing by 27collective
123 if(class_exists('\MyListing\Post_Types')) {
124 add_filter('permalink_manager_filter_default_post_uri', array($this, 'ml_listing_custom_fields'), 5, 5 );
125 add_action('mylisting/submission/save-listing-data', array($this, 'ml_set_listing_uri'), 100);
126 add_filter('permalink_manager_filter_query', array($this, 'ml_detect_archives'), 1);
127 }
128
129 // 14. bbPress
130 if(class_exists('bbPress') && function_exists('bbp_get_edit_slug')) {
131 add_filter('permalink_manager_endpoints', array($this, 'bbpress_endpoints'), 9);
132 add_action('wp', array($this, 'bbpress_detect_endpoints'), 0);
133 }
134
135 // 15. Dokan
136 if(class_exists('WeDevs_Dokan')) {
137 add_action('wp', array($this, 'dokan_detect_endpoints'), 999);
138 add_filter('permalink_manager_endpoints', array($this,'dokan_endpoints'));
139 }
140
141 // 16. GeoDirectory
142 if(class_exists('GeoDirectory')) {
143 add_filter('permalink_manager_filter_default_post_uri', array($this, 'geodir_custom_fields'), 5, 5 );
144 }
145
146 // 17. BasePress
147 if(class_exists('Basepress')) {
148 add_filter('permalink_manager_filter_query', array($this, 'kb_adjust_query'), 5, 5);
149 }
150
151 // 18. Ultimate Member
152 if(class_exists('UM') && !(empty($permalink_manager_options['general']['um_support']))) {
153 add_filter('permalink_manager_detect_uri', array($this, 'um_detect_extra_pages'), 20);
154 }
155
156 // 19. WooCommerce Subscriptions
157 if(class_exists('WC_Subscriptions')) {
158 add_filter('permalink_manager_filter_final_post_permalink', array($this, 'fix_wcs_subscription_links'), 10, 3);
159 }
160 }
161
162 /**
163 * Some of the hooks must be called shortly after all the plugins are loaded
164 */
165 public function init_early_hooks() {
166 // WP Store Locator
167 if(class_exists('WPSL_CSV')) {
168 add_action('added_post_meta', array($this, 'wpsl_regenerate_after_import'), 10, 4);
169 add_action('updated_post_meta', array($this, 'wpsl_regenerate_after_import'), 10, 4);
170 }
171 // Woocommerce
172 if(class_exists('WooCommerce')) {
173 add_filter('woocommerce_get_endpoint_url', array('Permalink_Manager_Core_Functions', 'control_trailing_slashes'), 9);
174 }
175 }
176
177 /**
178 * 0. Stop redirect
179 */
180 public static function stop_redirect() {
181 global $wp, $wp_query, $post;
182
183 if(!empty($wp_query->query)) {
184 $query_vars = $wp_query->query;
185
186 // WordPress Photo Seller Plugin
187 if(!empty($query_vars['image_id']) && !empty($query_vars['gallery_id'])) {
188 $wp_query->query_vars['do_not_redirect'] = 1;
189 }
190 // Ultimate Member
191 else if(!empty($query_vars['um_user']) || !empty($query_vars['um_tab']) || (!empty($query_vars['provider']) && !empty($query_vars['state']))) {
192 $wp_query->query_vars['do_not_redirect'] = 1;
193 }
194 // Mailster
195 else if(!empty($query_vars['_mailster_page'])) {
196 $wp_query->query_vars['do_not_redirect'] = 1;
197 }
198 // WP Route
199 else if(!empty($query_vars['WP_Route'])) {
200 $wp_query->query_vars['do_not_redirect'] = 1;
201 }
202 // WooCommerce Wishlist
203 else if(!empty($query_vars['wishlist-action'])) {
204 $wp_query->query_vars['do_not_redirect'] = 1;
205 }
206 // UserPro
207 else if(!empty($query_vars['up_username'])) {
208 $wp_query->query_vars['do_not_redirect'] = 1;
209 }
210 // The Events Calendar
211 else if(!empty($query_vars['eventDisplay'])) {
212 $wp_query->query_vars['do_not_redirect'] = 1;
213 }
214 // Groundhogg
215 else if(class_exists('\Groundhogg\Plugin') && function_exists('\Groundhogg\get_managed_page_name')) {
216 $gh_slug = \Groundhogg\get_managed_page_name();
217
218 if(!empty($gh_slug) && !empty($wp->request) && (strpos($wp->request, $gh_slug) === 0)) {
219 $wp_query->query_vars['do_not_redirect'] = 1;
220 }
221 }
222 // MyListing theme
223 else if(!empty($query_vars['explore_tab']) || !empty($query_vars['explore_region']) || !empty($_POST['submit_job'])) {
224 $wp_query->query_vars['do_not_redirect'] = 1;
225 }
226 // GeoDirectory
227 else if(function_exists('geodir_location_page_id') && !empty($post->ID) && geodir_location_page_id() == $post->ID) {
228 $wp_query->query_vars['do_not_redirect'] = 1;
229 }
230 // RankMath Pro
231 else if(isset($query_vars['schema-preview'])) {
232 $wp_query->query_vars['do_not_redirect'] = 1;
233 }
234 // Theme.co - Pro Theme
235 else if(!empty($_POST['_cs_nonce'])) {
236 $wp_query->query_vars['do_not_redirect'] = 1;
237 }
238 }
239
240 // WPForo
241 if(class_exists('wpForo')) {
242 $forum_page_id = get_option('wpforo_pageid');
243
244 if(!empty($forum_page_id) && !empty($post->ID) && $forum_page_id == $post->ID) {
245 $wp_query->query_vars['do_not_redirect'] = 1;
246 }
247 }
248 }
249
250 /**
251 * 2. AMP hooks
252 */
253 function detect_amp($uri_parts, $request_url) {
254 global $amp_enabled;
255 $amp_query_var = AMP_QUERY_VAR;
256
257 // Check if AMP should be triggered
258 preg_match("/^(.+?)\/({$amp_query_var})?\/?$/i", $uri_parts['uri'], $regex_parts);
259 if(!empty($regex_parts[2])) {
260 $uri_parts['uri'] = $regex_parts[1];
261 $amp_enabled = true;
262 }
263
264 return $uri_parts;
265 }
266
267 function enable_amp($query) {
268 global $amp_enabled;
269
270 if(!empty($amp_enabled)) {
271 $query[AMP_QUERY_VAR] = 1;
272 }
273
274 return $query;
275 }
276
277 function detect_amp_for_wp($query) {
278 global $wp_rewrite, $pm_query;
279
280 $amp_endpoint = AMPFORWP_AMP_QUERY_VAR;
281 $paged_endpoint = $wp_rewrite->pagination_base;
282
283 if(!empty($pm_query['endpoint']) && strpos($pm_query['endpoint_value'], "{$paged_endpoint}/") !== false) {
284 $paged_val = preg_replace("/({$paged_endpoint}\/)([\d]+)/", '$2', $pm_query['endpoint_value']);
285
286 if(!empty($paged_val)) {
287 $query[$amp_endpoint] = 1;
288 $query['paged'] = $paged_val;
289 }
290 }
291
292 return $query;
293 }
294
295 /**
296 * 3. Parse Custom Permalinks import
297 */
298 public static function custom_permalinks_uris() {
299 global $wpdb;
300
301 $custom_permalinks_uris = array();
302
303 // 1. List tags/categories
304 $table = get_option('custom_permalink_table');
305 if($table && is_array($table)) {
306 foreach ( $table as $permalink => $info ) {
307 $custom_permalinks_uris[] = array(
308 'id' => "tax-" . $info['id'],
309 'uri' => trim($permalink, "/")
310 );
311 }
312 }
313
314 // 2. List posts/pages
315 $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 != '';";
316 $posts = $wpdb->get_results($query);
317 foreach($posts as $post) {
318 $custom_permalinks_uris[] = array(
319 'id' => $post->ID,
320 'uri' => trim($post->meta_value, "/"),
321 );
322 }
323
324 return $custom_permalinks_uris;
325 }
326
327 static public function import_custom_permalinks_uris() {
328 global $permalink_manager_uris, $permalink_manager_before_sections_html;
329
330 $custom_permalinks_plugin = 'custom-permalinks/custom-permalinks.php';
331
332 if(is_plugin_active($custom_permalinks_plugin) && !empty($_POST['disable_custom_permalinks'])) {
333 deactivate_plugins($custom_permalinks_plugin);
334 }
335
336 // Get a list of imported URIs
337 $custom_permalinks_uris = self::custom_permalinks_uris();
338
339 if(!empty($custom_permalinks_uris) && count($custom_permalinks_uris) > 0) {
340 foreach($custom_permalinks_uris as $item) {
341 $permalink_manager_uris[$item['id']] = Permalink_Manager_Helper_Functions::sanitize_title($item['uri']);
342 }
343
344 $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message(__( '"Custom Permalinks" URIs were imported!', 'permalink-manager' ), 'updated');
345 update_option('permalink-manager-uris', $permalink_manager_uris);
346 } else {
347 $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message(__( 'No "Custom Permalinks" URIs were imported!', 'permalink-manager' ), 'error');
348 }
349 }
350
351 /**
352 * 4. WooCommerce
353 */
354 function woocommerce_detect($query) {
355 global $woocommerce, $pm_query;
356
357 $shop_page_id = get_option('woocommerce_shop_page_id');
358
359 // WPML - translate shop page id
360 $shop_page_id = apply_filters('wpml_object_id', $shop_page_id, 'page', TRUE);
361
362 // Fix shop page
363 if(get_theme_support('woocommerce') && !empty($pm_query['id']) && is_numeric($pm_query['id']) && $shop_page_id == $pm_query['id']) {
364 $query['post_type'] = 'product';
365 unset($query['pagename']);
366 }
367
368 // Fix WooCommerce pages
369 if(!empty($woocommerce->query->query_vars)) {
370 $query_vars = $woocommerce->query->query_vars;
371
372 foreach($query_vars as $key => $val) {
373 if(isset($query[$key])) {
374 $woocommerce_page = true;
375 $query['do_not_redirect'] = 1;
376 break;
377 }
378 }
379 }
380
381 return $query;
382 }
383
384 function woocommerce_checkout_fix() {
385 global $wp_query, $pm_query, $permalink_manager_options;
386
387 // Redirect from Shop archive to selected page
388 if(is_shop() && empty($pm_query['id'])) {
389 $redirect_mode = (!empty($permalink_manager_options['general']['redirect'])) ? $permalink_manager_options['general']['redirect'] : false;
390 $redirect_shop = apply_filters('permalink_manager_redirect_shop_archive', false);
391 $shop_page = get_option('woocommerce_shop_page_id');
392
393 if($redirect_mode && $redirect_shop && $shop_page && empty($wp_query->query_vars['s'])) {
394 $shop_url = get_permalink($shop_page);
395 wp_safe_redirect($shop_url, $redirect_mode);
396 exit();
397 }
398 }
399
400 // Do not redirect "thank you" & another WooCommerce pages
401 if(is_checkout() || (function_exists('is_wc_endpoint_url') && is_wc_endpoint_url())) {
402 $wp_query->query_vars['do_not_redirect'] = 1;
403 }
404 }
405
406 function woocommerce_generate_permalinks_after_duplicate($new_product, $old_product) {
407 global $permalink_manager_uris;
408
409 if(!empty($new_product)) {
410 $product_id = $new_product->get_id();
411
412 // Ignore variations
413 if($new_product->get_type() !== 'variation') {
414 $custom_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($product_id, false, true);
415
416 Permalink_Manager_URI_Functions::save_single_uri($product_id, $custom_uri, false, true);
417 }
418 }
419 }
420
421 function woocommerce_product_attributes($default_uri, $slug, $post, $post_name, $native_uri) {
422 // Do not affect native URIs
423 if($native_uri == true) { return $default_uri; }
424
425 // Use only for products
426 if(empty($post->post_type) || $post->post_type !== 'product') { return $default_uri; }
427
428 preg_match_all("/%pa_(.[^\%]+)%/", $default_uri, $custom_fields);
429
430 if(!empty($custom_fields[1])) {
431 $product = wc_get_product($post->ID);
432
433 foreach($custom_fields[1] as $i => $custom_field) {
434 $attribute_name = sanitize_title($custom_field);
435 $attribute_value = $product->get_attribute($attribute_name);
436
437 $default_uri = str_replace($custom_fields[0][$i], Permalink_Manager_Helper_Functions::sanitize_title($attribute_value), $default_uri);
438 }
439 }
440
441 return $default_uri;
442 }
443
444 function woocommerce_translate_ajax_fragments_urls($permalink, $post, $old_permalink) {
445 // Use it only if the permalinks are different
446 if($permalink == $old_permalink || $post->post_type !== 'page') {
447 return $permalink;
448 }
449
450 // A. Native WooCommerce AJAX events
451 if(!empty($_REQUEST['wc-ajax'])) {
452 $action = sanitize_title($_REQUEST['wc-ajax']);
453 }
454 // B. Shoptimizer theme
455 else if(!empty($_REQUEST['action'])) {
456 $action = sanitize_title($_REQUEST['action']);
457 }
458
459 // Allowed action names
460 $allowed_actions = array('shoptimizer_pdp_ajax_atc', 'get_refreshed_fragments');
461
462 if(in_array($action, $allowed_actions)) {
463 $translated_post_id = apply_filters('wpml_object_id', $post->ID, 'page');
464 $permalink = ($translated_post_id !== $post->ID) ? get_permalink($translated_post_id) : $permalink;
465 }
466
467 return $permalink;
468 }
469
470 /**
471 * 4A. WooCommerce CSV Import/Export
472 */
473 function woocommerce_csv_custom_uri_column($columns) {
474 if(!is_array($columns)) { return $columns; }
475
476 $label = __('Custom URI', 'permalink-manager');
477 $key = 'custom_uri';
478
479 if(current_filter() == 'woocommerce_csv_product_import_mapping_default_columns') {
480 $columns[$label] = $key;
481 } else {
482 $columns[$key] = $label;
483 }
484
485 return $columns;
486 }
487
488 function woocommerce_export_custom_uri_value($value, $product, $column_id) {
489 if(empty($value) && !empty($product)) {
490 $product_id = $product->get_id();
491
492 // Get custom permalink or default permalink
493 $value = Permalink_Manager_URI_Functions_Post::get_post_uri($product_id);
494 }
495
496 return $value;
497 }
498
499 function woocommerce_csv_import_custom_uri($product, $data) {
500 global $permalink_manager_uris;
501
502 if(!empty($product)) {
503 $product_id = $product->get_id();
504
505 // Ignore variations
506 if($product->get_type() == 'variation') {
507 return;
508 }
509
510 // A. Use default permalink if "Custom URI" is not set and did not exist before
511 if(empty($permalink_manager_uris[$product_id]) && empty($data['custom_uri'])) {
512 $custom_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($product_id, false, true);
513 } else if(!empty($data['custom_uri'])) {
514 $custom_uri = Permalink_Manager_Helper_Functions::sanitize_title($data['custom_uri']);
515 } else {
516 return;
517 }
518
519 Permalink_Manager_URI_Functions::save_single_uri($product_id, $custom_uri, false, true);
520 }
521 }
522
523 /**
524 * 5. Theme My Login
525 */
526 function tml_keep_query_parameters($permalink, $post, $old_permalink) {
527 // Get the query string from old permalink
528 $get_parameters = (($pos = strpos($old_permalink, "?")) !== false) ? substr($old_permalink, $pos) : "";
529
530 return $permalink . $get_parameters;
531 }
532
533 /**
534 * 6. Yoast SEO hooks
535 */
536 function yoast_fix_sitemap_urls($permalink) {
537 if(class_exists('WPSEO_Utils')) {
538 $home_url = WPSEO_Utils::home_url();
539 $home_protocol = parse_url($home_url, PHP_URL_SCHEME);
540
541 $permalink = preg_replace("/^http(s)?/", $home_protocol, $permalink);
542 }
543
544 return $permalink;
545 }
546
547 function yoast_update_indexable_permalink($element_id, $new_uri, $old_uri) {
548 global $wpdb;
549
550 if(!empty($new_uri) && !empty($old_uri) && $new_uri !== $old_uri) {
551 if(current_filter() == 'permalink_manager_updated_term_uri') {
552 $permalink = get_term_link((int) $element_id);
553 $object_type = 'term';
554 } else {
555 $permalink = get_permalink($element_id);
556 $object_type = 'post';
557 }
558
559 if(!empty($permalink)) {
560 $permalink_hash = strlen($permalink) . ':' . md5($permalink);
561 $wpdb->update("{$wpdb->prefix}yoast_indexable", array('permalink' => $permalink, 'permalink_hash' => $permalink_hash), array('object_id' => $element_id, 'object_type' => $object_type), array('%s', '%s'), array('%d', '%s'));
562 }
563 }
564 }
565
566 function yoast_fix_canonical($url) {
567 global $pm_query, $wp_rewrite;
568
569 if(!empty($pm_query['id'])) {
570 $element = get_queried_object();
571
572 if(!empty($element->ID) && !empty($element->post_type)) {
573 $new_url = get_permalink($element->ID);
574
575 // Do not filter if custom canonical URL is set
576 $yoast_canonical_url = get_post_meta($element->ID, '_yoast_wpseo_canonical', true);
577 if(!empty($yoast_canonical_url)) { return $url; }
578
579 if(is_home()) {
580 $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
581 $new_url = ($paged > 1) ? sprintf('%s/%s/%d', trim($new_url, '/'), $wp_rewrite->pagination_base, $paged) : $new_url;
582 } else {
583 $paged = (get_query_var('page')) ? get_query_var('page') : 1;
584 $new_url = ($paged > 1) ? sprintf('%s/%d', trim($new_url, '/'), $paged) : $new_url;
585 }
586 } else if(!empty($element->taxonomy) && !empty($element->term_id)) {
587 $new_url = get_term_link($element, $element->taxonomy);
588
589 // Do not filter if custom canonical URL is set
590 if(class_exists('WPSEO_Taxonomy_Meta')) {
591 $yoast_canonical_url = WPSEO_Taxonomy_Meta::get_term_meta($element, $element->taxonomy, 'canonical' );
592 if(!empty($yoast_canonical_url)) { return $url; }
593 }
594
595 $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
596 if($paged > 1) {
597 $new_url = sprintf('%s/%s/%d', trim($new_url, '/'), $wp_rewrite->pagination_base, $paged);
598 }
599 }
600
601 $url = (!empty($new_url)) ? $new_url : $url;
602 $url = Permalink_Manager_Core_Functions::control_trailing_slashes($url);
603 }
604
605 return $url;
606 }
607
608 /**
609 * 7. Breadcrumbs
610 */
611 function filter_breadcrumbs($links) {
612 // Get post type permastructure settings
613 global $permalink_manager_uris, $permalink_manager_options, $post, $wpdb, $wp, $wp_current_filter, $wp_post_types;
614
615 // Check if the filter should be activated
616 if(empty($permalink_manager_options['general']['yoast_breadcrumbs']) || empty($permalink_manager_uris)) { return $links; }
617
618 // Get current post/page/term (if available)
619 $queried_element = get_queried_object();
620 if(!empty($queried_element->ID)) {
621 $element_id = $queried_element->ID;
622 } else if(!empty($queried_element->term_id)) {
623 $element_id = "tax-{$queried_element->term_id}";
624 }
625
626 // Get the custom permalink (if available) or the current request URL (if unavailable)
627 if(!empty($element_id) && !empty($permalink_manager_uris[$element_id])) {
628 $custom_uri = preg_replace("/([^\/]+)$/", '', $permalink_manager_uris[$element_id]);
629 } else {
630 $custom_uri = trim(preg_replace("/([^\/]+)$/", '', $wp->request), "/");
631 }
632
633 $all_uris = array_flip($permalink_manager_uris);
634 $custom_uri_parts = explode('/', trim($custom_uri));
635 $breadcrumbs = array();
636 $snowball = '';
637 $available_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array(null, null, false, true);
638 $available_post_types = Permalink_Manager_Helper_Functions::get_post_types_array(null, null, true);
639 $available_post_types_archive = Permalink_Manager_Helper_Functions::get_post_types_array('archive_slug', null, true);
640 $current_filter = end($wp_current_filter);
641
642 // Get Yoast Meta (the breadcrumbs titles can be changed in Yoast metabox)
643 $yoast_meta_terms = get_option('wpseo_taxonomy_meta');
644
645 // Get internal breadcrumb elements
646 foreach($custom_uri_parts as $slug) {
647 if(empty($slug)) { continue; }
648
649 $snowball = (empty($snowball)) ? $slug : "{$snowball}/{$slug}";
650
651 // 1A. Try to match any custom URI
652 if($snowball) {
653 $uri = trim($snowball, "/");
654 $element = (!empty($all_uris[$uri])) ? $all_uris[$uri] : false;
655
656 if(!empty($element) && strpos($element, 'tax-') !== false) {
657 $element_id = intval(preg_replace("/[^0-9]/", "", $element));
658 $element = get_term($element_id);
659 } else if(is_numeric($element)) {
660 $element = get_post($element);
661 }
662 }
663
664 // 1B. Try to get term
665 if(empty($element) && !empty($available_taxonomies)) {
666 $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", esc_sql($slug), implode("','", array_keys($available_taxonomies)));
667
668 $element = $wpdb->get_row($sql);
669 }
670
671 // 1C. Try to get page/post
672 if(empty($element) && !empty($available_post_types)) {
673 $sql = sprintf("SELECT ID, post_title, post_type FROM {$wpdb->posts} WHERE post_name = '%s' AND post_status = 'publish' AND post_type IN ('%s') AND post_type != 'attachment' LIMIT 1", esc_sql($slug), implode("','", array_keys($available_post_types)));
674
675 $element = $wpdb->get_row($sql);
676 }
677
678 // 1D. Try to get post type archive
679 if(empty($element) && !empty($available_post_types_archive) && in_array($snowball, $available_post_types_archive)) {
680 $post_type_slug = array_search($snowball, $available_post_types_archive);
681 $element = get_post_type_object($post_type_slug);
682 }
683
684 // 2A. When the term is found, we can add it to the breadcrumbs
685 if(!empty($element->term_id)) {
686 $term_id = apply_filters('wpml_object_id', $element->term_id, $element->taxonomy, true);
687 $term = ($element->term_id !== $term_id) ? get_term($term_id) : $element;
688
689 $title = (!empty($yoast_meta_terms[$term->taxonomy][$term->term_id]['wpseo_bctitle'])) ? $yoast_meta_terms[$term->taxonomy][$term->term_id]['wpseo_bctitle'] : $term->name;
690
691 $breadcrumbs[] = array(
692 'text' => $title,
693 'url' => get_term_link((int) $term->term_id, $term->taxonomy),
694 );
695 }
696 // 2B. When the post/page is found, we can add it to the breadcrumbs
697 else if(!empty($element->ID)) {
698 $page_id = apply_filters('wpml_object_id', $element->ID, $element->post_type, true);
699 $page = ($element->ID !== $page_id) ? get_post($page_id) : $element;
700
701 $title = get_post_meta($page->ID, '_yoast_wpseo_bctitle', true);
702 $title = (!empty($title)) ? $title : $page->post_title;
703
704 $breadcrumbs[] = array(
705 'text' => $title,
706 'url' => get_permalink($page->ID),
707 );
708 }
709 // 2C. When the post archive is found, we can add it to the breadcrumbs
710 else if(!empty($element->rewrite) && (!empty($element->labels->name))) {
711 $breadcrumbs[] = array(
712 'text' => apply_filters('post_type_archive_title', $element->labels->name, $element->name),
713 'url' => get_post_type_archive_link($element->name),
714 );
715 }
716 }
717
718 // Add new links to current breadcrumbs array
719 if(!empty($links) && is_array($links)) {
720 $first_element = reset($links);
721 $last_element = end($links);
722 $breadcrumbs = (!empty($breadcrumbs)) ? $breadcrumbs : array();
723
724 // Support RankMath/SEOPress/WooCommerce/Slim SEO breadcrumbs
725 if(in_array($current_filter, array('wpseo_breadcrumb_links', 'rank_math/frontend/breadcrumb/items', 'seopress_pro_breadcrumbs_crumbs', 'woocommerce_get_breadcrumb', 'slim_seo_breadcrumbs_links'))) {
726 foreach($breadcrumbs as &$breadcrumb) {
727 if(isset($breadcrumb['text'])) {
728 $breadcrumb[0] = $breadcrumb['text'];
729 $breadcrumb[1] = $breadcrumb['url'];
730 }
731 }
732 }
733
734 if(in_array($current_filter, array('slim_seo_breadcrumbs_links'))) {
735 $links = array_merge(array($first_element), $breadcrumbs);
736 } else {
737 $links = array_merge(array($first_element), $breadcrumbs, array($last_element));
738 }
739 }
740
741 return array_filter($links);
742 }
743
744 /**
745 * 8. Support WooCommerce Wishlist Plugin
746 */
747 function ti_woocommerce_wishlist_uris($uri_parts, $request_url, $endpoints) {
748 global $permalink_manager_uris, $wp;
749
750 $wishlist_pid = tinv_get_option('general', 'page_wishlist');
751
752 // Find the Wishlist page URI
753 if(is_numeric($wishlist_pid) && !empty($permalink_manager_uris[$wishlist_pid])) {
754 $wishlist_uri = preg_quote($permalink_manager_uris[$wishlist_pid], '/');
755
756 // Extract the Wishlist ID
757 preg_match("/^({$wishlist_uri})\/([^\/]+)\/?$/", $uri_parts['uri'], $output_array);
758
759 if(!empty($output_array[2])) {
760 $uri_parts['uri'] = $output_array[1];
761 $uri_parts['endpoint'] = 'tinvwlID';
762 $uri_parts['endpoint_value'] = $output_array[2];
763 }
764 }
765
766 return $uri_parts;
767 }
768
769 /**
770 * 9. Revisionize
771 */
772 function revisionize_keep_post_uri($old_id, $new_id) {
773 global $permalink_manager_uris;
774
775 // Copy the custom URI from original post and apply it to the new temp. revision post
776 if(!empty($permalink_manager_uris[$old_id])) {
777 $permalink_manager_uris[$new_id] = $permalink_manager_uris[$old_id];
778
779 update_option('permalink-manager-uris', $permalink_manager_uris);
780 }
781 }
782
783 function revisionize_clone_uri($old_id, $new_id) {
784 global $permalink_manager_uris;
785
786 if(!empty($permalink_manager_uris[$new_id])) {
787 // Copy the custom URI from revision post and apply it to the original post
788 $permalink_manager_uris[$old_id] = $permalink_manager_uris[$new_id];
789 unset($permalink_manager_uris[$new_id]);
790
791 update_option('permalink-manager-uris', $permalink_manager_uris);
792 }
793 }
794
795 /**
796 * 10. WP All Import
797 */
798 function wpaiextra_uri_display($content_type, $current_values) {
799 // Check if post type is supported
800 if($content_type !== 'taxonomies' && Permalink_Manager_Helper_Functions::is_post_type_disabled($content_type)) {
801 return;
802 }
803
804 // Get custom URI format
805 $custom_uri = (!empty($current_values['custom_uri'])) ? sanitize_text_field($current_values['custom_uri']) : "";
806
807 $html = '<div class="wpallimport-collapsed closed wpallimport-section">';
808 $html .= '<div class="wpallimport-content-section">';
809 $html .= sprintf('<div class="wpallimport-collapsed-header"><h3>%s</h3></div>', __('Permalink Manager', 'permalink-manager'));
810 $html .= '<div class="wpallimport-collapsed-content">';
811
812 $html .= '<div class="template_input">';
813 $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));
814 $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')));
815 $html .= '</div>';
816
817 // $html .= print_r($current_values, true);
818
819 $html .= '</div>';
820 $html .= '</div>';
821 $html .= '</div>';
822
823 echo $html;
824 }
825
826 function wpai_api_options($all_options) {
827 return $all_options + array('custom_uri' => null);
828 }
829
830 function wpai_api_register($addons) {
831 if(empty($addons[PERMALINK_MANAGER_PLUGIN_SLUG])) {
832 $addons[PERMALINK_MANAGER_PLUGIN_SLUG] = 1;
833 }
834 return $addons;
835 }
836
837 function wpai_api_parse($functions) {
838 $functions[PERMALINK_MANAGER_PLUGIN_SLUG] = array($this, 'wpai_api_parse_function');
839 return $functions;
840 }
841
842 function wpai_api_import($functions) {
843 $functions[PERMALINK_MANAGER_PLUGIN_SLUG] = array($this, 'wpai_api_import_function');
844 return $functions;
845 }
846
847 function wpai_api_parse_function($data) {
848 extract($data);
849
850 $data = array(); // parsed data
851 $option_name = 'custom_uri';
852
853 if(!empty($import->options[$option_name])) {
854 $this->logger = $data['logger'];
855 $cxpath = $xpath_prefix . $import->xpath;
856 $tmp_files = array();
857
858 if(isset($import->options[$option_name]) && $import->options[$option_name] != '') {
859 if($import->options[$option_name] == "xpath") {
860 if ($import->options[$this->slug]['xpaths'][$option_name] == "") {
861 $count and $this->data[$option_name] = array_fill(0, $count, "");
862 } else {
863 $data[$option_name] = XmlImportParser::factory($xml, $cxpath, (string) $import->options['xpaths'][$option_name], $file)->parse();
864 $tmp_files[] = $file;
865 }
866 } else {
867 $data[$option_name] = XmlImportParser::factory($xml, $cxpath, (string) $import->options[$option_name], $file)->parse();
868 $tmp_files[] = $file;
869 }
870 } else {
871 $data[$option_name] = array_fill(0, $count, "");
872 }
873
874 foreach ($tmp_files as $file) {
875 unlink($file);
876 }
877 }
878
879 return $data;
880 }
881
882 function wpai_api_import_function($importData, $parsedData) {
883 global $permalink_manager_uris;
884
885 // Check if the array with $parsedData is not empty
886 if(empty($parsedData) || empty($importData['post_type'])) { return; }
887
888 // Check if the imported elements are terms
889 if($importData['post_type'] == 'taxonomies') {
890 $is_term = true;
891 } else if(Permalink_Manager_Helper_Functions::is_post_type_disabled($importData['post_type'])) {
892 return;
893 }
894
895 // Get the parsed custom URI
896 $index = (isset($importData['i'])) ? $importData['i'] : false;
897 $pid = (!empty($importData['pid'])) ? $importData['pid'] : false;
898
899 // Prepend "tax-" prefix if needed
900 $pid = (!empty($is_term) && !empty($pid)) ? "tax-{$pid}" : $pid;
901
902 if(isset($index) && !empty($pid) && !empty($parsedData['custom_uri'][$index])) {
903 $custom_uri = Permalink_Manager_Helper_Functions::sanitize_title($parsedData['custom_uri'][$index]);
904
905 if(!empty($custom_uri)) {
906 $permalink_manager_uris[$pid] = $custom_uri;
907 update_option('permalink-manager-uris', $permalink_manager_uris);
908 }
909 }
910 }
911
912 function wpai_save_redirects($pid) {
913 global $permalink_manager_external_redirects, $permalink_manager_uris;
914
915 $external_url = get_post_meta($pid, '_external_redirect', true);
916 $external_url = (empty($external_url)) ? get_post_meta($pid, 'external_redirect', true) : $external_url;
917
918 if($external_url && class_exists('Permalink_Manager_Pro_Functions')) {
919 Permalink_Manager_Pro_Functions::save_external_redirect($external_url, $pid);
920 }
921 }
922
923 function wpai_schedule_regenerate_uris_after_xml_import($import_id) {
924 global $wpdb;
925
926 $post_ids = $wpdb->get_col("SELECT post_id FROM {$wpdb->prefix}pmxi_posts WHERE import_id = {$import_id}");
927 $chunks = array_chunk($post_ids, 200);
928
929 // Schedule URI regenerate and split into bulks
930 foreach($chunks as $i => $chunk) {
931 wp_schedule_single_event(time() + ($i * 30), 'wpai_regenerate_uris_after_import_event', array($chunk));
932 }
933 }
934
935 function wpai_regenerate_uris_after_import($post_ids) {
936 global $permalink_manager_uris;
937
938 if(!is_array($post_ids)) { return; }
939
940 foreach($post_ids as $id) {
941 if(!empty($permalink_manager_uris[$id])) { continue; }
942 $permalink_manager_uris[$id] = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
943 }
944
945 update_option('permalink-manager-uris', $permalink_manager_uris);
946 }
947
948 /**
949 * 11. WP All Export
950 */
951 function wpae_custom_uri_section($sections) {
952 if(is_array($sections)) {
953 $sections['permalink_manager'] = array(
954 'title' => __('Permalink Manager', 'permalink-manager'),
955 'content' => 'permalink_manager_fields'
956 );
957 }
958
959 return $sections;
960 }
961
962 function wpae_custom_uri_section_fields($fields) {
963 if(is_array($fields)) {
964 $fields['permalink_manager_fields'] = array(
965 array(
966 'label' => 'custom_uri',
967 'name' => 'Custom URI',
968 'type' => 'custom_uri'
969 )
970 );
971 }
972
973 return $fields;
974 }
975
976 function wpae_export_custom_uri($articles, $options) {
977 foreach($articles as &$article) {
978 if(!empty($article['id'])) {
979 $article['Custom URI'] = Permalink_Manager_URI_Functions_Post::get_post_uri($article['id']);
980 }
981 }
982
983 return $articles;
984 }
985
986 /**
987 * 12. Duplicate Page
988 */
989 function duplicate_custom_uri($new_post_id, $old_post) {
990 global $permalink_manager_uris;
991
992 $duplicate_post_blacklist = get_option('duplicate_post_blacklist', false);
993 $duplicate_custom_uri_bool = (!empty($duplicate_post_blacklist) && strpos($duplicate_post_blacklist, 'custom_uri') !== false) ? false : true;
994
995 if(!empty($old_post->ID) && $duplicate_custom_uri_bool) {
996 $old_post_id = intval($old_post->ID);
997
998 // Clone custom permalink (if set for cloned post/page)
999 if(!empty($permalink_manager_uris[$old_post_id])) {
1000 $old_post_uri = $permalink_manager_uris[$old_post_id];
1001 $new_post_uri = preg_replace('/(.+?)(\.[^\.]+$|$)/', '$1-2$2', $old_post_uri);
1002
1003 $permalink_manager_uris[$new_post_id] = $new_post_uri;
1004 update_option('permalink-manager-uris', $permalink_manager_uris);
1005 }
1006 }
1007 }
1008
1009 /**
1010 * 13. My Listing by 27collective
1011 */
1012 public function ml_listing_custom_fields($default_uri, $native_slug, $element, $slug, $native_uri) {
1013 global $permalink_manager_uris;
1014
1015 // Use only for "listing" post type & custom permalink
1016 if(empty($element->post_type) || $element->post_type !== 'job_listing') { return $default_uri; }
1017
1018 // A1. Listing type
1019 if(strpos($default_uri, '%listing-type%') !== false || strpos($default_uri, '%listing_type%') !== false) {
1020 if(class_exists('MyListing\Src\Listing')) {
1021 $listing_type_post = MyListing\Src\Listing::get($element);
1022 $listing_type = (is_object($listing_type_post) && !empty($listing_type_post->type)) ? $listing_type_post->type->get_permalink_name() : '';
1023 } else {
1024 $listing_type_slug = get_post_meta($element->ID, '_case27_listing_type', true);
1025 $listing_type_post = get_page_by_path($listing_type_slug, OBJECT, 'case27_listing_type');
1026
1027 if(!empty($listing_type_post)) {
1028 $listing_type_post_settings = get_post_meta($listing_type_post->ID, 'case27_listing_type_settings_page', true);
1029 $listing_type_post_settings = (is_serialized($listing_type_post_settings)) ? unserialize($listing_type_post_settings) : array();
1030
1031 $listing_type = (!empty($listing_type_post_settings['permalink'])) ? $listing_type_post_settings['permalink'] : $listing_type_post->post_name;
1032 }
1033 }
1034
1035 if(!empty($listing_type)) {
1036 $default_uri = str_replace(array('%listing-type%', '%listing_type%'), Permalink_Manager_Helper_Functions::sanitize_title($listing_type, true), $default_uri);
1037 }
1038 }
1039
1040 // A2. Listing type (slug)
1041 if(strpos($default_uri, '%listing-type-slug%') !== false || strpos($default_uri, '%listing_type_slug%') !== false || strpos($default_uri, '%case27_listing_type%') !== false) {
1042 $listing_type = get_post_meta($element->ID, '_case27_listing_type', true);
1043
1044 if(!empty($listing_type)) {
1045 $listing_type = Permalink_Manager_Helper_Functions::sanitize_title($listing_type, true);
1046 $default_uri = str_replace(array('%listing-type-slug%', '%listing_type_slug%', '%case27_listing_type%'), $listing_type, $default_uri);
1047 }
1048 }
1049
1050 // B. Listing location
1051 if(strpos($default_uri, '%listing-location%') !== false || strpos($default_uri, '%listing_location%') !== false) {
1052 $listing_location = get_post_meta($element->ID, '_job_location', true);
1053
1054 if(!empty($listing_location)) {
1055 $listing_location = Permalink_Manager_Helper_Functions::sanitize_title($listing_location, true);
1056 $default_uri = str_replace(array('%listing-location%', '%listing_location%'), $listing_location, $default_uri);
1057 }
1058 }
1059
1060 // C. Listing region
1061 if(strpos($default_uri, '%listing-region%') !== false || strpos($default_uri, '%listing_region%') !== false) {
1062 $listing_region_terms = wp_get_object_terms($element->ID, 'region');
1063 $listing_region_term = (!is_wp_error($listing_region_terms) && !empty($listing_region_terms) && is_object($listing_region_terms[0])) ? Permalink_Manager_Helper_Functions::get_lowest_element($listing_region_terms[0], $listing_region_terms) : "";
1064
1065 if(!empty($listing_region_term)) {
1066 $listing_region = Permalink_Manager_Helper_Functions::get_term_full_slug($listing_region_term, $listing_region_terms, 2, false);
1067 $listing_region = Permalink_Manager_Helper_Functions::sanitize_title($listing_region, true);
1068
1069 $default_uri = str_replace(array('%listing-region%', '%listing_region%'), $listing_region, $default_uri);
1070 }
1071 }
1072
1073 // D. Listing category
1074 if(strpos($default_uri, '%listing-category%') !== false || strpos($default_uri, '%listing_category%') !== false) {
1075 $listing_category_terms = wp_get_object_terms($element->ID, 'job_listing_category');
1076 $listing_category_term = (!is_wp_error($listing_category_terms) && !empty($listing_category_terms) && is_object($listing_category_terms[0])) ? Permalink_Manager_Helper_Functions::get_lowest_element($listing_category_terms[0], $listing_category_terms) : "";
1077
1078 if(!empty($listing_category_term)) {
1079 $listing_category = Permalink_Manager_Helper_Functions::get_term_full_slug($listing_category_term, $listing_category_terms, 2, false);
1080 $listing_category = Permalink_Manager_Helper_Functions::sanitize_title($listing_category, true);
1081
1082 $default_uri = str_replace(array('%listing-category%', '%listing_category%'), $listing_category, $default_uri);
1083 }
1084 }
1085
1086 return $default_uri;
1087 }
1088
1089 function ml_set_listing_uri($post_id) {
1090 global $permalink_manager_uris;
1091
1092 if(!empty($permalink_manager_uris)) {
1093 $default_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($post_id);
1094
1095 if($default_uri) {
1096 $permalink_manager_uris[$post_id] = $default_uri;
1097 update_option('permalink-manager-uris', $permalink_manager_uris);
1098 }
1099 }
1100 }
1101
1102 function ml_detect_archives($query) {
1103 if(function_exists('mylisting_custom_taxonomies') && empty($_POST['submit_job'])) {
1104 $explore_page_id = get_option('options_general_explore_listings_page', false);
1105 if(empty($explore_page_id)) { return $query; }
1106
1107 $taxonomies = mylisting_custom_taxonomies();
1108 $taxonomies = array_merge(array_keys($taxonomies), array('job_listing_category', 'region', 'case27_job_listing_tags'));
1109
1110 // Check if any MyListing taxonomy was detected
1111 foreach($taxonomies as $taxonomy) {
1112 if(!empty($query[$taxonomy]) && empty($_GET[$taxonomy])) {
1113 return array(
1114 "page_id" => $explore_page_id,
1115 "explore_tab" => $taxonomy,
1116 "explore_{$taxonomy}" => $query['term']
1117 );
1118 }
1119 }
1120 }
1121
1122 return $query;
1123 }
1124
1125 /**
1126 * 14. bbPress
1127 */
1128 function bbpress_endpoints($endpoints, $all = true) {
1129 $bbpress_endpoints = array();
1130 $bbpress_endpoints[] = bbp_get_edit_slug();
1131 // $bbpress_endpoints[] = bbp_get_paged_slug();
1132
1133 return ($all) ? $endpoints . "|" . implode("|", $bbpress_endpoints) : $bbpress_endpoints;
1134 }
1135
1136 function bbpress_detect_endpoints() {
1137 global $wp_query;
1138
1139 if(!empty($wp_query->query)) {
1140 $edit_endpoint = bbp_get_edit_slug();
1141
1142 if(isset($wp_query->query[$edit_endpoint])) {
1143 if(isset($wp_query->query['forum'])) {
1144 $wp_query->bbp_is_forum_edit = true;
1145 } else if(isset($wp_query->query['topic'])) {
1146 $wp_query->bbp_is_topic_edit = true;
1147 } else if(isset($wp_query->query['reply'])) {
1148 $wp_query->bbp_is_reply_edit = true;
1149 }
1150 }
1151 }
1152 }
1153
1154 /**
1155 * 15. Dokan
1156 **/
1157 function dokan_endpoints($endpoints) {
1158 return "{$endpoints}|edit|edit-account";
1159 }
1160
1161 function dokan_detect_endpoints() {
1162 global $post, $wp_query, $wp, $pm_query;
1163
1164 // Check if Dokan is activated
1165 if(!function_exists('dokan_get_option') || is_admin()) { return; }
1166
1167 // Get Dokan dashboard page id
1168 $dashboard_page = dokan_get_option('dashboard', 'dokan_pages');
1169
1170 // Stop the redirect
1171 if(!empty($dashboard_page) && !empty($post->ID) && ($post->ID == $dashboard_page)) {
1172 $wp->query_vars['do_not_redirect'] = 1;
1173
1174 // Detect Dokan shortcode
1175 if(empty($pm_query['endpoint'])) {
1176 $wp->query_vars['page'] = 1;
1177 } else if(isset($wp->query_vars['page'])) {
1178 unset($wp->query_vars['page']);
1179 }
1180 }
1181
1182 // 2. Support "Edit Product" pages
1183 if(isset($wp_query->query_vars['edit'])) {
1184 $wp_query->query_vars['edit'] = 1;
1185 $wp_query->query_vars['do_not_redirect'] = 1;
1186 }
1187 }
1188
1189 /**
1190 * 16. GeoDirectory
1191 */
1192 public function geodir_custom_fields($default_uri, $native_slug, $element, $slug, $native_uri) {
1193 global $permalink_manager_uris;
1194
1195 // Use only for GeoDirectory post types & custom permalinks
1196 if(empty($element->post_type) || (strpos($element->post_type, 'gd_') === false) || $native_uri || !function_exists('geodir_get_post_info')) { return $default_uri; }
1197
1198 // Get place info
1199 $place_data = geodir_get_post_info($element->ID);
1200
1201 // A. Category
1202 if(strpos($default_uri, '%category%') !== false) {
1203 $place_category_terms = wp_get_object_terms($element->ID, 'gd_placecategory');
1204 $place_category_term = (!is_wp_error($place_category_terms) && !empty($place_category_terms) && is_object($place_category_terms[0])) ? Permalink_Manager_Helper_Functions::get_lowest_element($place_category_terms[0], $place_category_terms) : "";
1205
1206 if(!empty($place_category_term)) {
1207 $place_category = Permalink_Manager_Helper_Functions::get_term_full_slug($place_category_term, $place_category_term, 2, false);
1208 $place_category = Permalink_Manager_Helper_Functions::sanitize_title($place_category, true);
1209
1210 $default_uri = str_replace('%category%', $place_category, $default_uri);
1211 }
1212 }
1213
1214 // B. Country
1215 if(strpos($default_uri, '%country%') !== false && !empty($place_data->country)) {
1216 $place_country = Permalink_Manager_Helper_Functions::sanitize_title($place_data->country, true);
1217 $default_uri = str_replace('%country%', $place_country, $default_uri);
1218 }
1219
1220 // C. Region
1221 if(strpos($default_uri, '%region%') !== false && !empty($place_data->region)) {
1222 $place_region = Permalink_Manager_Helper_Functions::sanitize_title($place_data->region, true);
1223 $default_uri = str_replace('%region%', $place_region, $default_uri);
1224 }
1225
1226 // D. City
1227 if(strpos($default_uri, '%city%') !== false && !empty($place_data->city)) {
1228 $place_city = Permalink_Manager_Helper_Functions::sanitize_title($place_data->city, true);
1229 $default_uri = str_replace('%city%', $place_city, $default_uri);
1230 }
1231
1232 return $default_uri;
1233 }
1234
1235 /**
1236 * 17. BasePress
1237 */
1238 function kb_adjust_query($query, $old_query, $uri_parts, $pm_query, $content_type) {
1239 $knowledgebase_options = get_option('basepress_settings');
1240 $knowledgebase_page = (!empty($knowledgebase_options['entry_page'])) ? $knowledgebase_options['entry_page'] : '';
1241
1242 // A. Knowledgebase category
1243 if(isset($query['knowledgebase_cat']) && !empty($pm_query['id']) && strpos($pm_query['id'], 'tax-') !== false) {
1244 $query['post_type'] = 'knowledgebase';
1245 unset($query['taxonomy']);
1246 unset($query['term']);
1247
1248 $term_id = intval(preg_replace("/[^0-9]/", "", $pm_query['id']));
1249 $term = get_term($term_id);
1250
1251 if(empty($term->parent)) {
1252 $query['is_knowledgebase_product'] = 1;
1253 }
1254 }
1255 // B. Knowledgebase main page
1256 else if(!empty($knowledgebase_page) && !empty($pm_query['id']) && $pm_query['id'] == $knowledgebase_page) {
1257 $query = array(
1258 'page_id' => $knowledgebase_page
1259 );
1260 }
1261
1262 return $query;
1263 }
1264
1265 /**
1266 * 18. Ultimate Member
1267 */
1268 public function um_detect_extra_pages($uri_parts) {
1269 global $permalink_manager_uris;
1270
1271 $request_url = trim("{$uri_parts['uri']}/{$uri_parts['endpoint_value']}", "/");
1272 $um_pages = array(
1273 'user' => 'um_user',
1274 'account' => 'um_tab',
1275 );
1276
1277 // Detect UM permalinks
1278 foreach($um_pages as $um_page => $query_var) {
1279 $um_page_id = UM()->config()->permalinks[$um_page];
1280 // Support for WPML/Polylang
1281 $um_page_id = (!empty($uri_parts['lang'])) ? apply_filters('wpml_object_id', $um_page_id, 'page', true, $uri_parts['lang']) : $um_page_id;
1282
1283 if(!empty($um_page_id) && !empty($permalink_manager_uris[$um_page_id])) {
1284 $user_page_uri = preg_quote($permalink_manager_uris[$um_page_id], '/');
1285 preg_match("/^({$user_page_uri})\/([^\/]+)?$/", $request_url, $parts);
1286
1287 if(!empty($parts[2])) {
1288 $uri_parts['uri'] = $parts[1];
1289 $uri_parts['endpoint'] = $query_var;
1290 $uri_parts['endpoint_value'] = Permalink_Manager_Helper_Functions::sanitize_title($parts[2], null, null, false);
1291 }
1292 }
1293 }
1294
1295 return $uri_parts;
1296 }
1297
1298 /**
1299 * 19. WooCommerce Subscriptions
1300 */
1301 function fix_wcs_subscription_links($permalink, $post, $old_permalink) {
1302 if(!empty($post->post_type) && $post->post_type == 'product' && strpos($old_permalink, 'switch-subscription=') !== false) {
1303 $query_arg = parse_url($old_permalink, PHP_URL_QUERY);
1304 $permalink = "{$permalink}?{$query_arg}";
1305 }
1306
1307 return $permalink;
1308 }
1309
1310 /**
1311 * 20. Store Locator - CSV Manager
1312 */
1313 public function wpsl_regenerate_after_import($meta_id, $post_id, $meta_key, $meta_value) {
1314 global $permalink_manager_uris;
1315
1316 if(strpos($meta_key, 'wpsl_') !== false && isset($_POST['wpsl_csv_import_nonce'])) {
1317 $default_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($post_id);
1318
1319 if($default_uri) {
1320 $permalink_manager_uris[$post_id] = $default_uri;
1321 update_option('permalink-manager-uris', $permalink_manager_uris);
1322 }
1323 }
1324 }
1325
1326 }
1327