Permalink Manager Lite - Version 2.2.8.9

Version Description

Download this release

Release Info

Developer mbis
Plugin Icon 128x128 Permalink Manager Lite
Version 2.2.8.9
Comparing to
See all releases

Code changes from version 2.2.8.7 to 2.2.8.9

README.txt CHANGED
@@ -6,10 +6,10 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
6
  Tags: permalinks, custom permalinks, url editor, permalinks, woocommerce permalinks
7
  Requires at least: 4.4.0
8
  Requires PHP: 5.4
9
- Tested up to: 5.4.2
10
- Stable tag: 2.2.8.7
11
 
12
- Permalink Manager Pro allows to easily change full URL addresses of posts, pages, custom post types, terms and WooCommerce links. You can also set different permalink formats per language or bulk change the URLs.
13
 
14
  == Description ==
15
 
@@ -103,6 +103,18 @@ It is because Permalink Manager overwrites one of the core Wordpress functionali
103
 
104
  == Changelog ==
105
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  = 2.2.8.7 =
107
  * Improved breadcrumbs hook (better compatibility with WPML/Polylang)
108
  * Hotfix for permalinks used in language switcher on blog/posts page (WPML)
6
  Tags: permalinks, custom permalinks, url editor, permalinks, woocommerce permalinks
7
  Requires at least: 4.4.0
8
  Requires PHP: 5.4
9
+ Tested up to: 5.5.0
10
+ Stable tag: 2.2.8.9
11
 
12
+ Permalink Manager allows to easily change full URL addresses of posts, pages, custom post types, terms and WooCommerce links. You can also set different permalink formats per language or bulk change the URLs.
13
 
14
  == Description ==
15
 
103
 
104
  == Changelog ==
105
 
106
+ = 2.2.8.8/2.2.8.9 =
107
+ * Hotfix for 'redirect_canonical' function (causing a redirect loop)
108
+ * The custom canonical permalink set with Yoast SEO is now no longer overwriten
109
+ * The custom permalinks are no longer saved if the post/term has no title
110
+ * Hotfix for Gutenberg related JS errors
111
+ * Hotfix for Groundhogg plugin
112
+ * Hotfix for "Customize" admin bar menu link
113
+ * Hotfix for WPML's language switcher on posts page
114
+ * Hotfixes for WP 5.5 - blog/posts page + draft template is now loaded correctly
115
+ * Trailing slash redirect code adjustments
116
+ * Added support for GeoDirectory plugin
117
+
118
  = 2.2.8.7 =
119
  * Improved breadcrumbs hook (better compatibility with WPML/Polylang)
120
  * Hotfix for permalinks used in language switcher on blog/posts page (WPML)
includes/core/permalink-manager-actions.php CHANGED
@@ -362,6 +362,11 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
362
  self::fix_uri_duplicates();
363
  }
364
 
 
 
 
 
 
365
  // Save cleared URIs & Redirects
366
  if($removed_uris > 0 || $removed_redirects > 0) {
367
  update_option('permalink-manager-uris', array_filter($permalink_manager_uris));
362
  self::fix_uri_duplicates();
363
  }
364
 
365
+ // 4. Remove items without keys
366
+ /*if(!empty($permalink_manager_uris[null])) {
367
+ unset($permalink_manager_uris[null]);
368
+ }*/
369
+
370
  // Save cleared URIs & Redirects
