Permalink Manager Lite - Version 2.2.7.3

Version Description

  • Support for "Primary category" set with The SEO Framework
  • Changes for URI Editor section backend (SQL queries + improvements for search box)
  • Improved support for WooCommerce Wishlist plugin
  • Improvements for slugs sanitization functions
  • Possibility to exclude posts from bulk tools added to "Auto-update the URI" dropdown in URI Editor
Download this release

Release Info

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

Code changes from version 2.2.7.2 to 2.2.7.3

README.txt CHANGED
@@ -6,8 +6,8 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
6
  Tags: permalinks, custom permalinks, translate permalinks, woocommerce permalinks
7
  Requires at least: 4.4.0
8
  Requires PHP: 5.4
9
- Tested up to: 5.2.3
10
- Stable tag: 2.2.7.2
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
 
@@ -103,9 +103,15 @@ It is because Permalink Manager overwrites one of the core Wordpress functionali
103
 
104
  == Changelog ==
105
 
106
- = 2.2.7.1/2.2.7.2 =
107
- * Hotfix for PHP Fatal error
108
- * Hotfix for sanitization function: The dashes are no longer removed from custom permalinks.
 
 
 
 
 
 
109
 
110
  = 2.2.7 =
111
  * Force 404 for draft posts (for non-logged-in users)
@@ -119,7 +125,7 @@ It is because Permalink Manager overwrites one of the core Wordpress functionali
119
  * Support for location custom fields in WP Store Locator - CSV Manager plugin
120
  * Improved support for Gutenberg editor (reported by Cedric Busuttil)
121
 
122
- = 2.2.4/2.2.5=
123
  * Minor code improvements
124
  * Yoast SEO Breadcrumbs - further improvements
125
  * Hotfix for Toolset custom fields support (Permalink Manager Pro)
6
  Tags: permalinks, custom permalinks, translate permalinks, woocommerce permalinks
7
  Requires at least: 4.4.0
8
  Requires PHP: 5.4
9
+ Tested up to: 5.2.4
10
+ Stable tag: 2.2.7.3
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
 
103
 
104
  == Changelog ==
105
 
106
+ = 2.2.7.3 =
107
+ * Support for "Primary category" set with The SEO Framework
108
+ * Changes for URI Editor section backend (SQL queries + improvements for search box)
109
+ * Improved support for WooCommerce Wishlist plugin
110
+ * Improvements for slugs sanitization functions
111
+ * Possibility to exclude posts from bulk tools added to "Auto-update the URI" dropdown in URI Editor
112
+
113
+ = 2.2.7.1 =
114
+ * Hotfix for PHP Fatal error in permalink-manager-admin-functions.php file
115
 
116
  = 2.2.7 =
117
  * Force 404 for draft posts (for non-logged-in users)
125
  * Support for location custom fields in WP Store Locator - CSV Manager plugin
126
  * Improved support for Gutenberg editor (reported by Cedric Busuttil)
127
 
128
+ = 2.2.4/2.2.5 =
129
  * Minor code improvements
130
  * Yoast SEO Breadcrumbs - further improvements
131
  * Hotfix for Toolset custom fields support (Permalink Manager Pro)
includes/core/permalink-manager-actions.php CHANGED
@@ -23,7 +23,14 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
23
  global $permalink_manager_after_sections_html;
24
 
25
  // 1. Check if the form was submitted
26
- if(empty($_POST)) { return; }
 
 
 
 
 
 
 
27
 
28
  $actions_map = array(
29
  'uri_editor' => array('function' => 'update_all_permalinks', 'display_uri_table' => true),
@@ -35,7 +42,7 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
35
  'import' => array('function' => 'import_custom_permalinks_uris'),
36
  );
37
 
38
- // 2. Find the action
39
  foreach($actions_map as $action => $map) {
40
  if(isset($_POST[$action]) && wp_verify_nonce($_POST[$action], 'permalink-manager')) {
41
  // Execute the function
@@ -52,7 +59,7 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
52
  }
53
  }
54
 
55
- // 3. Display the slugs table (and append the globals)
56
  if(isset($updated_slugs_count)) {
57
  $permalink_manager_after_sections_html .= Permalink_Manager_Admin_Functions::display_updated_slugs($updated_slugs_array);
58
  }
@@ -231,12 +238,8 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
231
  * Update all permalinks in "Permalink Editor"
232
  */