371
  if($removed_uris > 0 || $removed_redirects > 0) {
372
  update_option('permalink-manager-uris', array_filter($permalink_manager_uris));
includes/core/permalink-manager-admin-functions.php CHANGED
@@ -11,7 +11,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
11
  public function __construct() {
12
  add_action( 'admin_menu', array($this, 'add_menu_page') );
13
  add_action( 'admin_init', array($this, 'init') );
14
- add_action( 'admin_bar_menu', array($this, 'fix_customize_url'), 10);
15
 
16
  add_action( 'admin_notices', array($this, 'display_plugin_notices'));
17
  add_action( 'admin_notices', array($this, 'display_global_notices'));
@@ -38,6 +38,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
38
  */
39
  public function fix_customize_url($wp_admin_bar) {
40
  $object = get_queried_object();
 
41
  $customize = $wp_admin_bar->get_node('customize');
42
 
43
  if(empty($customize->href)) { return; }
11
  public function __construct() {
12
  add_action( 'admin_menu', array($this, 'add_menu_page') );
13
  add_action( 'admin_init', array($this, 'init') );
14
+ add_action( 'admin_bar_menu', array($this, 'fix_customize_url'), 41);
15
 
16
  add_action( 'admin_notices', array($this, 'display_plugin_notices'));
17
  add_action( 'admin_notices', array($this, 'display_global_notices'));
38
  */
39
  public function fix_customize_url($wp_admin_bar) {
40
  $object = get_queried_object();
41
+
42
  $customize = $wp_admin_bar->get_node('customize');
43
 
44
  if(empty($customize->href)) { return; }
includes/core/permalink-manager-core-functions.php CHANGED
@@ -254,6 +254,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
254
  $query[$query_parameter] = $term->slug;
255
  } else {
256
  $broken_uri = true;
 
257
  }
258
  }
259
  /**
@@ -284,7 +285,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
284
  // Fix for hierarchical CPT & pages
285
  if(!(empty($post_to_load->ancestors)) && !empty($post_type_object->hierarchical)) {
286
  foreach ($post_to_load->ancestors as $parent) {
287
- $parent = get_post( $parent );
288
  if($parent && $parent->post_name) {
289
  $final_uri = $parent->post_name . '/' . $final_uri;
290
  }
@@ -294,7 +295,12 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
294
  // Alter query parameters + support drafts URLs
295
  if($post_to_load->post_status == 'draft' || empty($final_uri)) {
296
  if(is_user_logged_in()) {
297
- $query['p'] = $element_id;
 
 
 
 
 
298
  $query['preview'] = true;
299
  $query['post_type'] = $post_type;
300
  } else if($post_to_load->post_status == 'draft') {
@@ -322,6 +328,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
322
  }
323
  } else {
324
  $broken_uri = true;
 
325
  }
326
  }
327
 
@@ -385,14 +392,6 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
385
  }
386
  }
387
 
388
- /**
389
- * 5C. Fix for WPML (language switcher on blog page)
390
- */
391
- $blog_page_id = get_option('page_for_posts');
392
- if(is_numeric($element_id) && !empty($blog_page_id) && ($blog_page_id == $element_id) && !isset($query['page'])) {
393
- $query['page'] = 1;
394
- }
395
-
396
  /**
397
  * 6. Set global with detected item id
398
  */
@@ -472,7 +471,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
472
  $current_page = (empty($wp_query->query_vars['page']) && !empty($wp_query->query_vars['paged'])) ? $wp_query->query_vars['paged'] : $current_page;
473
 
474
  // 2B. Count post pages
475
- $num_pages = substr_count(strtolower($post->post_content), '<!--nextpage-->') + 1;
476
 
477
  $is_404 = ($current_page > 1 && ($current_page > $num_pages)) ? true : false;
478
  }
@@ -534,7 +533,6 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
534
 
535
  // Do not use custom redirects on author pages, search & front page
536
  if(!is_author() && !is_front_page() && !is_home() && !is_feed() && !is_search() && empty($_GET['s'])) {
537
-
538
  // Unset 404 if custom URI is detected
539
  if(isset($pm_query['id'])) {
540
  $wp_query->is_404 = false;
@@ -645,33 +643,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
645
  }
646
 
647
  /**
648
- * 2. Check trailing slashes (ignore links with query parameters)
649
- */
650
- if($trailing_slashes_mode && $trailing_slashes_redirect && empty($correct_permalink) && empty($_SERVER['QUERY_STRING']) && !empty($_SERVER['REQUEST_URI'])) {
651
- // Check if $old_uri ends with slash or not
652
- $ends_with_slash = (substr($old_uri, -1) == "/") ? true : false;
653
- $trailing_slashes_mode = (preg_match("/.*\.([a-zA-Z]{3,4})\/?$/", $old_uri) && $trailing_slashes_mode == 1) ? 2 : $trailing_slashes_mode;
654
-
655
- // Ignore empty URIs
656
- if($old_uri != "/") {
657
- // Remove the trailing slashes (and add them again if needed below)
658
- $old_uri = trim($old_uri, "/");
659
-
660
- // 2A. Force trailing slashes
661
- if($trailing_slashes_mode == 1 && $ends_with_slash == false) {
662
- $correct_permalink = "{$home_url}/{$old_uri}/";
663
- }
664
- // 2B. Remove trailing slashes
665
- else if($trailing_slashes_mode == 2 && $ends_with_slash == true) {
666
- $correct_permalink = "{$home_url}/{$old_uri}";
667
- }
668
- }
669
-
670
- $redirect_type = (!empty($correct_permalink)) ? 'slash_redirect' : '-';
671
- }
672
-
673
- /**
674
- * 3. Check if URL contains duplicated slashes
675
  */
676
  if(!empty($old_uri) && ($old_uri != '/') && preg_match('/\/{2,}/', $old_uri)) {
677
  $new_uri = ltrim(preg_replace('/([^:])([\/]+)/', '$1/', $old_uri), "/");
@@ -679,7 +651,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
679
  }
680
 
681
  /**
682
- * 4. Prevent redirect loop
683
  */
684
  if(!empty($correct_permalink) && is_string($correct_permalink) && !empty($wp->request) && !empty($redirect_type) && $redirect_type !== 'slash_redirect') {
685
  $current_uri = trim($wp->request, "/");
@@ -689,7 +661,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
689
  }
690
 
691
  /**
692
- * 5. Add endpoints to redirect URL
693
  */
694
  if(!empty($correct_permalink) && $endpoint_redirect && ($redirect_type !== 'slash_redirect') && (!empty($pm_query['endpoint_value']) || !empty($pm_query['endpoint']))) {
695
  $endpoint_value = $pm_query['endpoint_value'];
@@ -706,6 +678,32 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
706
  $queried_object = '-';
707
  }
708
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
709
  /**
710
  * 6. WWW prefix | SSL mismatch redirect
711
  */
@@ -744,7 +742,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
744
  }
745
  }
746
 
747
- function adjust_canonical_redirect() {
748
  global $permalink_manager_options, $permalink_manager_uris, $wp, $wp_rewrite;
749
 
750
  // Adjust rewrite settings for trailing slashes
@@ -761,7 +759,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
761
 
762
  // Check if any endpoint is called (fix for feed and similar endpoints)
763
  foreach($endpoints_array as $endpoint) {
764
- if(!empty($wp->query_vars[$endpoint])) {
765
  $wp->query_vars['do_not_redirect'] = 1;
766
  break;
767
  }
@@ -777,16 +775,27 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
777
  }
778
  }
779
 
780
- if(empty($permalink_manager_options['general']['canonical_redirect']) || !empty($wp->query_vars['do_not_redirect'])) {
781
  remove_action('template_redirect', 'redirect_canonical');
782
- add_filter('wpml_is_redirected', '__return_false', 99, 2);
783
- add_filter('pll_check_canonical_url', '__return_false', 99, 2);
784
  }
785
 
786
- if(empty($permalink_manager_options['general']['old_slug_redirect']) || !empty($wp->query_vars['do_not_redirect'])) {
787
  remove_action('template_redirect', 'wp_old_slug_redirect');
788
  }
789
 
 
 
 
 
 
 
 
 
 
 
 
 
 
790
  }
791
 
792
  /**
254
  $query[$query_parameter] = $term->slug;
255
  } else {
256
  $broken_uri = true;
257
+ $query = $old_query;
258
  }
259
  }
260
  /**
285
  // Fix for hierarchical CPT & pages
286
  if(!(empty($post_to_load->ancestors)) && !empty($post_type_object->hierarchical)) {
287
  foreach ($post_to_load->ancestors as $parent) {
288
+ $parent = get_post($parent);
289
  if($parent && $parent->post_name) {
290
  $final_uri = $parent->post_name . '/' . $final_uri;
291
  }
295
  // Alter query parameters + support drafts URLs
296
  if($post_to_load->post_status == 'draft' || empty($final_uri)) {
297
  if(is_user_logged_in()) {
298
+ if($post_type == 'page') {
299
+ $query['page_id'] = $element_id;
300
+ } else {
301
+ $query['p'] = $element_id;
302
+ }
303
+
304
  $query['preview'] = true;
305
  $query['post_type'] = $post_type;
306
  } else if($post_to_load->post_status == 'draft') {
328
  }
329
  } else {
330
  $broken_uri = true;
331
+ $query = $old_query;
332
  }
333
  }
334
 
392
  }
393
  }
394
 
 
 
 
 
 
 
 
 
395
  /**
396
  * 6. Set global with detected item id
397
  */
471
  $current_page = (empty($wp_query->query_vars['page']) && !empty($wp_query->query_vars['paged'])) ? $wp_query->query_vars['paged'] : $current_page;
472
 
473
  // 2B. Count post pages
474
+ $num_pages = (is_home() || is_archive()) ? $wp_query->max_num_pages : substr_count(strtolower($post->post_content), '<!--nextpage-->') + 1;
475
 
476
  $is_404 = ($current_page > 1 && ($current_page > $num_pages)) ? true : false;
477
  }
533
 
534
  // Do not use custom redirects on author pages, search & front page
535
  if(!is_author() && !is_front_page() && !is_home() && !is_feed() && !is_search() && empty($_GET['s'])) {
 
536
  // Unset 404 if custom URI is detected
537
  if(isset($pm_query['id'])) {
538
  $wp_query->is_404 = false;
643
  }
644
 
645
  /**
646
+ * 2. Check if URL contains duplicated slashes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
647
  */
648
  if(!empty($old_uri) && ($old_uri != '/') && preg_match('/\/{2,}/', $old_uri)) {
649
  $new_uri = ltrim(preg_replace('/([^:])([\/]+)/', '$1/', $old_uri), "/");
651
  }
652
 
653
  /**
654
+ * 3. Prevent redirect loop
655
  */
656
  if(!empty($correct_permalink) && is_string($correct_permalink) && !empty($wp->request) && !empty($redirect_type) && $redirect_type !== 'slash_redirect') {
657
  $current_uri = trim($wp->request, "/");
661
  }
662
 
663
  /**
664
+ * 4. Add endpoints to redirect URL
665
  */
666
  if(!empty($correct_permalink) && $endpoint_redirect && ($redirect_type !== 'slash_redirect') && (!empty($pm_query['endpoint_value']) || !empty($pm_query['endpoint']))) {
667
  $endpoint_value = $pm_query['endpoint_value'];
678
  $queried_object = '-';
679
  }
680
 
681
+ /**
682
+ * 5. Check trailing slashes (ignore links with query parameters)
683
+ */
684
+ if($trailing_slashes_mode && $trailing_slashes_redirect && empty($correct_permalink) && empty($_SERVER['QUERY_STRING']) && !empty($_SERVER['REQUEST_URI']) && !is_front_page()) {
685
+ // Check if $old_uri ends with slash or not
686
+ $ends_with_slash = (substr($old_uri, -1) == "/") ? true : false;
687
+ $trailing_slashes_mode = (preg_match("/.*\.([a-zA-Z]{3,4})\/?$/", $old_uri) && $trailing_slashes_mode == 1) ? 2 : $trailing_slashes_mode;
688
+
689
+ // Ignore empty URIs
690
+ if($old_uri != "/") {
691
+ // Remove the trailing slashes (and add them again if needed below)
692
+ $old_uri = trim($old_uri, "/");
693
+
694
+ // 2A. Force trailing slashes
695
+ if($trailing_slashes_mode == 1 && $ends_with_slash == false) {
696
+ $correct_permalink = "{$home_url}/{$old_uri}/";
697
+ }
698
+ // 2B. Remove trailing slashes
699
+ else if($trailing_slashes_mode == 2 && $ends_with_slash == true) {
700
+ $correct_permalink = "{$home_url}/{$old_uri}";
701
+ }
702
+ }
703
+
704
+ $redirect_type = (!empty($correct_permalink)) ? 'slash_redirect' : '-';
705
+ }
706
+
707
  /**
708
  * 6. WWW prefix | SSL mismatch redirect
709
  */
742
  }