233
  function update_all_permalinks() {
234
- // Do nothing if search query is not empty
235
- if(!empty($_REQUEST['search-submit'])) {
236
- return;
237
- }
238
  // Check if posts or terms should be updated
239
- else if(!empty($_POST['content_type']) && $_POST['content_type'] == 'taxonomies') {
240
  return Permalink_Manager_URI_Functions_Tax::update_all_permalinks();
241
  } else {
242
  return Permalink_Manager_URI_Functions_Post::update_all_permalinks();
23
  global $permalink_manager_after_sections_html;
24
 
25
  // 1. Check if the form was submitted
26
+ if(empty($_POST)) {
27
+ return;
28
+ }
29
+
30
+ // 2. Do nothing if search query is not empty
31
+ if(isset($_REQUEST['search-submit']) || isset($_REQUEST['months-filter-button'])) {
32
+ return;
33
+ }
34
 
35
  $actions_map = array(
36
  'uri_editor' => array('function' => 'update_all_permalinks', 'display_uri_table' => true),
42
  'import' => array('function' => 'import_custom_permalinks_uris'),
43
  );
44
 
45
+ // 3. Find the action
46
  foreach($actions_map as $action => $map) {
47
  if(isset($_POST[$action]) && wp_verify_nonce($_POST[$action], 'permalink-manager')) {
48
  // Execute the function
59
  }
60
  }
61
 
62
+ // 4. Display the slugs table (and append the globals)
63
  if(isset($updated_slugs_count)) {
64
  $permalink_manager_after_sections_html .= Permalink_Manager_Admin_Functions::display_updated_slugs($updated_slugs_array);
65
  }
238
  * Update all permalinks in "Permalink Editor"
239
  */
240
  function update_all_permalinks() {
 
 
 
 
241
  // Check if posts or terms should be updated
242
+ if(!empty($_POST['content_type']) && $_POST['content_type'] == 'taxonomies') {
243
  return Permalink_Manager_URI_Functions_Tax::update_all_permalinks();
244
  } else {
245
  return Permalink_Manager_URI_Functions_Post::update_all_permalinks();
includes/core/permalink-manager-admin-functions.php CHANGED
@@ -660,16 +660,16 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
660
  }
661
 
662
  // Decode permalink
663
- $permalink = urldecode(urldecode($permalink));
664
 
665
  $main_content .= "<tr{$alternate_class}>";
666
  $main_content .= '<td class="row-title column-primary" data-colname="' . __('Title', 'permalink-manager') . '">' . $row['item_title'] . "<a target=\"_blank\" href=\"{$permalink}\"><span class=\"small\">{$permalink}</span></a>" . '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details', 'permalink-manager') . '</span></button></td>';
667
  if($show_slugs) {
668
- $main_content .= (isset($row['old_slug'])) ? '<td data-colname="' . __('Old Slug', 'permalink-manager') . '">' . urldecode($row['old_slug']) . '</td>' : "";
669
- $main_content .= (isset($row['new_slug'])) ? '<td data-colname="' . __('New Slug', 'permalink-manager') . '">' . urldecode($row['new_slug']) . '</td>' : "";
670
  } else {
671
- $main_content .= '<td data-colname="' . __('Old URI', 'permalink-manager') . '">' . urldecode($row['old_uri']) . '</td>';
672
- $main_content .= '<td data-colname="' . __('New URI', 'permalink-manager') . '">' . urldecode($row['new_uri']) . '</td>';
673
  }
674
  $main_content .= '</tr>';
675
  }
@@ -766,8 +766,9 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
766
  $auto_update_def_label = ($auto_update_def_val) ? __("Yes", "permalink-manager") : __("No", "permalink-manager");
767
  $auto_update_choices = array(
768
  0 => array("label" => sprintf(__("Use global settings [%s]", "permalink-manager"), $auto_update_def_label), "atts" => "data-auto-update=\"{$auto_update_def_val}\""),
 
769
  -1 => array("label" => __("No", "permalink-manager"), "atts" => "data-auto-update=\"0\""),
770
- 1 => array("label" => __("Yes", "permalink-manager"), "atts" => "data-auto-update=\"1\"")
771
  );
772
 
773
  // Get URIs
@@ -788,7 +789,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
788
  }
789
 
790
  // Decode default URI
791
- $default_uri = urldecode($default_uri);
792
 
793
  // Start HTML output
794
  // 1. Button
@@ -823,7 +824,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
823
 
824
  // 5. Native slug
825
  if(!empty($element->ID) && !empty($permalink_manager_options["general"]["show_native_slug_field"])) {
826
- $native_slug_field = Permalink_Manager_Admin_Functions::generate_option_field("native_slug", array("extra_atts" => "data-default=\"{$native_slug}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat native_slug", "value" => urldecode($native_slug)));
827
 
828
  $html .= sprintf("<div class=\"native_slug_container\"><p><label for=\"native_slug\" class=\"strong\">%s %s</label></p><span>%s</span></div>",
829
  __("Native slug", "permalink-manager"),
@@ -859,7 +860,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
859
  "<div class=\"default-permalink-row columns-container\"><span><strong>%s</strong> <a href=\"%s\">%s</a></span></div>",
860
  __("Automatic redirect for native URI enabled:", "permalink-manager"),
861
  $native_permalink,
862
- urldecode($native_uri)
863
  );
864
  }
865
  }
660
  }
661
 
662
  // Decode permalink
663
+ $permalink = rawurldecode(rawurldecode($permalink));
664
 
665
  $main_content .= "<tr{$alternate_class}>";
666
  $main_content .= '<td class="row-title column-primary" data-colname="' . __('Title', 'permalink-manager') . '">' . $row['item_title'] . "<a target=\"_blank\" href=\"{$permalink}\"><span class=\"small\">{$permalink}</span></a>" . '<button type="button" class="toggle-row"><span class="screen-reader-text">' . __('Show more details', 'permalink-manager') . '</span></button></td>';
667
  if($show_slugs) {
668
+ $main_content .= (isset($row['old_slug'])) ? '<td data-colname="' . __('Old Slug', 'permalink-manager') . '">' . rawurldecode($row['old_slug']) . '</td>' : "";
669
+ $main_content .= (isset($row['new_slug'])) ? '<td data-colname="' . __('New Slug', 'permalink-manager') . '">' . rawurldecode($row['new_slug']) . '</td>' : "";
670
  } else {
671
+ $main_content .= '<td data-colname="' . __('Old URI', 'permalink-manager') . '">' . rawurldecode($row['old_uri']) . '</td>';
672
+ $main_content .= '<td data-colname="' . __('New URI', 'permalink-manager') . '">' . rawurldecode($row['new_uri']) . '</td>';
673
  }