743
  }
744
 
745
+ function adjust_canonical_redirect() {
746
  global $permalink_manager_options, $permalink_manager_uris, $wp, $wp_rewrite;
747
 
748
  // Adjust rewrite settings for trailing slashes
759
 
760
  // Check if any endpoint is called (fix for feed and similar endpoints)
761
  foreach($endpoints_array as $endpoint) {
762
+ if(!empty($wp->query_vars[$endpoint]) && $endpoint !== 'attachment') {
763
  $wp->query_vars['do_not_redirect'] = 1;
764
  break;
765
  }
775
  }
776
  }
777
 
778
+ if(empty($permalink_manager_options['general']['canonical_redirect'])) {
779
  remove_action('template_redirect', 'redirect_canonical');
 
 
780
  }
781
 
782
+ if(empty($permalink_manager_options['general']['old_slug_redirect'])) {
783
  remove_action('template_redirect', 'wp_old_slug_redirect');
784
  }
785
 
786
+ if(!empty($wp->query_vars['do_not_redirect'])) {
787
+ // RankMath
788
+ remove_action('template_redirect', 'do_redirection', 11);
789
+ remove_action('wp', 'do_redirection', 11);
790
+
791
+ // SEOPress
792
+ remove_action('template_redirect', 'seopress_category_redirect', 1);
793
+
794
+ remove_action('template_redirect', 'wp_old_slug_redirect');
795
+ remove_action('template_redirect', 'redirect_canonical');
796
+ add_filter('wpml_is_redirected', '__return_false', 99, 2);
797
+ add_filter('pll_check_canonical_url', '__return_false', 99, 2);
798
+ }
799
  }
800
 
801
  /**
includes/core/permalink-manager-gutenberg.php CHANGED
@@ -10,7 +10,19 @@ class Permalink_Manager_Gutenberg extends Permalink_Manager_Class {
10
  }
11
 
12
  public function init() {
13
- // add_action('enqueue_block_editor_assets', array($this, 'pm_gutenberg_scripts'));
 
 
 
 
 
 
 
 
 
 
 
 
14
  add_meta_box('permalink-manager', __('Permalink Manager', 'permalink-manager'), array($this, 'meta_box'), '', 'side', 'high' );
15
  }
16
 
10
  }
11
 
12
  public function init() {
13
+ global $current_screen;
14
+
15
+ // Get displayed post type
16
+ if(empty($current_screen->post_type)) { return; }
17
+ $post_type = $current_screen->post_type;
18
+
19
+ // Check if post type is disabled
20
+ if(Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) { return; }
21
+
22
+ // Stop the hook (if needed)
23
+ $show_uri_editor = apply_filters("permalink_manager_hide_uri_editor_post_{$post_type}", true);
24
+ if(!$show_uri_editor) { return; }
25
+
26
  add_meta_box('permalink-manager', __('Permalink Manager', 'permalink-manager'), array($this, 'meta_box'), '', 'side', 'high' );
27
  }
28
 
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -453,8 +453,9 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
453
  // Trim slashes & whitespaces
454
  $clean = trim($str, " /");
455
 
456
- // Remove accents
457
  $clean = (empty($permalink_manager_options['general']['keep_accents'])) ? remove_accents($clean) : $clean;
 
458
 
459
  $percent_sign = ($keep_percent_sign) ? "\%" : "";
460
  //$sanitize_regex = apply_filters("permalink_manager_sanitize_regex", "/[^\p{Thai}\p{Greek}\p{Hebrew}\p{Arabic}\p{Cyrillic}a-zA-Z0-9{$percent_sign}\/_\.|+, -]/u", $percent_sign);
453
  // Trim slashes & whitespaces
454
  $clean = trim($str, " /");
455
 
456
+ // Remove accents & entities
457
  $clean = (empty($permalink_manager_options['general']['keep_accents'])) ? remove_accents($clean) : $clean;
458
+ $clean = str_replace(array('&lt', '&gt', '&amp'), '', $clean);
459
 
460
  $percent_sign = ($keep_percent_sign) ? "\%" : "";
461
  //$sanitize_regex = apply_filters("permalink_manager_sanitize_regex", "/[^\p{Thai}\p{Greek}\p{Hebrew}\p{Arabic}\p{Cyrillic}a-zA-Z0-9{$percent_sign}\/_\.|+, -]/u", $percent_sign);
includes/core/permalink-manager-language-plugins.php CHANGED
@@ -19,6 +19,10 @@ class Permalink_Manager_Language_Plugins extends Permalink_Manager_Class {
19
  add_filter('permalink_manager_detected_post_id', array($this, 'fix_language_mismatch'), 9, 3);
20
  add_filter('permalink_manager_detected_term_id', array($this, 'fix_language_mismatch'), 9, 3);
21
  }
 
 
 
 
22
 
23
  // URI Editor
24
  add_filter('permalink_manager_uri_editor_extra_info', array($this, 'language_column_uri_editor'), 9, 3);
@@ -96,7 +100,10 @@ class Permalink_Manager_Language_Plugins extends Permalink_Manager_Class {
96
  * WPML/Polylang/TranslatePress filters
97
  */