674
  $main_content .= '</tr>';
675
  }
766
  $auto_update_def_label = ($auto_update_def_val) ? __("Yes", "permalink-manager") : __("No", "permalink-manager");
767
  $auto_update_choices = array(
768
  0 => array("label" => sprintf(__("Use global settings [%s]", "permalink-manager"), $auto_update_def_label), "atts" => "data-auto-update=\"{$auto_update_def_val}\""),
769
+ 1 => array("label" => __("Yes", "permalink-manager"), "atts" => "data-auto-update=\"1\""),
770
  -1 => array("label" => __("No", "permalink-manager"), "atts" => "data-auto-update=\"0\""),
771
+ -2 => array("label" => __("No (ignore this URI in bulk tools)", "permalink-manager"), "atts" => "data-auto-update=\"2\"")
772
  );
773
 
774
  // Get URIs
789
  }
790
 
791
  // Decode default URI
792
+ $default_uri = rawurldecode($default_uri);
793
 
794
  // Start HTML output
795
  // 1. Button
824
 
825
  // 5. Native slug
826
  if(!empty($element->ID) && !empty($permalink_manager_options["general"]["show_native_slug_field"])) {
827
+ $native_slug_field = Permalink_Manager_Admin_Functions::generate_option_field("native_slug", array("extra_atts" => "data-default=\"{$native_slug}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat native_slug", "value" => rawurldecode($native_slug)));
828
 
829
  $html .= sprintf("<div class=\"native_slug_container\"><p><label for=\"native_slug\" class=\"strong\">%s %s</label></p><span>%s</span></div>",
830
  __("Native slug", "permalink-manager"),
860
  "<div class=\"default-permalink-row columns-container\"><span><strong>%s</strong> <a href=\"%s\">%s</a></span></div>",
861
  __("Automatic redirect for native URI enabled:", "permalink-manager"),
862
  $native_permalink,
863
+ rawurldecode($native_uri)
864
  );
865
  }
866
  }
includes/core/permalink-manager-core-functions.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
 
3
  /**
4
- * Core function
5
  */
6
  class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
7
 
@@ -17,10 +17,6 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
17
  add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
18
  add_filter( 'permalink_manager_filter_post_sample_uri', array($this, 'control_trailing_slashes'), 9);
19
 
20
- // Replace empty placeholder tags & remove BOM
21
- add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5 );
22
- add_filter( 'permalink_manager_filter_default_term_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5 );
23
-
24
  /**
25
  * Detect & canonical URL/redirect functions
26
  */
@@ -142,10 +138,13 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
142
  $uri = strtolower(urldecode($uri));
143
 
144
  foreach($all_uris as $raw_uri => $uri_id) {
145
- $raw_uri = strtolower(urldecode($raw_uri));
146
  $all_uris[$raw_uri] = $uri_id;
147
  }
148
 
 
 
 
149
  $element_id = isset($all_uris[$uri]) ? $all_uris[$uri] : $element_id;
150
  }
151
 
@@ -380,7 +379,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
380
  /**
381
  * Trailing slash & remove BOM and double slashes
382
  */
383
- function control_trailing_slashes($permalink) {
384
  global $permalink_manager_options;
385
 
386
  // Ignore empty permalinks
@@ -476,8 +475,8 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
476
  $old_uri = preg_replace("/{$home_dir_regex}/", "", $old_uri, 1);
477
  }
478
 
479
- // Do not use custom redirects on author pages & front page
480
- if(!is_author() && !is_front_page() && !is_home() && !is_feed()) {
481
 
482
  // Unset 404 if custom URI is detected
483
  if(isset($pm_query['id'])) {
@@ -497,7 +496,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
497
  // Allow redirect
498
  $wp_query->query_vars['do_not_redirect'] = 0;
499
 
500
- wp_redirect($external_url, 301);
501
  exit();
502
  }
503
  }
@@ -630,7 +629,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
630
  $home_url_has_ssl = (strpos($home_url, 'https') !== false) ? true : false;
631
  $requested_url_has_ssl = is_ssl();
632
 
633
- if(($home_url_has_www !==$requested_url_has_www) || ($home_url_has_ssl !== $requested_url_has_ssl)) {
634
  $correct_permalink = "{$home_url}/{$old_uri}";
635
  $redirect_type = 'www_redirect';
636
  }
@@ -651,10 +650,10 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
651
  // Append query string
652
  $correct_permalink = (!empty($query_string)) ? sprintf("%s?%s", strtok($correct_permalink, "?"), $query_string) : $correct_permalink;
653
 
654
- // Remove double slash
655
- $correct_permalink = preg_replace('~(?<!https:|http:)[/\\\\]+~', "/", trim($correct_permalink));
656
 
657
- wp_safe_redirect($correct_permalink, $redirect_mode);
658
  exit();
659
  }
660
  }
@@ -712,29 +711,4 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
712
  }
713
  }
714
 
715
- /**
716
- * Replace empty placeholder tags & remove BOM
717
- */
718
- public static function replace_empty_placeholder_tags($default_uri, $native_slug = "", $element = "", $slug = "", $native_uri = "") {
719
- // Do not affect native URIs
720
- if($native_uri == true) { return $default_uri; }
721
-
722
- // Remove the BOM
723
- $default_uri = str_replace(array("\xEF\xBB\xBF", "%ef%bb%bf"), '', $default_uri);
724
-
725
- // Encode the URI before placeholders are removed
726
- $chunks = explode('/', $default_uri);
727
- foreach ($chunks as &$chunk) {
728
- if(preg_match("/^(%.+?%)$/", $chunk) == false) {
729
- $chunk = urldecode($chunk);
730
- }
731
- }
732
- $default_uri = implode("/", $chunks);
733
-
734
- $empty_tag_replacement = apply_filters('permalink_manager_empty_tag_replacement', null, $element);
735
- $default_uri = ($empty_tag_replacement || is_null($empty_tag_replacement)) ? str_replace("//", "/", preg_replace("/%(.+?)%/", $empty_tag_replacement, $default_uri)) : $default_uri;
736
-
737
- return trim($default_uri, "/");
738
- }
739
-
740
  }
1
  <?php
2
 
3
  /**
4
+ * Core functions
5
  */
6
  class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
7
 
17
  add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
18
  add_filter( 'permalink_manager_filter_post_sample_uri', array($this, 'control_trailing_slashes'), 9);
19
 
 
 
 
 
20
  /**
21
  * Detect & canonical URL/redirect functions
22
  */
138
  $uri = strtolower(urldecode($uri));
139
 
140
  foreach($all_uris as $raw_uri => $uri_id) {
141
+ $raw_uri = urldecode($raw_uri);
142
  $all_uris[$raw_uri] = $uri_id;
143
  }
144
 
145
+ // Convert array keys lowercase
146
+ $all_uris = array_change_key_case($all_uris, CASE_LOWER);
147
+
148
  $element_id = isset($all_uris[$uri]) ? $all_uris[$uri] : $element_id;
149
  }
150
 
379
  /**
380
  * Trailing slash & remove BOM and double slashes
381
  */
382
+ static function control_trailing_slashes($permalink) {
383
  global $permalink_manager_options;
384
 
385
  // Ignore empty permalinks
475
  $old_uri = preg_replace("/{$home_dir_regex}/", "", $old_uri, 1);
476
  }
477
 
478
+ // Do not use custom redirects on author pages, search & front page
479
+ if(!is_author() && !is_front_page() && !is_home() && !is_feed() && !is_search() && empty($_GET['s'])) {
480
 
481
  // Unset 404 if custom URI is detected
482
  if(isset($pm_query['id'])) {
496
  // Allow redirect
497
  $wp_query->query_vars['do_not_redirect'] = 0;
498
 
499
+ wp_redirect($external_url, 301, PERMALINK_MANAGER_PLUGIN_NAME);
500
  exit();
501
  }
502
  }
629
  $home_url_has_ssl = (strpos($home_url, 'https') !== false) ? true : false;
630
  $requested_url_has_ssl = is_ssl();
631
 
632
+ if(($home_url_has_www !== $requested_url_has_www) || ($home_url_has_ssl !== $requested_url_has_ssl)) {
633
  $correct_permalink = "{$home_url}/{$old_uri}";
634
  $redirect_type = 'www_redirect';
635
  }
650
  // Append query string
651
  $correct_permalink = (!empty($query_string)) ? sprintf("%s?%s", strtok($correct_permalink, "?"), $query_string) : $correct_permalink;
652
 
653
+ // Adjust trailing slashes
654
+ $correct_permalink = self::control_trailing_slashes($correct_permalink);
655
 
656
+ wp_safe_redirect($correct_permalink, $redirect_mode, PERMALINK_MANAGER_PLUGIN_NAME);
657
  exit();
658
  }
659
  }
711
  }
712
  }
713
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
714
  }
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -10,9 +10,13 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
10
  }
11
 
12
  public function init() {
 
 
 
 
13
  // Clear the final default URIs
14
- add_filter( 'permalink_manager_filter_default_term_uri', array('Permalink_Manager_Helper_Functions', 'clear_single_uri'), 20);
15
- add_filter( 'permalink_manager_filter_default_post_uri', array('Permalink_Manager_Helper_Functions', 'clear_single_uri'), 20);
16
  }
17
 
18
  /**
@@ -40,15 +44,20 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
40
 
41
  $primary_term_enabled = apply_filters('permalink_manager_primary_term', true);
42
 
43
- if($primary_term_enabled && class_exists('WPSEO_Primary_Term')) {
 
 
44
  $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
45
  $primary_term = get_term($primary_term->get_primary_term());
 
 
 
46
 
47
- if(!is_wp_error($primary_term)) {
48
- return ($slug_only) ? $primary_term->slug : $primary_term;
49
- }
 
50
  }
51
- return '';
52
  }
53
 
54
  /**
@@ -455,28 +464,49 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
455
  $clean = preg_replace("/[\s]+/", "-", $clean);
456
  }
457
 
 
 
 
458
  return $clean;
459
  }
460
 
461
  /**
462
- * Clear the URI
463
  */