98
  public static function get_language_code($element) {
99
- global $TRP_LANGUAGE, $translate_press_settings;
 
 
 
100
 
101
  // Fallback
102
  if(is_string($element) && strpos($element, 'tax-') !== false) {
@@ -125,6 +132,9 @@ class Permalink_Manager_Language_Plugins extends Permalink_Manager_Class {
125
  $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
126
  }
127
 
 
 
 
128
  // Use default language if nothing detected
129
  return ($lang_code) ? $lang_code : self::get_default_language();
130
  }
@@ -226,6 +236,24 @@ class Permalink_Manager_Language_Plugins extends Permalink_Manager_Class {
226
  return $item_id;
227
  }
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  function detect_uri_language($uri_parts, $request_url, $endpoints) {
230
  global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
231
 
@@ -440,7 +468,7 @@ class Permalink_Manager_Language_Plugins extends Permalink_Manager_Class {
440
 
441
  // Replace translate endpoint with its original name
442
  foreach($endpoint_translations as $endpoint) {
443
- if(isset($request[$endpoint->translated_endpoint])) {
444
  $request[$endpoint->endpoint] = $request[$endpoint->translated_endpoint];
445
  unset($request[$endpoint->translated_endpoint]);
446
  }
19
  add_filter('permalink_manager_detected_post_id', array($this, 'fix_language_mismatch'), 9, 3);
20
  add_filter('permalink_manager_detected_term_id', array($this, 'fix_language_mismatch'), 9, 3);
21
  }
22
+ // Fix posts page
23
+ else {
24
+ add_filter('permalink_manager_filter_query', array($this, 'fix_posts_page'), 5, 5);
25
+ }
26
 
27
  // URI Editor
28
  add_filter('permalink_manager_uri_editor_extra_info', array($this, 'language_column_uri_editor'), 9, 3);
100
  * WPML/Polylang/TranslatePress filters
101
  */
102
  public static function get_language_code($element) {
103
+ global $TRP_LANGUAGE, $translate_press_settings, $icl_adjust_id_url_filter_off;
104
+
105
+ // Disable WPML adjust ID filter
106
+ $icl_adjust_id_url_filter_off = true;
107
 
108
  // Fallback
109
  if(is_string($element) && strpos($element, 'tax-') !== false) {
132
  $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
133
  }
134
 
135
+ // Enable WPML adjust ID filter
136
+ $icl_adjust_id_url_filter_off = false;
137
+
138
  // Use default language if nothing detected
139
  return ($lang_code) ? $lang_code : self::get_default_language();
140
  }
236
  return $item_id;
237
  }
238
 
239
+ /**
240
+ * 5C. Fix for WPML (language switcher on blog page)
241
+ */
242
+ function fix_posts_page($query, $old_query, $uri_parts, $pm_query, $content_type) {
243
+ if(empty($pm_query['id']) || !is_numeric($pm_query['id'])) {
244
+ return $query;
245
+ }
246
+
247
+ $blog_page_id = apply_filters('wpml_object_id', get_option('page_for_posts'), 'page');
248
+ $element_id = apply_filters('wpml_object_id', $pm_query['id'], 'page');
249
+
250
+ if(!empty($blog_page_id) && !empty($blog_page_id) && ($blog_page_id == $element_id) && !isset($query['page'])) {
251
+ $query['page'] = '';
252
+ }
253
+
254
+ return $query;
255
+ }
256
+
257
  function detect_uri_language($uri_parts, $request_url, $endpoints) {
258
  global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
259
 
468
 
469
  // Replace translate endpoint with its original name
470
  foreach($endpoint_translations as $endpoint) {
471
+ if(isset($request[$endpoint->translated_endpoint]) && ($endpoint->endpoint !== $endpoint->translated_endpoint)) {
472
  $request[$endpoint->endpoint] = $request[$endpoint->translated_endpoint];
473
  unset($request[$endpoint->translated_endpoint]);
474
  }
includes/core/permalink-manager-third-parties.php CHANGED
@@ -105,8 +105,9 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
105
  }
106
 
107
  // 13. bbPress
108
- if(class_exists('bbPress')) {
109
  add_filter('permalink_manager_endpoints', array($this, 'bbpress_endpoints'), 9);
 
110
  }
111
 
112
  // 14. Dokan
@@ -114,6 +115,11 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
114
  add_action('wp', array($this, 'dokan_detect_endpoints'), 999);
115
  add_filter('permalink_manager_endpoints', array($this,'dokan_endpoints'));
116
  }
 
 
 
 
 
117
  }
118
 
119
  /**
@@ -135,7 +141,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
135
  * 0. Stop redirect
136
  */
137
  public static function stop_redirect() {
138
- global $wp_query, $post;
139
 
140
  if(!empty($wp_query->query)) {
141
  $query_vars = $wp_query->query;
@@ -169,11 +175,19 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
169
  $wp_query->query_vars['do_not_redirect'] = 1;
170
  }
171
  // Groundhogg
172
- else if(!empty($query_vars['target_url'])) {
173
- $wp_query->query_vars['do_not_redirect'] = 1;
 
 
 
 
174
  }
175
  // MyListing theme
176
- else if(!empty($query_vars['explore_tab']) || !empty($query_vars['explore_region'])) {
 
 
 
 
177
  $wp_query->query_vars['do_not_redirect'] = 1;
178
  }
179
  }
@@ -419,6 +433,9 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
419
  if(!empty($element->ID) && !empty($element->post_type)) {
420
  $new_url = get_permalink($element->ID);
421
 
 
 
 
422
  $paged = (get_query_var('page')) ? get_query_var('page') : 1;
423
  if($paged > 1) {
424
  $new_url = sprintf('%s/%d', trim($new_url, '/'), $paged);
@@ -813,7 +830,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
813
 
814
  if(!empty($listing_type)) {
815
  $listing_type = Permalink_Manager_Helper_Functions::sanitize_title($listing_type, true);
816
- $default_uri = str_replace(array('%listing-type%', '%listing_type%'), $listing_type, $default_uri);
817
  }
818
  }
819
 
@@ -870,7 +887,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
870
  }
871
 
872
  function ml_detect_archives($query) {
873
- if(function_exists('mylisting_custom_taxonomies')) {
874
  $explore_page_id = get_option('options_general_explore_listings_page', false);
875
  if(empty($explore_page_id)) { return $query; }
876
 
@@ -903,6 +920,24 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
903
  return ($all) ? $endpoints . "|" . implode("|", $bbpress_endpoints) : $bbpress_endpoints;
904
  }
905
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
906
  /**
907
  * 14. Dokan
908
  **/
@@ -911,7 +946,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
911
  }
912
 
913
  function dokan_detect_endpoints() {
914
- global $post, $wp_query, $wp;
915
 
916
  // Check if Dokan is activated
917
  if(!function_exists('dokan_get_option') || is_admin()) { return; }
@@ -926,6 +961,8 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
926
  // Detect Dokan shortcode
927
  if(empty($pm_query['endpoint'])) {
928
  $wp->query_vars['page'] = 1;
 
 
929
  }
930
  }
931
 
@@ -937,7 +974,53 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
937
  }
938
 
939
  /**
940
- * 15. Store Locator - CSV Manager
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
941
  */
942
  public function wpsl_regenerate_after_import($meta_id, $post_id, $meta_key, $meta_value) {
943
  global $permalink_manager_uris;
105
  }
106
 
107
  // 13. bbPress
108
+ if(class_exists('bbPress') && function_exists('bbp_get_edit_slug')) {
109
  add_filter('permalink_manager_endpoints', array($this, 'bbpress_endpoints'), 9);
110
+ add_action('wp', array($this, 'bbpress_detect_endpoints'), 0);
111
  }
112
 
113
  // 14. Dokan
115
  add_action('wp', array($this, 'dokan_detect_endpoints'), 999);
116
  add_filter('permalink_manager_endpoints', array($this,'dokan_endpoints'));
117
  }
118
+
119
+ // 15. GeoDirectory
120
+ if(class_exists('GeoDirectory')) {
121
+ add_filter('permalink_manager_filter_default_post_uri', array($this, 'geodir_custom_fields'), 5, 5 );
122
+ }
123
  }
124
 
125
  /**
141
  * 0. Stop redirect
142
  */
143
  public static function stop_redirect() {
144
+ global $wp, $wp_query, $post;
145
 
146
  if(!empty($wp_query->query)) {
147
  $query_vars = $wp_query->query;
175
  $wp_query->query_vars['do_not_redirect'] = 1;
176
  }
177
  // Groundhogg
178
+ else if(class_exists('\Groundhogg\Plugin') && function_exists('\Groundhogg\get_managed_page_name')) {
179
+ $gh_slug = \Groundhogg\get_managed_page_name();
180
+
181
+ if(!empty($gh_slug) && !empty($wp->request) && (strpos($wp->request, $gh_slug) === 0)) {
182
+ $wp_query->query_vars['do_not_redirect'] = 1;
183
+ }
184
  }
185
  // MyListing theme
186
+ else if(!empty($query_vars['explore_tab']) || !empty($query_vars['explore_region']) || !empty($_POST['submit_job'])) {
187
+ $wp_query->query_vars['do_not_redirect'] = 1;
188
+ }
189
+ // GeoDirectory
190
+ else if(function_exists('geodir_location_page_id') && !empty($post->ID) && geodir_location_page_id() == $post->ID) {
191
  $wp_query->query_vars['do_not_redirect'] = 1;
192
  }
193
  }
433
  if(!empty($element->ID) && !empty($element->post_type)) {
434
  $new_url = get_permalink($element->ID);
435
 
436
+ // Do not filter if custom canonical URL is set
437
+ if(!empty(get_post_meta($element->ID, '_yoast_wpseo_canonical', true))) { return $url; }
438
+
439
  $paged = (get_query_var('page')) ? get_query_var('page') : 1;
440
  if($paged > 1) {
441
  $new_url = sprintf('%s/%d', trim($new_url, '/'), $paged);
830
 
831
  if(!empty($listing_type)) {
832
  $listing_type = Permalink_Manager_Helper_Functions::sanitize_title($listing_type, true);
833
+ $default_uri = str_replace(array('%listing-type-slug%', '%listing_type_slug%'), $listing_type, $default_uri);
834
  }
835
  }
836
 
887
  }
888
 
889
  function ml_detect_archives($query) {
890
+ if(function_exists('mylisting_custom_taxonomies') && empty($_POST['submit_job'])) {
891
  $explore_page_id = get_option('options_general_explore_listings_page', false);
892
  if(empty($explore_page_id)) { return $query; }
893
 
920
  return ($all) ? $endpoints . "|" . implode("|", $bbpress_endpoints) : $bbpress_endpoints;
921
  }
922
 
923
+ function bbpress_detect_endpoints() {
924
+ global $wp_query;
925
+
926
+ if(!empty($wp_query->query)) {
927
+ $edit_endpoint = bbp_get_edit_slug();
928
+
929
+ if(isset($wp_query->query[$edit_endpoint])) {
930
+ if(isset($wp_query->query['forum'])) {
931
+ $wp_query->bbp_is_forum_edit = true;
932
+ } else if(isset($wp_query->query['topic'])) {
933
+ $wp_query->bbp_is_topic_edit = true;
934
+ } else if(isset($wp_query->query['reply'])) {
935
+ $wp_query->bbp_is_reply_edit = true;
936
+ }
937
+ }
938
+ }
939
+ }
940
+
941
  /**
942
  * 14. Dokan
943
  **/
946
  }