464
- public static function clear_single_uri($uri) {
465
- $uri = preg_replace("/[\s_|+-]+/", "-", $uri);
466
- $uri = preg_replace('/([-\s+]\/[-\s+])/', '-', $uri);
467
- $uri = str_replace(array('-/', '/-', '//'), '/', $uri);
468
- $uri = trim($uri, "/");
 
 
 
 
 
 
 
 
 
 
469
 
470
- return $uri;
 
 
 
 
 
 
 
 
 
 
471
  }
472
 
473
  /**
474
  * Remove all slashes
475
  */
476
  public static function remove_slashes($uri) {
477
- $uri = preg_replace("/[\/]+/", "", $uri);
478
-
479
- return $uri;
480
  }
481
 
482
  /**
@@ -489,10 +519,6 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
489
  $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
490
 
491
  if($force_custom_slugs) {
492
- // Decode URI-encoded characters
493
- //$slug = urldecode($slug);
494
- //$title = urldecode($title);
495
-
496
  $title = (!empty($object->name)) ? $object->name : $object->post_title;
497
  $title = self::remove_slashes($title);
498
 
10
  }
11
 
12
  public function init() {
13
+ // Replace empty placeholder tags & remove BOM
14
+ add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5);
15
+ add_filter( 'permalink_manager_filter_default_term_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5);
16
+
17
  // Clear the final default URIs
18
+ add_filter( 'permalink_manager_filter_default_term_uri', array($this, 'clear_single_uri'), 20);
19
+ add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'clear_single_uri'), 20);
20
  }
21
 
22
  /**
44
 
45
  $primary_term_enabled = apply_filters('permalink_manager_primary_term', true);
46
 
47
+ if(!$primary_term_enabled) { return; }
48
+
49
+ if(class_exists('WPSEO_Primary_Term')) {
50
  $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
51
  $primary_term = get_term($primary_term->get_primary_term());
52
+ } else if(function_exists('the_seo_framework')) {
53
+ $primary_term = the_seo_framework()->get_primary_term($post_id, $taxonomy);
54
+ }
55
 
56
+ if(!empty($primary_term) && !is_wp_error($primary_term)) {
57
+ return ($slug_only) ? $primary_term->slug : $primary_term;
58
+ } else {
59
+ return;
60
  }
 
61
  }
62
 
63
  /**
464
  $clean = preg_replace("/[\s]+/", "-", $clean);
465
  }
466
 
467
+ // Remove trailing slashes
468
+ $clean = str_replace(array('-/', '/-', '//'), '/', $clean);
469
+
470
  return $clean;
471
  }
472
 
473
  /**
474
+ * Replace empty placeholder tags & remove BOM
475
  */
476
+ public static function replace_empty_placeholder_tags($default_uri, $native_slug = "", $element = "", $slug = "", $native_uri = "") {
477
+ // Do not affect native URIs
478
+ if($native_uri == true) { return $default_uri; }
479
+
480
+ // Remove the BOM
481
+ $default_uri = str_replace(array("\xEF\xBB\xBF", "%ef%bb%bf"), '', $default_uri);
482
+
483
+ // Encode the URI before placeholders are removed
484
+ $chunks = explode('/', $default_uri);
485
+ foreach ($chunks as &$chunk) {
486
+ if(preg_match("/^(%.+?%)$/", $chunk) == false) {
487
+ $chunk = rawurldecode($chunk);
488
+ }
489
+ }
490
+ $default_uri = implode("/", $chunks);
491
 
492
+ $empty_tag_replacement = apply_filters('permalink_manager_empty_tag_replacement', null, $element);
493
+ $default_uri = ($empty_tag_replacement || is_null($empty_tag_replacement)) ? str_replace("//", "/", preg_replace("/%(.+?)%/", $empty_tag_replacement, $default_uri)) : $default_uri;
494
+
495
+ return trim($default_uri, "/");
496
+ }
497
+
498
+ /**
499
+ * Clear/Sanitize the URI
500
+ */
501
+ public static function clear_single_uri($uri) {
502
+ return self::sanitize_title($uri, true);
503
  }
504
 
505
  /**
506
  * Remove all slashes
507
  */
508
  public static function remove_slashes($uri) {
509
+ return preg_replace("/[\/]+/", "", $uri);
 
 
510
  }
511
 
512
  /**
519
  $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
520
 
521
  if($force_custom_slugs) {
 
 
 
 
522
  $title = (!empty($object->name)) ? $object->name : $object->post_title;
523
  $title = self::remove_slashes($title);
524
 
includes/core/permalink-manager-third-parties.php CHANGED
@@ -174,6 +174,10 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
174
  else if(!empty($query_vars['WP_Route'])) {
175
  $wp_query->query_vars['do_not_redirect'] = 1;
176
  }
 
 
 
 
177
  }
178
  }
179
 
@@ -658,7 +662,8 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
658
  if(!empty($object)) {
659
  $product_id = $object->get_id();
660
 
661
- if(empty($permalink_manager_uris[$product_id])) {
 
662
  $permalink_manager_uris[$product_id] = Permalink_Manager_URI_Functions_Post::get_default_post_uri($product_id, false, true);
663
 
664
  update_option('permalink-manager-uris', $permalink_manager_uris);
@@ -684,7 +689,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
684
  $home_url = WPSEO_Utils::home_url();
685
  $home_protocol = parse_url($home_url, PHP_URL_SCHEME);
686
 
687
- $permalink = preg_replace("/http(s)?/", $home_protocol, $permalink);
688
  }
689
 
690
  return $permalink;
174
  else if(!empty($query_vars['WP_Route'])) {
175
  $wp_query->query_vars['do_not_redirect'] = 1;
176
  }
177
+ // WooCommerce Wishlist
178
+ else if(!empty($query_vars['wishlist-action'])) {
179
+ $wp_query->query_vars['do_not_redirect'] = 1;
180
+ }
181
  }
182
  }
183
 
662
  if(!empty($object)) {
663
  $product_id = $object->get_id();
664
 
665
+ // Ignore variations
666
+ if(empty($permalink_manager_uris[$product_id]) && $object->get_type() !== 'variation') {
667
  $permalink_manager_uris[$product_id] = Permalink_Manager_URI_Functions_Post::get_default_post_uri($product_id, false, true);
668
 
669
  update_option('permalink-manager-uris', $permalink_manager_uris);
689
  $home_url = WPSEO_Utils::home_url();
690
  $home_protocol = parse_url($home_url, PHP_URL_SCHEME);
691
 
692
+ $permalink = preg_replace("/^http(s)?/", $home_protocol, $permalink);
693
  }
694
 
695
  return $permalink;
includes/core/permalink-manager-uri-functions-post.php CHANGED
@@ -23,9 +23,11 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
23
  * URI Editor
24
  */
25
  add_filter( 'get_sample_permalink_html', array($this, 'edit_uri_box'), 99, 5 );
 
26
  add_action( 'save_post', array($this, 'update_post_uri'), 99, 1);
27
  add_action( 'edit_attachment', array($this, 'update_post_uri'), 99, 1 );
28
  add_action( 'wp_insert_post', array($this, 'new_post_uri'), 99, 1 );
 
29
  add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 100, 1 );
30
 
31
  add_action( 'quick_edit_custom_box', array($this, 'quick_edit_column_form'), 99, 3);
@@ -83,14 +85,14 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
83
  if(isset($permalink_manager_uris[$post->ID])) {
84
  // Encode URI?
85
  if(!empty($permalink_manager_options['general']['decode_uris'])) {
86
- $permalink = "{$home_url}/" . urldecode("/{$permalink_manager_uris[$post->ID]}");
87
  } else {
88
  $permalink = "{$home_url}/" . Permalink_Manager_Helper_Functions::encode_uri("{$permalink_manager_uris[$post->ID]}");
89
  }
90
  } else if($post->post_type == 'attachment' && $post->post_parent > 0 && $post->post_parent != $post->ID && !empty($permalink_manager_uris[$post->post_parent])) {
91
  $permalink = "{$home_url}/{$permalink_manager_uris[$post->post_parent]}/attachment/{$post->post_name}";
92
  } else if(!empty($permalink_manager_options['general']['decode_uris'])) {
93
- $permalink = "{$home_url}/" . urldecode("/{$permalink}");
94
  }
95
 
96
  // 5. Allow to filter (do not filter in Customizer)
@@ -382,6 +384,12 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
382
  $where .= ")";
383
  }
384
 
 
 
 
 
 
 
385
  // Support for attachments
386
  $attachment_support = (in_array('attachment', $post_types_array)) ? " OR (post_type = 'attachment')" : "";
387
 
@@ -470,9 +478,6 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
470
  // Now if the array is not empty use IDs from each subarray as a key
471
  if($posts_to_update && empty($errors)) {
472
  foreach ($posts_to_update as $row) {
473
- // Prevent server timeout
474
- set_time_limit(0);
475
-
476
  // Get default & native URL
477
  $native_uri = self::get_default_post_uri($row['ID'], true);
478
  $default_uri = self::get_default_post_uri($row['ID']);
@@ -538,9 +543,6 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
538
 
539
  if (!empty($new_uris)) {
540
  foreach($new_uris as $id => $new_uri) {
541
- // Prevent server timeout
542
- set_time_limit(0);
543
-
544
  // Prepare variables
545
  $this_post = get_post($id);
546
  $updated = '';
@@ -616,7 +618,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
616
  }
617
 
618
  // Decode URI & allow to filter it
619
- $sample_permalink_uri = apply_filters('permalink_manager_filter_post_sample_uri', urldecode($sample_permalink_uri), $post);
620
 
621
  // Prepare the sample & default permalink
622
  $sample_permalink = sprintf("%s/<span class=\"editable\">%s</span>", $home_url, str_replace("//", "/", $sample_permalink_uri));
@@ -658,7 +660,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
658
  $auto_update_val = get_post_meta($post_id, "auto_update_uri", true);
659
  $auto_update_uri = (!empty($auto_update_val)) ? $auto_update_val : $permalink_manager_options["general"]["auto_update_uris"];
660
 
661
- $uri = (!empty($permalink_manager_uris[$post_id])) ? urldecode($permalink_manager_uris[$post_id]) : self::get_post_uri($post_id, true);
662
  printf('<span class="permalink-manager-col-uri" data-auto_update="%s">%s</span>', intval($auto_update_uri), $uri);
663
  }
664
  }
@@ -771,9 +773,6 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
771
  // Use default URI if URI is cleared by user OR URI should be automatically updated
772
  $new_uri = (($_POST['custom_uri'] == '') || $auto_update_uri == 1) ? $default_uri : Permalink_Manager_Helper_Functions::sanitize_title($_POST['custom_uri'], true);
773
 
774
- // Remove the empty placeholder tags
775
- $new_uri = Permalink_Manager_Core_Functions::replace_empty_placeholder_tags($new_uri);
776
-
777
  // Save or remove "Auto-update URI" settings
778
  if(!empty($auto_update_uri_current)) {
779
  update_post_meta($post_id, "auto_update_uri", $auto_update_uri_current);
23
  * URI Editor
24
  */
25
  add_filter( 'get_sample_permalink_html', array($this, 'edit_uri_box'), 99, 5 );
26
+
27
  add_action( 'save_post', array($this, 'update_post_uri'), 99, 1);
28
  add_action( 'edit_attachment', array($this, 'update_post_uri'), 99, 1 );
29
  add_action( 'wp_insert_post', array($this, 'new_post_uri'), 99, 1 );
30
+ add_action( 'add_attachment', array($this, 'new_post_uri'), 99, 1 );
31
  add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 100, 1 );
32
 
33
  add_action( 'quick_edit_custom_box', array($this, 'quick_edit_column_form'), 99, 3);
85
  if(isset($permalink_manager_uris[$post->ID])) {
86
  // Encode URI?
87
  if(!empty($permalink_manager_options['general']['decode_uris'])) {
88
+ $permalink = "{$home_url}/" . rawurldecode("/{$permalink_manager_uris[$post->ID]}");
89
  } else {
90
  $permalink = "{$home_url}/" . Permalink_Manager_Helper_Functions::encode_uri("{$permalink_manager_uris[$post->ID]}");
91
  }
92
  } else if($post->post_type == 'attachment' && $post->post_parent > 0 && $post->post_parent != $post->ID && !empty($permalink_manager_uris[$post->post_parent])) {
93
  $permalink = "{$home_url}/{$permalink_manager_uris[$post->post_parent]}/attachment/{$post->post_name}";
94
  } else if(!empty($permalink_manager_options['general']['decode_uris'])) {
95
+ $permalink = "{$home_url}/" . rawurldecode("/{$permalink}");
96
  }
97
 
98
  // 5. Allow to filter (do not filter in Customizer)
384
  $where .= ")";
385
  }