947
 
948
  function dokan_detect_endpoints() {
949
+ global $post, $wp_query, $wp, $pm_query;
950
 
951
  // Check if Dokan is activated
952
  if(!function_exists('dokan_get_option') || is_admin()) { return; }
961
  // Detect Dokan shortcode
962
  if(empty($pm_query['endpoint'])) {
963
  $wp->query_vars['page'] = 1;
964
+ } else if(isset($wp->query_vars['page'])) {
965
+ unset($wp->query_vars['page']);
966
  }
967
  }
968
 
974
  }
975
 
976
  /**
977
+ * 15. GeoDirectory
978
+ */
979
+ public function geodir_custom_fields($default_uri, $native_slug, $element, $slug, $native_uri) {
980
+ global $permalink_manager_uris;
981
+
982
+ // Use only for "gd_place" post type & custom permalink
983
+ if(empty($element->post_type) || $element->post_type !== 'gd_place' || $native_uri || !function_exists('geodir_get_post_info')) { return $default_uri; }
984
+
985
+ // Get place info
986
+ $place_data = geodir_get_post_info($element->ID);
987
+
988
+ // A. Category
989
+ if(strpos($default_uri, '%category%') !== false) {
990
+ $place_category_terms = wp_get_object_terms($element->ID, 'gd_placecategory');
991
+ $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) : "";
992
+
993
+ if(!empty($place_category_term)) {
994
+ $place_category = Permalink_Manager_Helper_Functions::get_term_full_slug($place_category_term, $place_category_term, 2, false);
995
+ $place_category = Permalink_Manager_Helper_Functions::sanitize_title($place_category, true);
996
+
997
+ $default_uri = str_replace('%category%', $place_category, $default_uri);
998
+ }
999
+ }
1000
+
1001
+ // B. Country
1002
+ if(strpos($default_uri, '%country%') !== false && !empty($place_data->country)) {
1003
+ $place_country = Permalink_Manager_Helper_Functions::sanitize_title($place_data->country, true);
1004
+ $default_uri = str_replace('%country%', $place_country, $default_uri);
1005
+ }
1006
+
1007
+ // C. Region
1008
+ if(strpos($default_uri, '%region%') !== false && !empty($place_data->region)) {
1009
+ $place_region = Permalink_Manager_Helper_Functions::sanitize_title($place_data->region, true);
1010
+ $default_uri = str_replace('%region%', $place_region, $default_uri);
1011
+ }
1012
+
1013
+ // D. City
1014
+ if(strpos($default_uri, '%city%') !== false && !empty($place_data->city)) {
1015
+ $place_city = Permalink_Manager_Helper_Functions::sanitize_title($place_data->city, true);
1016
+ $default_uri = str_replace('%city%', $place_city, $default_uri);
1017
+ }
1018
+
1019
+ return $default_uri;
1020
+ }
1021
+
1022
+ /**
1023
+ * 16. Store Locator - CSV Manager
1024
  */