386
 
387
+ // Get excluded items
388
+ $exclude_posts = $wpdb->get_col("SELECT post_ID FROM {$wpdb->postmeta} AS pm LEFT JOIN {$wpdb->posts} AS p ON (pm.post_ID = p.ID) WHERE pm.meta_key = 'auto_update_uri' AND pm.meta_value = '-2' AND post_type IN ('{$post_types}')");
389
+ if(!empty($exclude_posts)) {
390
+ $where .= sprintf("AND ID NOT IN ('%s')", implode("', '", $exclude_posts));
391
+ }
392
+
393
  // Support for attachments
394
  $attachment_support = (in_array('attachment', $post_types_array)) ? " OR (post_type = 'attachment')" : "";
395
 
478
  // Now if the array is not empty use IDs from each subarray as a key
479
  if($posts_to_update && empty($errors)) {
480
  foreach ($posts_to_update as $row) {
 
 
 
481
  // Get default & native URL
482
  $native_uri = self::get_default_post_uri($row['ID'], true);
483
  $default_uri = self::get_default_post_uri($row['ID']);
543
 
544
  if (!empty($new_uris)) {
545
  foreach($new_uris as $id => $new_uri) {
 
 
 
546
  // Prepare variables
547
  $this_post = get_post($id);
548
  $updated = '';
618
  }
619
 
620
  // Decode URI & allow to filter it
621
+ $sample_permalink_uri = apply_filters('permalink_manager_filter_post_sample_uri', rawurldecode($sample_permalink_uri), $post);
622
 
623
  // Prepare the sample & default permalink
624
  $sample_permalink = sprintf("%s/<span class=\"editable\">%s</span>", $home_url, str_replace("//", "/", $sample_permalink_uri));
660
  $auto_update_val = get_post_meta($post_id, "auto_update_uri", true);
661
  $auto_update_uri = (!empty($auto_update_val)) ? $auto_update_val : $permalink_manager_options["general"]["auto_update_uris"];
662
 
663
+ $uri = (!empty($permalink_manager_uris[$post_id])) ? rawurldecode($permalink_manager_uris[$post_id]) : self::get_post_uri($post_id, true);
664
  printf('<span class="permalink-manager-col-uri" data-auto_update="%s">%s</span>', intval($auto_update_uri), $uri);
665
  }
666
  }
773
  // Use default URI if URI is cleared by user OR URI should be automatically updated
774
  $new_uri = (($_POST['custom_uri'] == '') || $auto_update_uri == 1) ? $default_uri : Permalink_Manager_Helper_Functions::sanitize_title($_POST['custom_uri'], true);
775
 
 
 
 
776
  // Save or remove "Auto-update URI" settings
777
  if(!empty($auto_update_uri_current)) {
778
  update_post_meta($post_id, "auto_update_uri", $auto_update_uri_current);
includes/views/permalink-manager-uri-editor-post.php CHANGED
@@ -172,7 +172,7 @@ class Permalink_Manager_URI_Editor_Post extends WP_List_Table {
172
  $html .= "<option value=\"{$month_raw}\" {$selected}>{$month_human_name}</option>";
173
  }
174
  $html .= "</select>";
175
- $html .= sprintf("<input id=\"months-filter-button\" class=\"button\" value=\"%s\" type=\"submit\">", __("Filter", "permalink-manager"));
176
  $html .= "</div>";
177
  }
178
  }
@@ -233,13 +233,14 @@ class Permalink_Manager_URI_Editor_Post extends WP_List_Table {
233
  // Grab posts from database
234
  $sql_parts['start'] = "SELECT * FROM {$wpdb->posts} ";
235
  if($search_query) {
236
- $sql_parts['where'] = "WHERE post_name LIKE ('%{$search_query}%') ";
237
 
238
  // Search in array with custom URIs
239
  $found = Permalink_Manager_Helper_Functions::search_uri($search_query, 'posts');
240
  if($found) {
241
  $sql_parts['where'] .= sprintf("OR ID IN ('%s')", implode(',', (array) $found));
242
  }
 
243
  } else {
244
  $sql_parts['where'] = "WHERE ((post_status IN ($this->displayed_post_statuses) AND post_type IN ($this->displayed_post_types)) {$attachment_support}) {$extra_filters} ";
245
  }
172
  $html .= "<option value=\"{$month_raw}\" {$selected}>{$month_human_name}</option>";
173
  }
174
  $html .= "</select>";
175
+ $html .= get_submit_button(__("Filter", "permalink-manager"), 'button', false, false, array('id' => 'months-filter-button', 'name' => 'months-filter-button'));
176
  $html .= "</div>";
177
  }
178
  }
233
  // Grab posts from database
234
  $sql_parts['start'] = "SELECT * FROM {$wpdb->posts} ";
235
  if($search_query) {
236
+ $sql_parts['where'] = "WHERE (post_name LIKE ('%{$search_query}%') ";
237
 
238
  // Search in array with custom URIs
239
  $found = Permalink_Manager_Helper_Functions::search_uri($search_query, 'posts');
240
  if($found) {
241
  $sql_parts['where'] .= sprintf("OR ID IN ('%s')", implode(',', (array) $found));
242
  }
243
+ $sql_parts['where'] .= " ) AND ((post_status IN ($this->displayed_post_statuses) AND post_type IN ($this->displayed_post_types)) {$attachment_support}) {$extra_filters} ";
244
  } else {
245
  $sql_parts['where'] = "WHERE ((post_status IN ($this->displayed_post_statuses) AND post_type IN ($this->displayed_post_types)) {$attachment_support}) {$extra_filters} ";
246
  }
out/permalink-manager-admin.js CHANGED
@@ -23,19 +23,43 @@ jQuery(document).ready(function() {
23
  });
24
 
25
  /**
26
- * Filter by dates in "Permalink editor"
27
  */
28
- jQuery('#permalink-manager #months-filter-button').on('click', function() {
29
- var filter_name = jQuery("#months-filter-select").attr('name');
30
  var filter_value = jQuery("#months-filter-select").val();
31
- var url = jQuery(this).parent().data('filter-url');
32
 
33
- if(filter_name != '' && filter_value != '' && url != ''){
34
- document.location.href = url + "&" + filter_name + "=" + filter_value;
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
 
 
 
 
36
  return false;
37
  });
38
 
 
 
 
 
 
 
 
 
 
39
  /**
40
  * Filter by content types in "Tools"
41
  */
23
  });
24
 
25
  /**
26
+ * Filter by dates + Search in URI Editor
27
  */
28
+ jQuery('#permalink-manager #months-filter-button, #permalink-manager #search-submit').on('click', function(e) {
29
+ var search_value = jQuery('#permalink-manager input[name="s"]').val();
30
  var filter_value = jQuery("#months-filter-select").val();
 
31
 
32
+ var filter_url = window.location.href;
33
+
34
+ // Date filter
35
+ if(filter_url.indexOf('month=') > 1) {
36
+ filter_url = filter_url.replace(/month=([^&]+)/gm, 'month=' + filter_value);
37
+ } else if(filter_value != '') {
38
+ filter_url = filter_url + '&month=' + filter_value;
39
+ }
40
+
41
+ // Search query
42
+ if(filter_url.indexOf('s=') > 1) {
43
+ filter_url = filter_url.replace(/s=([^&]+)/gm, 's=' + search_value);
44
+ } else if(search_value != '') {
45
+ filter_url = filter_url + '&s=' + search_value;
46
  }
47
+
48
+ window.location.href = filter_url;
49
+
50
+ e.preventDefault();
51
  return false;
52
  });
53
 
54
+ jQuery('#permalink-manager #uri_editor form input[name="s"]').on('keydown keypress keyup', function(e){
55
+ if(e.keyCode == 13) {
56
+ jQuery('#permalink-manager #search-submit').trigger('click');
57
+
58
+ e.preventDefault();
59
+ return false;
60
+ }
61
+ });
62
+
63
  /**
64
  * Filter by content types in "Tools"
65
  */
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.7.2
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: 3.7.0
16
  */
17
 
18
  // If this file is called directly or plugin is already defined, abort.
@@ -23,7 +23,7 @@ if (!defined('WPINC')) {
23
  // Define the directories used to load plugin files.
24
  define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
25
  define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
26
- define( 'PERMALINK_MANAGER_VERSION', '2.2.7.2' );
27
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
28
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
29
  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.7.3
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: 3.8.0
16
  */
17
 
18
  // If this file is called directly or plugin is already defined, abort.
23
  // Define the directories used to load plugin files.
24
  define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
25
  define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
26
+ define( 'PERMALINK_MANAGER_VERSION', '2.2.7.3' );
27
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
28
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
29
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__));