1025
  public function wpsl_regenerate_after_import($meta_id, $post_id, $meta_key, $meta_value) {
1026
  global $permalink_manager_uris;
includes/core/permalink-manager-uri-functions-post.php CHANGED
@@ -734,8 +734,8 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
734
  // Ignore menu items
735
  if($post_object->post_type == 'nav_menu_item') { return $post_id; }
736
 
737
- // Ignore auto-drafts & removed posts
738
- if(in_array($post_object->post_status, array('auto-draft', 'trash')) || (!empty($post_object->post_name) && $post_object->post_name == 'auto-draft')) { return $post_id; }
739
 
740
  $native_uri = self::get_default_post_uri($post_id, true);
741
  $new_uri = self::get_default_post_uri($post_id);
@@ -782,8 +782,8 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
782
  // Hotfix for menu items
783
  if($post->post_type == 'nav_menu_item') { return $post_id; }
784
 
785
- // Ignore auto-drafts & removed posts
786
- if(in_array($post->post_status, array('auto-draft', 'trash'))) { return $post_id; }
787
 
788
  // Get auto-update URI setting (if empty use global setting)
789
  if(!empty($_POST["auto_update_uri"])) {
734
  // Ignore menu items
735
  if($post_object->post_type == 'nav_menu_item') { return $post_id; }
736
 
737
+ // Ignore auto-drafts, removed posts and posts without title
738
+ if(in_array($post_object->post_status, array('auto-draft', 'trash')) || empty($post->post_title) || (!empty($post_object->post_name) && $post_object->post_name == 'auto-draft')) { return $post_id; }
739
 
740
  $native_uri = self::get_default_post_uri($post_id, true);
741
  $new_uri = self::get_default_post_uri($post_id);
782
  // Hotfix for menu items
783
  if($post->post_type == 'nav_menu_item') { return $post_id; }
784
 
785
+ // Ignore auto-drafts, removed posts and posts without title
786
+ if(in_array($post->post_status, array('auto-draft', 'trash')) || empty($post->post_title)) { return $post_id; }
787
 
788
  // Get auto-update URI setting (if empty use global setting)
789
  if(!empty($_POST["auto_update_uri"])) {
out/permalink-manager-admin.js CHANGED
@@ -323,36 +323,28 @@ jQuery(document).ready(function() {
323
  /**
324
  * Reload the URI Editor in Gutenberg after the post is published or the title/slug is changed
325
  */
326
- try {
327
- if(typeof wp !== 'undefined' && typeof wp.data !== 'undefined' && typeof wp.data.select !== 'undefined' && typeof wp.blocks !== 'undefined' && typeof wp.data.subscribe !== 'undefined') {
328
- if(wp.data.select('core/editor') == undefined || wp.data.select('core/editor') == null) {
329
- throw "Gutenberg was not loaded correctly!";
330
- }
331
-
332
- wp.data.subscribe(function () {
333
- var isSavingPost = wp.data.select('core/editor').isSavingPost();
334
- var isAutosavingPost = wp.data.select('core/editor').isAutosavingPost();
335
 
336
- if(isSavingPost && !isAutosavingPost) {
337
- old_status = wp.data.select('core/editor').getCurrentPostAttribute('status');
338
- new_status = wp.data.select('core/editor').getEditedPostAttribute('status');
339
 
340
- old_title = wp.data.select('core/editor').getCurrentPostAttribute('title');
341
- new_title = wp.data.select('core/editor').getEditedPostAttribute('title');
342
 
343
- old_slug = wp.data.select('core/editor').getCurrentPostAttribute('slug');
344
- new_slug = wp.data.select('core/editor').getEditedPostAttribute('slug');
345
 
346
- if((old_status !== new_status && new_status == 'publish') || (old_title !== new_title) || (old_slug !== new_slug)) {
347
- setTimeout(function() {
348
- pm_reload_gutenberg_uri_editor();
349
- }, 1500);
350
- }
351
  }
352
- })
353
- };
354
- } catch (e) {
355
- console.log(e);
356
  }
357
 
358
  /**
323
  /**
324
  * Reload the URI Editor in Gutenberg after the post is published or the title/slug is changed
325
  */
326
+ if(typeof wp !== 'undefined' && typeof wp.data !== 'undefined' && typeof wp.data.select !== 'undefined' && typeof wp.blocks !== 'undefined' && typeof wp.data.subscribe !== 'undefined' && wp.data.select('core/editor') !== 'undefined' && wp.data.select('core/editor') !== null) {
327
+ wp.data.subscribe(function() {
328
+ var isSavingPost = wp.data.select('core/editor').isSavingPost();
329
+ var isAutosavingPost = wp.data.select('core/editor').isAutosavingPost();
 
 
 
 
 
330
 
331
+ if(isSavingPost && !isAutosavingPost) {
332
+ old_status = wp.data.select('core/editor').getCurrentPostAttribute('status');
333
+ new_status = wp.data.select('core/editor').getEditedPostAttribute('status');
334
 
335
+ old_title = wp.data.select('core/editor').getCurrentPostAttribute('title');
336
+ new_title = wp.data.select('core/editor').getEditedPostAttribute('title');
337
 
338
+ old_slug = wp.data.select('core/editor').getCurrentPostAttribute('slug');
339
+ new_slug = wp.data.select('core/editor').getEditedPostAttribute('slug');
340
 
341
+ if((old_status !== new_status && new_status == 'publish') || (old_title !== new_title) || (old_slug !== new_slug)) {
342
+ setTimeout(function() {
343
+ pm_reload_gutenberg_uri_editor();
344
+ }, 1500);
 
345
  }
346
+ }
347
+ });
 
 
348
  }
349
 
350
  /**
permalink-manager.php CHANGED
@@ -4,7 +4,7 @@
4
  * Plugin Name: Permalink Manager Lite
5
  * Plugin URI: https://permalinkmanager.pro?utm_source=plugin
6
  * Description: Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
7
- * Version: 2.2.8.7
8
  * Author: Maciej Bis
9
  * Author URI: http://maciejbis.net/
10
  * License: GPL-2.0+
@@ -12,7 +12,7 @@
12
  * Text Domain: permalink-manager
13
  * Domain Path: /languages
14
  * WC requires at least: 3.0.0
15
- * WC tested up to: 4.2.2
16
  */
17
 
18
  // If this file is called directly or plugin is already defined, abort.
@@ -25,7 +25,7 @@ if(!class_exists('Permalink_Manager_Class')) {
25
  // Define the directories used to load plugin files.
26
  define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
27
  define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
28
- define( 'PERMALINK_MANAGER_VERSION', '2.2.8.7' );
29
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
30
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
31
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__));
4
  * Plugin Name: Permalink Manager Lite
5
  * Plugin URI: https://permalinkmanager.pro?utm_source=plugin
6
  * Description: Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
7
+ * Version: 2.2.8.9
8
  * Author: Maciej Bis
9
  * Author URI: http://maciejbis.net/
10
  * License: GPL-2.0+
12
  * Text Domain: permalink-manager
13
  * Domain Path: /languages
14
  * WC requires at least: 3.0.0
15
+ * WC tested up to: 4.3.2
16
  */
17
 
18
  // If this file is called directly or plugin is already defined, abort.
25
  // Define the directories used to load plugin files.
26
  define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
27
  define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
28
+ define( 'PERMALINK_MANAGER_VERSION', '2.2.8.9' );
29
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
30
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
31
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__));