Permalink Manager Lite - Version 2.2.8.5

Version Description

Download this release

Release Info

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

Code changes from version 2.2.8.4 to 2.2.8.5

README.txt CHANGED
@@ -6,8 +6,8 @@ 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.3.1
10
- Stable tag: 2.2.8.4
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,12 +103,17 @@ It is because Permalink Manager overwrites one of the core Wordpress functionali
103
 
104
  == Changelog ==
105
 
106
- = 2.2.8.4 =
107
  * Hotfix for Permastructures (now the permalink formats are saved correctly)
108
- * Hotfix for trailing slashes settings (the native settings will no longer be overwritten by Permalink Manager)
 
 
 
 
 
109
 
110
  = 2.2.8.2/2.2.8.3 =
111
- * Improved feature descriptions in the settings
112
  * Hotfix for endpoint redirect
113
 
114
  = 2.2.8.1 =
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
10
+ Stable tag: 2.2.8.5
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.8.4/2.2.8.5 =
107
  * Hotfix for Permastructures (now the permalink formats are saved correctly)
108
+ * Hotfix for trailing slashes settings
109
+ * Improved setting fields descriptions
110
+ * Adjustments for search functionality in Bulk URI Editor
111
+ * Support for WPML Classic Translation Editor
112
+ * Adjustments for "Auto-update URI"
113
+ * Improvements for get_post_types_array() & get_taxonomies_array() functions used to list the content types supported by Permalink Manager
114
 
115
  = 2.2.8.2/2.2.8.3 =
116
+ * Improved descriptions in the plugin settings
117
  * Hotfix for endpoint redirect
118
 
119
  = 2.2.8.1 =
includes/core/permalink-manager-actions.php CHANGED
@@ -681,7 +681,7 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
681
  $event_name = 'clean_permalinks_event';
682
 
683
  // Set-up the "Automatically remove duplicates" function that runs in background once a day
684
- if(!empty($permalink_manager_options['general']['auto_remove_duplicates'])) {
685
  if(!wp_next_scheduled($event_name)) {
686
  wp_schedule_event(time(), 'daily', $event_name);
687
  }
681
  $event_name = 'clean_permalinks_event';
682
 
683
  // Set-up the "Automatically remove duplicates" function that runs in background once a day
684
+ if(!empty($permalink_manager_options['general']['auto_remove_duplicates']) && $permalink_manager_options['general']['auto_remove_duplicates'] == 2) {
685
  if(!wp_next_scheduled($event_name)) {
686
  wp_schedule_event(time(), 'daily', $event_name);
687
  }
includes/core/permalink-manager-admin-functions.php CHANGED
@@ -368,7 +368,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
368
  $fields .= "<div class=\"permastruct-toggle\">";
369
 
370
  // 2A. Permastructure for each language
371
- $languages = (array) Permalink_Manager_Third_Parties::get_all_languages(true);
372
  if($languages) {
373
  $fields .= sprintf(
374
  "<h4>%s</h4><p class=\"permastruct-instruction\">%s</p>",
@@ -426,7 +426,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
426
  $html .= $append_content;
427
  $html .= "</div>";
428
  } else if(isset($args['container']) && $args['container'] == 'row') {
429
- $html = "<tr data-field=\"{$input_name}\" {$container_class}><th><label for='{$input_name}'>{$args['label']}</label></th>";
430
  $html .= "<td><fieldset>{$fields}{$description}</fieldset></td></tr>";
431
  $html .= ($append_content) ? "<tr class=\"appended-row\"><td colspan=\"2\">{$append_content}</td></tr>" : "";
432
  } else if(isset($args['container']) && $args['container'] == 'screen-options') {
@@ -905,7 +905,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
905
  $html = "<div class=\"permalink-manager redirects-row redirects-panel columns-container\">";
906
 
907
  $html .= sprintf(
908
- "<div><a class=\"button\" href=\"#\" id=\"toggle-redirect-panel\">%s</a></span></div>",
909
  __("Manage redirects", "permalink-manager")
910
  );
911
 
368
  $fields .= "<div class=\"permastruct-toggle\">";
369
 
370
  // 2A. Permastructure for each language
371
+ $languages = (array) Permalink_Manager_Language_Plugins::get_all_languages(true);
372
  if($languages) {
373
  $fields .= sprintf(
374
  "<h4>%s</h4><p class=\"permastruct-instruction\">%s</p>",
426
  $html .= $append_content;
427
  $html .= "</div>";
428
  } else if(isset($args['container']) && $args['container'] == 'row') {
429
+ $html = sprintf("<tr id=\"%s\" data-field=\"%s\" %s><th><label for=\"%s\">%s</label></th>", esc_attr(preg_replace('/(?:.*\[)(.*)(?:\].*)/', '$1', $input_name)), $input_name, $container_class, $input_name, $args['label']);
430
  $html .= "<td><fieldset>{$fields}{$description}</fieldset></td></tr>";
431
  $html .= ($append_content) ? "<tr class=\"appended-row\"><td colspan=\"2\">{$append_content}</td></tr>" : "";
432
  } else if(isset($args['container']) && $args['container'] == 'screen-options') {
905
  $html = "<div class=\"permalink-manager redirects-row redirects-panel columns-container\">";
906
 
907
  $html .= sprintf(
908
+ "<div><a class=\"button\" href=\"#\" id=\"toggle-redirect-panel\">%s</a></div>",
909
  __("Manage redirects", "permalink-manager")
910
  );
911
 
includes/core/permalink-manager-core-functions.php CHANGED
@@ -326,7 +326,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
326
  /**
327
  * 4. Auto-remove removed term custom URI & redirects (works if enabled in plugin settings)
328
  */
329
- if(!empty($broken_uri) && !empty($permalink_manager_options['general']['auto_remove_duplicates'])) {
330
  $broken_element_id = (!empty($revision_id)) ? $revision_id : $element_id;
331
  $remove_broken_uri = Permalink_Manager_Actions::force_clear_single_element_uris_and_redirects($broken_element_id);
332
 
@@ -492,9 +492,10 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
492
  // Get the redirection mode & trailing slashes settings
493
  $redirect_mode = (!empty($permalink_manager_options['general']['redirect'])) ? $permalink_manager_options['general']['redirect'] : false;
494
  $trailing_slashes_mode = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : false;
495
- $trailing_slashes_redirect_mode = (!empty($permalink_manager_options['general']['trailing_slashes_redirect'])) ? $permalink_manager_options['general']['trailing_slashes_redirect'] : 301;
496
  $canonical_redirect = (!empty($permalink_manager_options['general']['canonical_redirect'])) ? $permalink_manager_options['general']['canonical_redirect'] : false;
497
  $old_slug_redirect = (!empty($permalink_manager_options['general']['old_slug_redirect'])) ? $permalink_manager_options['general']['old_slug_redirect'] : false;
 
498
  $redirect_type = '-';
499
 
500
  // Get home URL
@@ -553,7 +554,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
553
 
554
  // Check if the URI is not assigned to any post/term's redirects
555
  foreach($permalink_manager_redirects as $element => $redirects) {
556
- if(!is_array($redirects) || empty($permalink_manager_uris[$element])) { continue; }
557
 
558
  if(in_array($uri, $redirects) || in_array($decoded_url, $redirects) || (is_numeric($endpoint_value) && in_array($endpoint_url, $redirects))) {
559
 
@@ -621,30 +622,23 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
621
  /**
622
  * 2. Check trailing slashes (ignore links with query parameters)
623
  */
624
- if($trailing_slashes_mode && empty($_SERVER['QUERY_STRING']) && !empty($_SERVER['REQUEST_URI'])) {
625
  // Check if $old_uri ends with slash or not
626
  $ends_with_slash = (substr($old_uri, -1) == "/") ? true : false;
627
- $trailing_slashes_mode = (preg_match("/.*\.([a-zA-Z]{3,4})\/?$/", $old_uri) && $trailing_slashes_mode == 10) ? 20 : $trailing_slashes_mode;
628
 
629
  // Ignore empty URIs
630
  if($old_uri != "/") {
631
  // Remove the trailing slashes (and add them again if needed below)
632
  $old_uri = trim($old_uri, "/");
633
- $correct_permalink = (!empty($correct_permalink)) ? trim($correct_permalink, "/") : "";
634
 
635
  // 2A. Force trailing slashes
636
- if($trailing_slashes_mode == 10 && $ends_with_slash == false) {
637
- $correct_permalink = (!empty($correct_permalink)) ? "{$correct_permalink}/" : "{$home_url}/{$old_uri}/";
638
- }
639
- // 2B. Remove trailing slashes
640
- else if($trailing_slashes_mode == 20 && $ends_with_slash == true) {
641
- $correct_permalink = (!empty($correct_permalink)) ? $correct_permalink : "{$home_url}/{$old_uri}";
642
- $correct_permalink = trim($correct_permalink, "/");
643
  }
644
-
645
- // Use redirect mode set for trailing slash redirect
646
- if(($trailing_slashes_mode == 20 && $ends_with_slash == true) || ($trailing_slashes_mode == 10 && $ends_with_slash == false)) {
647
- $redirect_mode = $trailing_slashes_redirect_mode;
648
  }
649
  }
650
 
@@ -672,7 +666,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
672
  /**
673
  * 5. Add endpoints to redirect URL
674
  */
675
- if(!empty($correct_permalink) && ($redirect_type !== 'slash_redirect') && (!empty($pm_query['endpoint_value']) || !empty($pm_query['endpoint']))) {
676
  $endpoint_value = $pm_query['endpoint_value'];
677
 
678
  if(empty($pm_query['endpoint']) && is_numeric($endpoint_value)) {
326
  /**
327
  * 4. Auto-remove removed term custom URI & redirects (works if enabled in plugin settings)
328
  */
329
+ if(!empty($broken_uri) && (!empty($permalink_manager_options['general']['auto_remove_duplicates'])) && $permalink_manager_options['general']['auto_remove_duplicates'] == 1) {
330
  $broken_element_id = (!empty($revision_id)) ? $revision_id : $element_id;
331
  $remove_broken_uri = Permalink_Manager_Actions::force_clear_single_element_uris_and_redirects($broken_element_id);
332
 
492
  // Get the redirection mode & trailing slashes settings
493
  $redirect_mode = (!empty($permalink_manager_options['general']['redirect'])) ? $permalink_manager_options['general']['redirect'] : false;
494
  $trailing_slashes_mode = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : false;
495
+ $trailing_slashes_redirect = (!empty($permalink_manager_options['general']['trailing_slashes_redirect'])) ? $permalink_manager_options['general']['trailing_slashes_redirect'] : false;
496
  $canonical_redirect = (!empty($permalink_manager_options['general']['canonical_redirect'])) ? $permalink_manager_options['general']['canonical_redirect'] : false;
497
  $old_slug_redirect = (!empty($permalink_manager_options['general']['old_slug_redirect'])) ? $permalink_manager_options['general']['old_slug_redirect'] : false;
498
+ $endpoint_redirect = (!empty($permalink_manager_options['general']['endpoint_redirect'])) ? $permalink_manager_options['general']['endpoint_redirect'] : false;
499
  $redirect_type = '-';
500
 
501
  // Get home URL
554
 
555
  // Check if the URI is not assigned to any post/term's redirects
556
  foreach($permalink_manager_redirects as $element => $redirects) {
557
+ if(!is_array($redirects)) { continue; }
558
 
559
  if(in_array($uri, $redirects) || in_array($decoded_url, $redirects) || (is_numeric($endpoint_value) && in_array($endpoint_url, $redirects))) {
560
 
622
  /**
623
  * 2. Check trailing slashes (ignore links with query parameters)
624
  */
625
+ if($trailing_slashes_mode && $trailing_slashes_redirect && empty($correct_permalink) && empty($_SERVER['QUERY_STRING']) && !empty($_SERVER['REQUEST_URI'])) {
626
  // Check if $old_uri ends with slash or not
627
  $ends_with_slash = (substr($old_uri, -1) == "/") ? true : false;
628
+ $trailing_slashes_mode = (preg_match("/.*\.([a-zA-Z]{3,4})\/?$/", $old_uri) && $trailing_slashes_mode == 1) ? 2 : $trailing_slashes_mode;
629
 
630
  // Ignore empty URIs
631
  if($old_uri != "/") {
632
  // Remove the trailing slashes (and add them again if needed below)
633
  $old_uri = trim($old_uri, "/");
 
634
 
635
  // 2A. Force trailing slashes
636
+ if($trailing_slashes_mode == 1 && $ends_with_slash == false) {
637
+ $correct_permalink = "{$home_url}/{$old_uri}/";
 
 
 
 
 
638
  }
639
+ // 2B. Remove trailing slashes
640
+ else if($trailing_slashes_mode == 2 && $ends_with_slash == true) {
641
+ $correct_permalink = "{$home_url}/{$old_uri}";
 
642
  }
643
  }
644
 
666
  /**
667
  * 5. Add endpoints to redirect URL
668
  */
669
+ if(!empty($correct_permalink) && $endpoint_redirect && ($redirect_type !== 'slash_redirect') && (!empty($pm_query['endpoint_value']) || !empty($pm_query['endpoint']))) {
670
  $endpoint_value = $pm_query['endpoint_value'];
671
 
672
  if(empty($pm_query['endpoint']) && is_numeric($endpoint_value)) {
includes/core/permalink-manager-debug.php CHANGED
@@ -83,8 +83,8 @@ class Permalink_Manager_Debug_Functions extends Permalink_Manager_Class {
83
  remove_filter('post_type_link', array($uri_post_class, 'custom_post_permalinks'), 99, 2);
84
  remove_filter('attachment_link', array($uri_post_class, 'custom_post_permalinks'), 99, 2);
85
  remove_filter('term_link', array($uri_tax_class, 'custom_tax_permalinks'), 999, 2 );
86
- remove_filter('category_link', array($uri_tax_class, 'custom_tax_permalinks'), 999, 2 );
87
- remove_filter('tag_link', array($uri_tax_class, 'custom_tax_permalinks'), 999, 2 );
88
 
89
  $csv = array();
90
 
83
  remove_filter('post_type_link', array($uri_post_class, 'custom_post_permalinks'), 99, 2);
84
  remove_filter('attachment_link', array($uri_post_class, 'custom_post_permalinks'), 99, 2);
85
  remove_filter('term_link', array($uri_tax_class, 'custom_tax_permalinks'), 999, 2 );
86
+ // remove_filter('category_link', array($uri_tax_class, 'custom_tax_permalinks'), 999, 2 );
87
+ // remove_filter('tag_link', array($uri_tax_class, 'custom_tax_permalinks'), 999, 2 );
88
 
89
  $csv = array();
90
 
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -159,45 +159,49 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
159
  return (!empty($term_slug)) ? $term_slug : "";
160
  }
161
 
162
- static function content_types_disabled_by_default($is_taxonomy = false) {
163
- if($is_taxonomy) {
164
- return array('product_shipping_class', 'post_status', 'fl-builder-template-category', 'post_format');
165
- } else {
166
- return array('revision', 'algolia_task', 'fl_builder', 'fl-builder', 'fl-builder-template', 'fl-theme-layout', 'wc_product_tab', 'wc_voucher', 'wc_voucher_template', 'sliders', 'thirstylink', 'elementor_library', 'cms_block', 'us_page_block');
167
- }
168
- }
169
-
170
  /**
171
  * Allow to disable post types and taxonomies
172
  */
173
- static function get_disabled_post_types() {
174
- global $permalink_manager_options, $wp_post_types, $wp_rewrite;
175
 
176
- $initial_disabled_post_types = self::content_types_disabled_by_default();
177
 
178
- // Disable post types that are not publicly_queryable
179
- if(!empty($wp_rewrite)){
180
- foreach($wp_post_types as $post_type) {
181
- //$is_publicly_queryable = (empty($post_type->publicly_queryable) && empty($post_type->public)) ? false : true;
182
- $is_publicly_queryable = (empty($post_type->publicly_queryable) || empty($post_type->public)) ? false : true;
183
 
184
- if(!$is_publicly_queryable && !in_array($post_type->name, array('post', 'page', 'attachment'))) {
185
- $initial_disabled_post_types[] = $post_type->name;
186
- }
187
  }
188
  }
189
 
190
- $disabled_post_types = (!empty($permalink_manager_options['general']['partial_disable']['post_types'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['post_types'], $initial_disabled_post_types) : $initial_disabled_post_types;
 
 
 
191
 
192
  return apply_filters('permalink_manager_disabled_post_types', $disabled_post_types);
193
  }
194
 
195
- static function get_disabled_taxonomies() {
196
- global $permalink_manager_options;
197
 
198
- $initial_disabled_taxonomies = self::content_types_disabled_by_default(true);
199
 
200
- $disabled_taxonomies = (!empty($permalink_manager_options['general']['partial_disable']['taxonomies'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['taxonomies'], $initial_disabled_taxonomies) : array();
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
  return apply_filters('permalink_manager_disabled_taxonomies', $disabled_taxonomies);
203
  }
@@ -219,37 +223,23 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
219
  }
220
 
221
  /**
222
- * Get post_types array
223
- */
224
- static function get_post_types_array($format = null, $cpt = null, $all = false) {
225
  global $wp_post_types;
226
 
227
- $post_types = get_post_types(array('publicly_queryable' => true, '_builtin' => false), 'objects', 'AND');
228
- $disabled_post_types = self::get_disabled_post_types();
229
-
230
- // Include native post types
231
- foreach(array('post', 'page', 'attachment') as $post_type_name) {
232
- $post_types[$post_type_name] = $wp_post_types[$post_type_name];
233
- }
234
-
235
  $post_types_array = array();
236
- foreach($post_types as $post_type) {
237
- $value = ($format == 'full') ? array('label' => $post_type->labels->name, 'name' => $post_type->name) : $post_type->labels->name;
238
- $post_types_array[$post_type->name] = $value;
239
- }
240
 
241
- // Soft exclude disabled post types
242
- if(!$all && is_array($disabled_post_types)) {
243
- foreach($disabled_post_types as $post_type) {
244
- if(!empty($post_types_array[$post_type])) { unset($post_types_array[$post_type]); }
245
- }
246
  }
247
 
248
- // Hard exclude disabled post types
249
- $hard_disabled_post_types = self::content_types_disabled_by_default();
250
- if(is_array($hard_disabled_post_types)) {
251
- foreach($hard_disabled_post_types as $post_type) {
252
- if(!empty($post_types_array[$post_type])) { unset($post_types_array[$post_type]); }
253
  }
254
  }
255
 
@@ -257,35 +247,24 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
257
  }
258
 
259
  /**
260
- * Get array with all taxonomies
261
- */
262
- static function get_taxonomies_array($format = null, $tax = null, $prefix = false, $all = false, $settings = false) {
263
- $taxonomies = get_taxonomies(array('public' => true, 'publicly_queryable' => true), 'objects', 'AND');
264
- $disabled_taxonomies = self::get_disabled_taxonomies();
265
 
266
  $taxonomies_array = array();
 
267
 
268
- foreach($taxonomies as $taxonomy) {
269
  $key = ($prefix) ? "tax-{$taxonomy->name}" : $taxonomy->name;
270
- if($format == 'full') {
271
- $taxonomies_array[$taxonomy->name] = array('label' => $taxonomy->labels->name, 'name' => $taxonomy->name);
272
- } else {
273
- $taxonomies_array[$key] = $taxonomy->labels->name;
274
- }
275
  }
276
 
277
- // Soft exclude taxonomies
278
- if(!$all && is_array($disabled_taxonomies)) {
279
  foreach($disabled_taxonomies as $taxonomy) {
280
- if(!empty($taxonomies_array[$taxonomy])) { unset($taxonomies_array[$taxonomy]); }
281
- }
282
- }
283
-
284
- // Hard exclude disabled taxonomies
285
- $hard_disabled_taxonomies = self::content_types_disabled_by_default(true);
286
- if(is_array($hard_disabled_taxonomies)) {
287
- foreach($hard_disabled_taxonomies as $taxonomy) {
288
- if(!empty($taxonomies_array[$taxonomy])) { unset($taxonomies_array[$taxonomy]); }
289
  }
290
  }
291
 
@@ -534,19 +513,26 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
534
  * Force custom slugs
535
  */
536
  public static function force_custom_slugs($slug, $object, $flat = false) {
537
- global $permalink_manager_options;
538
 
539
- $force_custom_slugs = (!empty($permalink_manager_options['general']['force_custom_slugs'])) ? true : false;
540
  $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
541
 
542
  if($force_custom_slugs) {
543
- $title = (!empty($object->name)) ? $object->name : $object->post_title;
544
- $title = self::remove_slashes($title);
 
 
545
 
546
- $old_slug = basename($slug);
547
- $new_slug = self::sanitize_title($title, false, null, null);
 
 
 
 
 
548
 
549
- $slug = ($old_slug != $new_slug) ? str_replace($old_slug, $new_slug, $slug) : $slug;
550
  }
551
 
552
  if($flat) {
@@ -626,11 +612,11 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
626
 
627
  if(in_array($uri, $all_uris)) {
628
  $all_duplicates = (array) array_keys($all_uris, $uri);
629
- $this_uri_lang = Permalink_Manager_Third_Parties::get_language_code($element_id);
630
 
631
  if($this_uri_lang) {
632
  foreach($all_duplicates as $key => $duplicated_id) {
633
- $duplicated_uri_lang = Permalink_Manager_Third_Parties::get_language_code($duplicated_id);
634
 
635
  if($duplicated_uri_lang !== $this_uri_lang) {
636
  unset($all_duplicates[$key]);
159
  return (!empty($term_slug)) ? $term_slug : "";
160
  }
161
 
 
 
 
 
 
 
 
 
162
  /**
163
  * Allow to disable post types and taxonomies
164
  */
165
+ static function get_disabled_post_types($include_user_excluded = true) {
166
+ global $wp_post_types, $permalink_manager_options;
167
 
168
+ $disabled_post_types = array('revision', 'algolia_task', 'fl_builder', 'fl-builder', 'fl-builder-template', 'fl-theme-layout', 'wc_product_tab', 'wc_voucher', 'wc_voucher_template', 'sliders', 'thirstylink', 'elementor_library', 'cms_block');
169
 
170
+ // 1. Disable post types that are not publicly_queryable
171
+ foreach($wp_post_types as $post_type) {
172
+ $is_publicly_queryable = (!empty($post_type->publicly_queryable) || (!empty($post_type->public) && !empty($post_type->rewrite))) ? true : false;
 
 
173
 
174
+ if(!$is_publicly_queryable && !in_array($post_type->name, array('post', 'page', 'attachment'))) {
175
+ $disabled_post_types[] = $post_type->name;
 
176
  }
177
  }
178
 
179
+ // 2. Add post types disabled by user
180
+ if($include_user_excluded) {
181
+ $disabled_post_types = (!empty($permalink_manager_options['general']['partial_disable']['post_types'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['post_types'], $disabled_post_types) : $disabled_post_types;
182
+ }
183
 
184
  return apply_filters('permalink_manager_disabled_post_types', $disabled_post_types);
185
  }
186
 
187
+ static function get_disabled_taxonomies($include_user_excluded = true) {
188
+ global $wp_taxonomies, $permalink_manager_options;
189
 
190
+ $disabled_taxonomies = array('product_shipping_class', 'post_status', 'fl-builder-template-category', 'post_format');
191
 
192
+ // 1. Disable taxonomies that are not publicly_queryable
193
+ foreach($wp_taxonomies as $taxonomy) {
194
+ $is_publicly_queryable = (!empty($taxonomy->publicly_queryable) || (!empty($taxonomy->public) && !empty($taxonomy->rewrite))) ? true : false;
195
+
196
+ if(!$is_publicly_queryable && !in_array($taxonomy->name, array('category', 'post_tag'))) {
197
+ $disabled_taxonomies[] = $taxonomy->name;
198
+ }
199
+ }
200
+
201
+ // 2. Add taxonomies disabled by user
202
+ if($include_user_excluded) {
203
+ $disabled_taxonomies = (!empty($permalink_manager_options['general']['partial_disable']['taxonomies'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['taxonomies'], $disabled_taxonomies) : array();
204
+ }
205
 
206
  return apply_filters('permalink_manager_disabled_taxonomies', $disabled_taxonomies);
207
  }
223
  }
224
 
225
  /**
226
+ * Get all post types supported by Permalink Manager
227
+ */
228
+ static function get_post_types_array($format = null, $cpt = null, $include_user_excluded = false) {
229
  global $wp_post_types;
230
 
 
 
 
 
 
 
 
 
231
  $post_types_array = array();
232
+ $disabled_post_types = self::get_disabled_post_types(!$include_user_excluded);
 
 
 
233
 
234
+ foreach($wp_post_types as $post_type) {
235
+ $post_types_array[$post_type->name] = ($format == 'full') ? array('label' => $post_type->labels->name, 'name' => $post_type->name) : $post_type->labels->name;
 
 
 
236
  }
237
 
238
+ if(is_array($disabled_post_types)) {
239
+ foreach($disabled_post_types as $post_type) {
240
+ if(!empty($post_types_array[$post_type])) {
241
+ unset($post_types_array[$post_type]);
242
+ }
243
  }
244
  }
245
 
247
  }
248
 
249
  /**
250
+ * Get all taxonomies supported by Permalink Manager
251
+ */
252
+ static function get_taxonomies_array($format = null, $tax = null, $prefix = false, $include_user_excluded = false, $settings = false) {
253
+ global $wp_taxonomies;
 
254
 
255
  $taxonomies_array = array();
256
+ $disabled_taxonomies = self::get_disabled_taxonomies(!$include_user_excluded);
257
 
258
+ foreach($wp_taxonomies as $taxonomy) {
259
  $key = ($prefix) ? "tax-{$taxonomy->name}" : $taxonomy->name;
260
+ $taxonomies_array[$taxonomy->name] = ($format == 'full') ? array('label' => $taxonomy->labels->name, 'name' => $taxonomy->name) : $taxonomy->labels->name;
 
 
 
 
261
  }
262
 
263
+ if(is_array($disabled_taxonomies)) {
 
264
  foreach($disabled_taxonomies as $taxonomy) {
265
+ if(!empty($taxonomies_array[$taxonomy])) {
266
+ unset($taxonomies_array[$taxonomy]);
267
+ }
 
 
 
 
 
 
268
  }
269
  }
270
 
513
  * Force custom slugs
514
  */
515
  public static function force_custom_slugs($slug, $object, $flat = false) {
516
+ global $permalink_manager_options, $permalink_manager_uris;
517
 
518
+ $force_custom_slugs = (!empty($permalink_manager_options['general']['force_custom_slugs'])) ? $permalink_manager_options['general']['force_custom_slugs'] : false;
519
  $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
520
 
521
  if($force_custom_slugs) {
522
+ // A. Custom slug (title)
523
+ if($force_custom_slugs == 1) {
524
+ $title = (!empty($object->name)) ? $object->name : $object->post_title;
525
+ $title = self::remove_slashes($title);
526
 
527
+ $new_slug = self::sanitize_title($title, false, null, null);
528
+ }
529
+ // B. Custom slug (custom permalink)
530
+ else {
531
+ $object_id = (!empty($object->term_id)) ? "tax-{$object->term_id}" : $object->ID;
532
+ $new_slug = (!empty($permalink_manager_uris[$object_id])) ? basename($permalink_manager_uris[$object_id]) : '';
533
+ }
534
 
535
+ $slug = (!empty($new_slug)) ? preg_replace('/([^\/]+)$/', $new_slug, $slug) : $slug;
536
  }
537
 
538
  if($flat) {
612
 
613
  if(in_array($uri, $all_uris)) {
614
  $all_duplicates = (array) array_keys($all_uris, $uri);
615
+ $this_uri_lang = Permalink_Manager_Language_Plugins::get_language_code($element_id);
616
 
617
  if($this_uri_lang) {
618
  foreach($all_duplicates as $key => $duplicated_id) {
619
+ $duplicated_uri_lang = Permalink_Manager_Language_Plugins::get_language_code($duplicated_id);
620
 
621
  if($duplicated_uri_lang !== $this_uri_lang) {
622
  unset($all_duplicates[$key]);
includes/core/permalink-manager-language-plugins.php ADDED
@@ -0,0 +1,509 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Third parties integration
5
+ */
6
+ class Permalink_Manager_Language_Plugins extends Permalink_Manager_Class {
7
+
8
+ public function __construct() {
9
+ add_action('init', array($this, 'init_hooks'), 99);
10
+ }
11
+
12
+ function init_hooks() {
13
+ global $sitepress_settings, $permalink_manager_options, $polylang, $translate_press_settings;
14
+
15
+ // 1. WPML, Polylang & TranslatePress
16
+ if($sitepress_settings || !empty($polylang->links_model->options) || class_exists('TRP_Translate_Press')) {
17
+ // Detect Post/Term function
18
+ if(!empty($permalink_manager_options['general']['fix_language_mismatch'])) {
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);
25
+
26
+ // Adjust front page ID
27
+ add_filter('permalink_manager_is_front_page', array($this, 'wpml_is_front_page'), 9, 3);
28
+
29
+ // Get translation mode
30
+ $mode = 0;
31
+
32
+ // A. WPML
33
+ if(isset($sitepress_settings['language_negotiation_type'])) {
34
+ $url_settings = $sitepress_settings['language_negotiation_type'];
35
+
36
+ if(in_array($sitepress_settings['language_negotiation_type'], array(1, 2))) {
37
+ $mode = 'prepend';
38
+ } else if($sitepress_settings['language_negotiation_type'] == 3) {
39
+ $mode = 'append';
40
+ }
41
+ }
42
+ // B. Polylang
43
+ else if(isset($polylang->links_model->options['force_lang'])) {
44
+ $url_settings = $polylang->links_model->options['force_lang'];
45
+
46
+ if(in_array($url_settings, array(1, 2, 3))) {
47
+ $mode = 'prepend';
48
+ }
49
+ }
50
+ // C. TranslatePress
51
+ else if(class_exists('TRP_Translate_Press')) {
52
+ $translate_press_settings = get_option('trp_settings');
53
+
54
+ $mode = 'prepend';
55
+ }
56
+
57
+ if($mode === 'prepend') {
58
+ add_filter('permalink_manager_detect_uri', array($this, 'detect_uri_language'), 9, 3);
59
+ add_filter('permalink_manager_filter_permalink_base', array($this, 'prepend_lang_prefix'), 9, 2);
60
+ add_filter('template_redirect', array($this, 'wpml_redirect'), 0, 998 );
61
+ } else if($mode === 'append') {
62
+ add_filter('permalink_manager_filter_final_post_permalink', array($this, 'append_lang_prefix'), 5, 2);
63
+ add_filter('permalink_manager_filter_final_term_permalink', array($this, 'append_lang_prefix'), 5, 2);
64
+ add_filter('permalink_manager_detect_uri', array($this, 'wpml_ignore_lang_query_parameter'), 9);
65
+ }
66
+
67
+ // Translate permastructures
68
+ add_filter('permalink_manager_filter_permastructure', array($this, 'translate_permastructure'), 9, 2);
69
+
70
+ // Translate post type slug
71
+ if(class_exists('WPML_Slug_Translation')) {
72
+ add_filter('permalink_manager_filter_post_type_slug', array($this, 'wpml_translate_post_type_slug'), 9, 3);
73
+ }
74
+
75
+ // Translate WooCommerce endpoints
76
+ if(class_exists('WCML_Endpoints')) {
77
+ add_filter('request', array($this, 'wpml_translate_wc_endpoints'), 99999);
78
+ }
79
+
80
+ // Edit custom URI using WPML Classic Translation Editor
81
+ if(class_exists('WPML_Translation_Editor_UI')) {
82
+ add_filter('wpml_tm_adjust_translation_fields', array($this, 'wpml_translation_edit_uri'), 999, 2);
83
+ add_filter('wpml-translation-editor-fetch-job', array($this, 'wpml_translation_save_uri'), 999, 2);
84
+ }
85
+
86
+ add_action('icl_make_duplicate', array($this, 'wpml_duplicate_uri'), 999, 4);
87
+ }
88
+ }
89
+
90
+ /**
91
+ * WPML/Polylang/TranslatePress filters
92
+ */
93
+ public static function get_language_code($element) {
94
+ global $TRP_LANGUAGE, $translate_press_settings;
95
+
96
+ // Fallback
97
+ if(is_string($element) && strpos($element, 'tax-') !== false) {
98
+ $element_id = intval(preg_replace("/[^0-9]/", "", $element));
99
+ $element = get_term($element_id);
100
+ } else if(is_numeric($element)) {
101
+ $element = get_post($element);
102
+ }
103
+
104
+ // A. TranslatePress
105
+ if(!empty($TRP_LANGUAGE)) {
106
+ $lang_code = self::get_translatepress_language_code($TRP_LANGUAGE);
107
+ }
108
+ // B. WPML & Polylang
109
+ else {
110
+ if(isset($element->post_type)) {
111
+ $element_id = $element->ID;
112
+ $element_type = $element->post_type;
113
+ } else if(isset($element->taxonomy)) {
114
+ $element_id = $element->term_taxonomy_id;
115
+ $element_type = $element->taxonomy;
116
+ } else {
117
+ return false;
118
+ }
119
+
120
+ $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
121
+ }
122
+
123
+ // Use default language if nothing detected
124
+ return ($lang_code) ? $lang_code : self::get_default_language();
125
+ }
126
+
127
+ public static function get_translatepress_language_code($lang) {
128
+ global $translate_press_settings;
129
+
130
+ if(!empty($translate_press_settings['url-slugs'])) {
131
+ $lang_code = (!empty($translate_press_settings['url-slugs'][$lang])) ? $translate_press_settings['url-slugs'][$lang] : '';
132
+ }
133
+
134
+ return (!empty($lang_code)) ? $lang_code : false;
135
+ }
136
+
137
+ public static function get_default_language() {
138
+ global $sitepress, $translate_press_settings;
139
+
140
+ if(function_exists('pll_default_language')) {
141
+ $def_lang = pll_default_language('slug');
142
+ } else if(is_object($sitepress)) {
143
+ $def_lang = $sitepress->get_default_language();
144
+ } else if(!empty($translate_press_settings['default-language'])) {
145
+ $def_lang = self::get_translatepress_language_code($translate_press_settings['default-language']);
146
+ } else {
147
+ $def_lang = '';
148
+ }
149
+
150
+ return $def_lang;
151
+ }
152
+
153
+ public static function get_all_languages($exclude_default_language = false) {
154
+ global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
155
+
156
+ $languages_array = $active_languages = array();
157
+ $default_language = self::get_default_language();
158
+
159
+ if(!empty($sitepress_settings['active_languages'])) {
160
+ $languages_array = $sitepress_settings['active_languages'];
161
+ } elseif(function_exists('pll_languages_list')) {
162
+ $languages_array = pll_languages_list(array('fields' => null));
163
+ } if(!empty($translate_press_settings['url-slugs'])) {
164
+ // $languages_array = $translate_press_settings['url-slugs'];
165
+ }
166
+
167
+ // Get native language names as value
168
+ if($languages_array) {
169
+ foreach($languages_array as $val) {
170
+ if(!empty($sitepress)) {
171
+ $lang = $val;
172
+ $lang_details = $sitepress->get_language_details($lang);
173
+ $language_name = $lang_details['native_name'];
174
+ } else if(!empty($val->name)) {
175
+ $lang = $val->slug;
176
+ $language_name = $val->name;
177
+ }
178
+
179
+ $active_languages[$lang] = (!empty($language_name)) ? sprintf('%s <span>(%s)</span>', $language_name, $lang) : '-';
180
+ }
181
+
182
+ // Exclude default language if needed
183
+ if($exclude_default_language && $default_language && !empty($active_languages[$default_language])) {
184
+ unset($active_languages[$default_language]);
185
+ }
186
+ }
187
+
188
+ return (array) $active_languages;
189
+ }
190
+
191
+ function fix_language_mismatch($item_id, $uri_parts, $is_term = false) {
192
+ global $wp, $language_code;
193
+
194
+ if($is_term) {
195
+ $element = get_term($item_id);
196
+ if(!empty($element) && !is_wp_error($element)) {
197
+ $element_id = $element->term_taxonomy_id;
198
+ $element_type = $element->taxonomy;
199
+ } else {
200
+ return false;
201
+ }
202
+ } else {
203
+ $element = get_post($item_id);
204
+
205
+ if(!empty($element->post_type)) {
206
+ $element_id = $item_id;
207
+ $element_type = $element->post_type;
208
+ }
209
+ }
210
+
211
+ // Stop if no term or post is detected
212
+ if(empty($element)) { return false; }
213
+
214
+ $language_code = self::get_language_code($element);
215
+
216
+ if(!empty($uri_parts['lang']) && ($uri_parts['lang'] != $language_code)) {
217
+ $wpml_item_id = apply_filters('wpml_object_id', $element_id, $element_type);
218
+ $item_id = (is_numeric($wpml_item_id)) ? $wpml_item_id : $item_id;
219
+ }
220
+
221
+ return $item_id;
222
+ }
223
+
224
+ function detect_uri_language($uri_parts, $request_url, $endpoints) {
225
+ global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
226
+
227
+ if(!empty($sitepress_settings['active_languages'])) {
228
+ $languages_list = (array) $sitepress_settings['active_languages'];
229
+ } elseif(function_exists('pll_languages_list')) {
230
+ $languages_array = pll_languages_list();
231
+ $languages_list = (is_array($languages_array)) ? (array) $languages_array : "";
232
+ } elseif($translate_press_settings['url-slugs']) {
233
+ $languages_list = $translate_press_settings['url-slugs'];
234
+ }
235
+
236
+ if(is_array($languages_list)) {
237
+ $languages_list = implode("|", $languages_list);
238
+ } else {
239
+ return $uri_parts;
240
+ }
241
+
242
+ $default_language = self::get_default_language();
243
+
244
+ // Fix for multidomain language configuration
245
+ if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
246
+ if(!empty($polylang->options['domains'])) {
247
+ $domains = (array) $polylang->options['domains'];
248
+ } else if(!empty($sitepress_settings['language_domains'])) {
249
+ $domains = (array) $sitepress_settings['language_domains'];
250
+ }
251
+
252
+ foreach($domains as &$domain) {
253
+ $domain = preg_replace('/((http(s)?:\/\/(www\.)?)|(www\.))?(.+?)\/?$/', 'http://$6', $domain);
254
+ }
255
+
256
+ $request_url = trim(str_replace($domains, "", $request_url), "/");
257
+ }
258
+
259
+ if(!empty($languages_list)) {
260
+ //preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})[\/$]([^\/]*)|\/()([\d+]))?\/?$/i", $request_url, $regex_parts);
261
+ preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i", $request_url, $regex_parts);
262
+
263
+ $uri_parts['lang'] = (!empty($regex_parts[1])) ? $regex_parts[1] : $default_language;
264
+ $uri_parts['uri'] = (!empty($regex_parts[2])) ? $regex_parts[2] : "";
265
+ $uri_parts['endpoint'] = (!empty($regex_parts[3])) ? $regex_parts[3] : "";
266
+ $uri_parts['endpoint_value'] = (!empty($regex_parts[4])) ? $regex_parts[4] : "";
267
+ }
268
+
269
+ return $uri_parts;
270
+ }
271
+
272
+ function prepend_lang_prefix($base, $element) {
273
+ global $sitepress_settings, $polylang, $permalink_manager_uris, $translate_press_settings;
274
+
275
+ $language_code = self::get_language_code($element);
276
+ $default_language_code = self::get_default_language();
277
+ $home_url = get_home_url();
278
+
279
+ // Hide language code if "Use directory for default language" option is enabled
280
+ $hide_prefix_for_default_lang = ((isset($sitepress_settings['urls']['directory_for_default_language']) && $sitepress_settings['urls']['directory_for_default_language'] != 1) || !empty($polylang->links_model->options['hide_default']) || !empty($translate_press_settings['add-subdirectory-to-default-language'])) ? true : false;
281
+
282
+ // Last instance - use language paramater from &_GET array
283
+ if(is_admin()) {
284
+ $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
285
+ }
286
+
287
+ // Adjust URL base
288
+ if(!empty($language_code)) {
289
+ // A. Different domain per language
290
+ if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
291
+
292
+ if(!empty($polylang->options['domains'])) {
293
+ $domains = $polylang->options['domains'];
294
+ } else if(!empty($sitepress_settings['language_domains'])) {
295
+ $domains = $sitepress_settings['language_domains'];
296
+ }
297
+
298
+ $is_term = (!empty($element->term_taxonomy_id)) ? true : false;
299
+ $element_id = ($is_term) ? "tax-{$element->term_taxonomy_id}" : $element->ID;
300
+
301
+ // Filter only custom permalinks
302
+ if(empty($permalink_manager_uris[$element_id]) || empty($domains)) { return $base; }
303
+
304
+ // Replace the domain name
305
+ if(!empty($domains[$language_code])) {
306
+ $base = trim($domains[$language_code], "/");
307
+
308
+ // Append URL scheme
309
+ if(!preg_match("~^(?:f|ht)tps?://~i", $base)) {
310
+ $scehme = parse_url($home_url, PHP_URL_SCHEME);
311
+ $base = "{$scehme}://{$base}";
312
+ }
313
+ }
314
+ }
315
+ // B. Prepend language code
316
+ else if(!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 2) {
317
+ if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
318
+ return $base;
319
+ } else {
320
+ $base = preg_replace('/(https?:\/\/)/', "$1{$language_code}.", $home_url);
321
+ }
322
+ }
323
+ // C. Append prefix
324
+ else {
325
+ if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
326
+ return $base;
327
+ } else {
328
+ $base .= "/{$language_code}";
329
+ }
330
+ }
331
+ }
332
+
333
+ return $base;
334
+ }
335
+
336
+ function append_lang_prefix($permalink, $element) {
337
+ global $sitepress_settings, $polylang, $permalink_manager_uris;
338
+
339
+ $language_code = self::get_language_code($element);
340
+ $default_language_code = self::get_default_language();
341
+
342
+ // Last instance - use language paramater from &_GET array
343
+ if(is_admin()) {
344
+ $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
345
+ }
346
+
347
+ // B. Append ?lang query parameter
348
+ if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 3) {
349
+ if($default_language_code == $language_code) {
350
+ return $permalink;
351
+ } else {
352
+ $permalink .= "?lang={$language_code}";
353
+ }
354
+ }
355
+
356
+ return $permalink;
357
+ }
358
+
359
+ function language_column_uri_editor($output, $column, $element) {
360
+ $language_code = self::get_language_code($element);
361
+ $output .= (!empty($language_code)) ? sprintf(" | <span><strong>%s:</strong> %s</span>", __("Language"), $language_code) : "";
362
+
363
+ return $output;
364
+ }
365
+
366
+ function wpml_is_front_page($bool, $page_id, $front_page_id) {
367
+ $default_language_code = self::get_default_language();
368
+ $page_id = apply_filters('wpml_object_id', $page_id, 'page', true, $default_language_code);
369
+
370
+ return (!empty($page_id) && $page_id == $front_page_id) ? true : $bool;
371
+ }
372
+
373
+ function wpml_ignore_lang_query_parameter($uri_parts) {
374
+ global $permalink_manager_uris;
375
+
376
+ foreach($permalink_manager_uris as &$uri) {
377
+ $uri = trim(strtok($uri, '?'), "/");
378
+ }
379
+
380
+ return $uri_parts;
381
+ }
382
+
383
+ function wpml_redirect() {
384
+ global $language_code, $wp_query;
385
+
386
+ if(!empty($language_code) && defined('ICL_LANGUAGE_CODE') && ICL_LANGUAGE_CODE != $language_code && !empty($wp_query->query['do_not_redirect'])) {
387
+ unset($wp_query->query['do_not_redirect']);
388
+ }
389
+ }
390
+
391
+ function translate_permastructure($permastructure, $element) {
392
+ global $permalink_manager_permastructs, $pagenow;;
393
+
394
+ // Get element language code
395
+ if(!empty($_REQUEST['data']) && strpos($_REQUEST['data'], "target_lang")) {
396
+ $language_code = preg_replace('/(.*target_lang=)([^=&]+)(.*)/', '$2', $_REQUEST['data']);
397
+ } else if(in_array($pagenow, array('post.php', 'post-new.php')) && !empty($_GET['lang'])) {
398
+ $language_code = $_GET['lang'];
399
+ } else if(!empty($_REQUEST['icl_post_language'])) {
400
+ $language_code = $_REQUEST['icl_post_language'];
401
+ } else if(!empty($_POST['action']) && $_POST['action'] == 'pm_save_permalink' && defined('ICL_LANGUAGE_CODE')) {
402
+ $language_code = ICL_LANGUAGE_CODE;
403
+ } else {
404
+ $language_code = self::get_language_code($element);
405
+ }
406
+
407
+ if(!empty($element->ID)) {
408
+ $translated_permastructure = (!empty($permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"])) ? $permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"] : '';
409
+ } else if(!empty($element->term_id)) {
410
+ $translated_permastructure = (!empty($permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"])) ? $permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"] : '';
411
+ }
412
+
413
+ return (!empty($translated_permastructure)) ? $translated_permastructure : $permastructure;
414
+ }
415
+
416
+ function wpml_translate_post_type_slug($post_type_slug, $element, $post_type) {
417
+ $post = (is_integer($element)) ? get_post($element) : $element;
418
+ $language_code = self::get_language_code($post);
419
+
420
+ $post_type_slug = apply_filters('wpml_get_translated_slug', $post_type_slug, $post_type, $language_code);
421
+
422
+ // Translate %post_type% tag in custom permastructures
423
+ return $post_type_slug;
424
+ }
425
+
426
+ function wpml_translate_wc_endpoints($request) {
427
+ global $woocommerce, $wpdb;
428
+
429
+ if(!empty($woocommerce->query->query_vars)) {
430
+ // Get WooCommerce original endpoints
431
+ $endpoints = $woocommerce->query->query_vars;
432
+
433
+ // Get all endppoint translations
434
+ $endpoint_translations = $wpdb->get_results("SELECT t.value AS translated_endpoint, t.language, s.value AS endpoint FROM {$wpdb->prefix}icl_string_translations AS t LEFT JOIN {$wpdb->prefix}icl_strings AS s ON t.string_id = s.id WHERE context = 'WP Endpoints'");
435
+
436
+ // Replace translate endpoint with its original name
437
+ foreach($endpoint_translations as $endpoint) {
438
+ if(isset($request[$endpoint->translated_endpoint])) {
439
+ $request[$endpoint->endpoint] = $request[$endpoint->translated_endpoint];
440
+ unset($request[$endpoint->translated_endpoint]);
441
+ }
442
+ }
443
+ }
444
+
445
+ return $request;
446
+ }
447
+
448
+ /**
449
+ * Edit custom URI using WPML Classic Translation Editor
450
+ */
451
+ function wpml_translation_edit_uri($fields, $job) {
452
+ global $permalink_manager_uris;
453
+
454
+ $element_type = (strpos($job->original_post_type, 'post_') !== false) ? preg_replace('/^(post_)/', '', $job->original_post_type) : '';
455
+
456
+ if(!empty($element_type)) {
457
+ $original_id = $job->original_doc_id;
458
+ $translation_id = apply_filters('wpml_object_id', $original_id, $element_type, false, $job->language_code);
459
+
460
+ $original_custom_uri = Permalink_Manager_URI_Functions_Post::get_post_uri($original_id, true);
461
+ $translation_custom_uri = Permalink_Manager_URI_Functions_Post::get_post_uri($translation_id, true);
462
+
463
+ $fields[] = array(
464
+ 'field_type' => 'pm-custom_uri',
465
+ //'tid' => 9999,
466
+ 'field_data' => $original_custom_uri,
467
+ 'field_data_translated' => $translation_custom_uri,
468
+ 'field_style' => '0',
469
+ 'title' => 'Custom URI',
470
+ );
471
+ }
472
+
473
+ return $fields;
474
+ }
475
+
476
+ function wpml_translation_save_uri($job, $job_details) {
477
+ global $permalink_manager_uris;
478
+
479
+ if(!empty($_POST['data'])) {
480
+ $data = array();
481
+ $post_data = \WPML_TM_Post_Data::strip_slashes_for_single_quote($_POST['data']);
482
+ parse_str($post_data, $data);
483
+
484
+ if(isset($data['fields']['pm-custom_uri'])) {
485
+ $original_id = $data['job_post_id'];
486
+ $element_type = (strpos($data['job_post_type'], 'post_') !== false) ? preg_replace('/^(post_)/', '', $data['job_post_type']) : '';
487
+
488
+ $translation_id = apply_filters('wpml_object_id', $original_id, $element_type, false, $data['target_lang']);
489
+ $permalink_manager_uris[$translation_id] = (!empty($data['fields']['pm-custom_uri']['data'])) ? Permalink_Manager_Helper_Functions::sanitize_title($data['fields']['pm-custom_uri']['data'], true) : Permalink_Manager_URI_Functions_Post::get_default_post_uri($translation_id);
490
+
491
+ update_option('permalink-manager-uris', $permalink_manager_uris);
492
+ }
493
+ }
494
+
495
+ return $job;
496
+ }
497
+
498
+ function wpml_duplicate_uri($master_post_id, $lang, $post_array, $id) {
499
+ global $permalink_manager_uris;
500
+
501
+ // Trigger the function only if duplicate is created in the metabox
502
+ if(empty($_POST['action']) || $_POST['action'] !== 'make_duplicates') { return; }
503
+
504
+ $permalink_manager_uris[$id] = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
505
+
506
+ update_option('permalink-manager-uris', $permalink_manager_uris);
507
+ }
508
+
509
+ }
includes/core/permalink-manager-third-parties.php CHANGED
@@ -11,73 +11,11 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
11
  }
12
 
13
  function init_hooks() {
14
- global $sitepress_settings, $permalink_manager_options, $polylang, $translate_press_settings;
15
 
16
  // 0. Stop redirect
17
  add_action('wp', array($this, 'stop_redirect'), 0);
18
 
19
- // 1. WPML, Polylang & TranslatePress
20
- if($sitepress_settings || !empty($polylang->links_model->options) || class_exists('TRP_Translate_Press')) {
21
- // Detect Post/Term function
22
- if(!empty($permalink_manager_options['general']['fix_language_mismatch'])) {
23
- add_filter('permalink_manager_detected_post_id', array($this, 'fix_language_mismatch'), 9, 3);
24
- add_filter('permalink_manager_detected_term_id', array($this, 'fix_language_mismatch'), 9, 3);
25
- }
26
-
27
- // URI Editor
28
- add_filter('permalink_manager_uri_editor_extra_info', array($this, 'language_column_uri_editor'), 9, 3);
29
-
30
- // Adjust front page ID
31
- add_filter('permalink_manager_is_front_page', array($this, 'wpml_is_front_page'), 9, 3);
32
-
33
- // Get translation mode
34
- $mode = 0;
35
-
36
- // A. WPML
37
- if(isset($sitepress_settings['language_negotiation_type'])) {
38
- $url_settings = $sitepress_settings['language_negotiation_type'];
39
-
40
- if(in_array($sitepress_settings['language_negotiation_type'], array(1, 2))) {
41
- $mode = 'prepend';
42
- } else if($sitepress_settings['language_negotiation_type'] == 3) {
43
- $mode = 'append';
44
- }
45
- }
46
- // B. Polylang
47
- else if(isset($polylang->links_model->options['force_lang'])) {
48
- $url_settings = $polylang->links_model->options['force_lang'];
49
-
50
- if(in_array($url_settings, array(1, 2, 3))) {
51
- $mode = 'prepend';
52
- }
53
- }
54
- // C. TranslatePress
55
- else if(class_exists('TRP_Translate_Press')) {
56
- $translate_press_settings = get_option('trp_settings');
57
-
58
- $mode = 'prepend';
59
- }
60
-
61
- if($mode === 'prepend') {
62
- add_filter('permalink_manager_detect_uri', array($this, 'detect_uri_language'), 9, 3);
63
- add_filter('permalink_manager_filter_permalink_base', array($this, 'prepend_lang_prefix'), 9, 2);
64
- add_filter('template_redirect', array($this, 'wpml_redirect'), 0, 998 );
65
- } else if($mode === 'append') {
66
- add_filter('permalink_manager_filter_final_post_permalink', array($this, 'append_lang_prefix'), 5, 2);
67
- add_filter('permalink_manager_filter_final_term_permalink', array($this, 'append_lang_prefix'), 5, 2);
68
- add_filter('permalink_manager_detect_uri', array($this, 'wpml_ignore_lang_query_parameter'), 9);
69
- }
70
-
71
- // Translate slugs
72
- if(class_exists('WPML_Slug_Translation')) {
73
- add_filter('permalink_manager_filter_post_type_slug', array($this, 'wpml_translate_post_type_slug'), 9, 3);
74
- // add_filter('permalink_manager_filter_taxonomy_slug', array($this, 'wpml_translate_taxonomy_slug'), 9, 3);
75
- }
76
-
77
- // Translate permastructure
78
- add_filter('permalink_manager_filter_permastructure', array($this, 'translate_permastructure'), 9, 2);
79
- }
80
-
81
  // 2. AMP
82
  if(defined('AMP_QUERY_VAR')) {
83
  // Detect AMP endpoint
@@ -197,6 +135,10 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
197
  else if(!empty($query_vars['up_username'])) {
198
  $wp_query->query_vars['do_not_redirect'] = 1;
199
  }
 
 
 
 
200
  }
201
 
202
  // WPForo
@@ -209,343 +151,6 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
209
  }
210
  }
211
 
212
- /**
213
- * 1. WPML/Polylang/TranslatePress filters
214
- */
215
- public static function get_language_code($element) {
216
- global $TRP_LANGUAGE, $translate_press_settings;
217
-
218
- // Fallback
219
- if(is_string($element) && strpos($element, 'tax-') !== false) {
220
- $element_id = intval(preg_replace("/[^0-9]/", "", $element));
221
- $element = get_term($element_id);
222
- } else if(is_numeric($element)) {
223
- $element = get_post($element);
224
- }
225
-
226
- // A. TranslatePress
227
- if(!empty($TRP_LANGUAGE)) {
228
- $lang_code = self::get_translatepress_language_code($TRP_LANGUAGE);
229
- }
230
- // B. WPML & Polylang
231
- else {
232
- if(isset($element->post_type)) {
233
- $element_id = $element->ID;
234
- $element_type = $element->post_type;
235
- } else if(isset($element->taxonomy)) {
236
- $element_id = $element->term_taxonomy_id;
237
- $element_type = $element->taxonomy;
238
- } else {
239
- return false;
240
- }
241
-
242
- $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
243
- }
244
-
245
- // Use default language if nothing detected
246
- return ($lang_code) ? $lang_code : self::get_default_language();
247
- }
248
-
249
- public static function get_translatepress_language_code($lang) {
250
- global $translate_press_settings;
251
-
252
- if(!empty($translate_press_settings['url-slugs'])) {
253
- $lang_code = (!empty($translate_press_settings['url-slugs'][$lang])) ? $translate_press_settings['url-slugs'][$lang] : '';
254
- }
255
-
256
- return (!empty($lang_code)) ? $lang_code : false;
257
- }
258
-
259
- public static function get_default_language() {
260
- global $sitepress, $translate_press_settings;
261
-
262
- if(function_exists('pll_default_language')) {
263
- $def_lang = pll_default_language('slug');
264
- } else if(is_object($sitepress)) {
265
- $def_lang = $sitepress->get_default_language();
266
- } else if(!empty($translate_press_settings['default-language'])) {
267
- $def_lang = self::get_translatepress_language_code($translate_press_settings['default-language']);
268
- } else {
269
- $def_lang = '';
270
- }
271
-
272
- return $def_lang;
273
- }
274
-
275
- public static function get_all_languages($exclude_default_language = false) {
276
- global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
277
-
278
- $languages_array = $active_languages = array();
279
- $default_language = self::get_default_language();
280
-
281
- if(!empty($sitepress_settings['active_languages'])) {
282
- $languages_array = $sitepress_settings['active_languages'];
283
- } elseif(function_exists('pll_languages_list')) {
284
- $languages_array = pll_languages_list(array('fields' => null));
285
- } if(!empty($translate_press_settings['url-slugs'])) {
286
- // $languages_array = $translate_press_settings['url-slugs'];
287
- }
288
-
289
- // Get native language names as value
290
- if($languages_array) {
291
- foreach($languages_array as $val) {
292
- if(!empty($sitepress)) {
293
- $lang = $val;
294
- $lang_details = $sitepress->get_language_details($lang);
295
- $language_name = $lang_details['native_name'];
296
- } else if(!empty($val->name)) {
297
- $lang = $val->slug;
298
- $language_name = $val->name;
299
- }
300
-
301
- $active_languages[$lang] = (!empty($language_name)) ? sprintf('%s <span>(%s)</span>', $language_name, $lang) : '-';
302
- }
303
-
304
- // Exclude default language if needed
305
- if($exclude_default_language && $default_language && !empty($active_languages[$default_language])) {
306
- unset($active_languages[$default_language]);
307
- }
308
- }
309
-
310
- return (array) $active_languages;
311
- }
312
-
313
- function fix_language_mismatch($item_id, $uri_parts, $is_term = false) {
314
- global $wp, $language_code;
315
-
316
- if($is_term) {
317
- $element = get_term($item_id);
318
- if(!empty($element) && !is_wp_error($element)) {
319
- $element_id = $element->term_taxonomy_id;
320
- $element_type = $element->taxonomy;
321
- } else {
322
- return false;
323
- }
324
- } else {
325
- $element = get_post($item_id);
326
-
327
- if(!empty($element->post_type)) {
328
- $element_id = $item_id;
329
- $element_type = $element->post_type;
330
- }
331
- }
332
-
333
- // Stop if no term or post is detected
334
- if(empty($element)) { return false; }
335
-
336
- $language_code = self::get_language_code($element);
337
-
338
- if(!empty($uri_parts['lang']) && ($uri_parts['lang'] != $language_code)) {
339
- $wpml_item_id = apply_filters('wpml_object_id', $element_id, $element_type);
340
- $item_id = (is_numeric($wpml_item_id)) ? $wpml_item_id : $item_id;
341
- }
342
-
343
- return $item_id;
344
- }
345
-
346
- function detect_uri_language($uri_parts, $request_url, $endpoints) {
347
- global $sitepress, $sitepress_settings, $polylang, $translate_press_settings;
348
-
349
- if(!empty($sitepress_settings['active_languages'])) {
350
- $languages_list = (array) $sitepress_settings['active_languages'];
351
- } elseif(function_exists('pll_languages_list')) {
352
- $languages_array = pll_languages_list();
353
- $languages_list = (is_array($languages_array)) ? (array) $languages_array : "";
354
- } elseif($translate_press_settings['url-slugs']) {
355
- $languages_list = $translate_press_settings['url-slugs'];
356
- }
357
-
358
- if(is_array($languages_list)) {
359
- $languages_list = implode("|", $languages_list);
360
- } else {
361
- return $uri_parts;
362
- }
363
-
364
- $default_language = self::get_default_language();
365
-
366
- // Fix for multidomain language configuration
367
- if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
368
- if(!empty($polylang->options['domains'])) {
369
- $domains = (array) $polylang->options['domains'];
370
- } else if(!empty($sitepress_settings['language_domains'])) {
371
- $domains = (array) $sitepress_settings['language_domains'];
372
- }
373
-
374
- foreach($domains as &$domain) {
375
- $domain = preg_replace('/((http(s)?:\/\/(www\.)?)|(www\.))?(.+?)\/?$/', 'http://$6', $domain);
376
- }
377
-
378
- $request_url = trim(str_replace($domains, "", $request_url), "/");
379
- }
380
-
381
- if(!empty($languages_list)) {
382
- //preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})[\/$]([^\/]*)|\/()([\d+]))?\/?$/i", $request_url, $regex_parts);
383
- preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i", $request_url, $regex_parts);
384
-
385
- $uri_parts['lang'] = (!empty($regex_parts[1])) ? $regex_parts[1] : $default_language;
386
- $uri_parts['uri'] = (!empty($regex_parts[2])) ? $regex_parts[2] : "";
387
- $uri_parts['endpoint'] = (!empty($regex_parts[3])) ? $regex_parts[3] : "";
388
- $uri_parts['endpoint_value'] = (!empty($regex_parts[4])) ? $regex_parts[4] : "";
389
- }
390
-
391
- return $uri_parts;
392
- }
393
-
394
- function prepend_lang_prefix($base, $element) {
395
- global $sitepress_settings, $polylang, $permalink_manager_uris, $translate_press_settings;
396
-
397
- $language_code = self::get_language_code($element);
398
- $default_language_code = self::get_default_language();
399
- $home_url = get_home_url();
400
-
401
- // Hide language code if "Use directory for default language" option is enabled
402
- $hide_prefix_for_default_lang = ((isset($sitepress_settings['urls']['directory_for_default_language']) && $sitepress_settings['urls']['directory_for_default_language'] != 1) || !empty($polylang->links_model->options['hide_default']) || !empty($translate_press_settings['add-subdirectory-to-default-language'])) ? true : false;
403
-
404
- // Last instance - use language paramater from &_GET array
405
- if(is_admin()) {
406
- $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
407
- }
408
-
409
- // Adjust URL base
410
- if(!empty($language_code)) {
411
- // A. Different domain per language
412
- if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
413
-
414
- if(!empty($polylang->options['domains'])) {
415
- $domains = $polylang->options['domains'];
416
- } else if(!empty($sitepress_settings['language_domains'])) {
417
- $domains = $sitepress_settings['language_domains'];
418
- }
419
-
420
- $is_term = (!empty($element->term_taxonomy_id)) ? true : false;
421
- $element_id = ($is_term) ? "tax-{$element->term_taxonomy_id}" : $element->ID;
422
-
423
- // Filter only custom permalinks
424
- if(empty($permalink_manager_uris[$element_id]) || empty($domains)) { return $base; }
425
-
426
- // Replace the domain name
427
- if(!empty($domains[$language_code])) {
428
- $base = trim($domains[$language_code], "/");
429
-
430
- // Append URL scheme
431
- if(!preg_match("~^(?:f|ht)tps?://~i", $base)) {
432
- $scehme = parse_url($home_url, PHP_URL_SCHEME);
433
- $base = "{$scehme}://{$base}";
434
- }
435
- }
436
- }
437
- // B. Prepend language code
438
- else if(!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 2) {
439
- if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
440
- return $base;
441
- } else {
442
- $base = preg_replace('/(https?:\/\/)/', "$1{$language_code}.", $home_url);
443
- }
444
- }
445
- // C. Append prefix
446
- else {
447
- if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
448
- return $base;
449
- } else {
450
- $base .= "/{$language_code}";
451
- }
452
- }
453
- }
454
-
455
- return $base;
456
- }
457
-
458
- function append_lang_prefix($permalink, $element) {
459
- global $sitepress_settings, $polylang, $permalink_manager_uris;
460
-
461
- $language_code = self::get_language_code($element);
462
- $default_language_code = self::get_default_language();
463
-
464
- // Last instance - use language paramater from &_GET array
465
- if(is_admin()) {
466
- $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
467
- }
468
-
469
- // B. Append ?lang query parameter
470
- if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 3) {
471
- if($default_language_code == $language_code) {
472
- return $permalink;
473
- } else {
474
- $permalink .= "?lang={$language_code}";
475
- }
476
- }
477
-
478
- return $permalink;
479
- }
480
-
481
- function translate_permastructure($permastructure, $element) {
482
- global $permalink_manager_permastructs, $pagenow;;
483
-
484
- // Get element language code
485
- if(!empty($_REQUEST['data']) && strpos($_REQUEST['data'], "target_lang")) {
486
- $language_code = preg_replace('/(.*target_lang=)([^=&]+)(.*)/', '$2', $_REQUEST['data']);
487
- } else if(in_array($pagenow, array('post.php', 'post-new.php')) && !empty($_GET['lang'])) {
488
- $language_code = $_GET['lang'];
489
- } else if(!empty($_REQUEST['icl_post_language'])) {
490
- $language_code = $_REQUEST['icl_post_language'];
491
- } else if(!empty($_POST['action']) && $_POST['action'] == 'pm_save_permalink' && defined('ICL_LANGUAGE_CODE')) {
492
- $language_code = ICL_LANGUAGE_CODE;
493
- } else {
494
- $language_code = self::get_language_code($element);
495
- }
496
-
497
- if(!empty($element->ID)) {
498
- $translated_permastructure = (!empty($permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"])) ? $permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"] : '';
499
- } else if(!empty($element->term_id)) {
500
- $translated_permastructure = (!empty($permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"])) ? $permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"] : '';
501
- }
502
-
503
- return (!empty($translated_permastructure)) ? $translated_permastructure : $permastructure;
504
- }
505
-
506
-
507
- function language_column_uri_editor($output, $column, $element) {
508
- $language_code = self::get_language_code($element);
509
- $output .= (!empty($language_code)) ? sprintf(" | <span><strong>%s:</strong> %s</span>", __("Language"), $language_code) : "";
510
-
511
- return $output;
512
- }
513
-
514
- function wpml_translate_post_type_slug($post_type_slug, $element, $post_type) {
515
- $post = (is_integer($element)) ? get_post($element) : $element;
516
- $language_code = self::get_language_code($post);
517
-
518
- $post_type_slug = apply_filters('wpml_get_translated_slug', $post_type_slug, $post_type, $language_code);
519
-
520
- // Translate %post_type% tag in custom permastructures
521
- return $post_type_slug;
522
- }
523
-
524
- function wpml_is_front_page($bool, $page_id, $front_page_id) {
525
- $default_language_code = self::get_default_language();
526
- $page_id = apply_filters('wpml_object_id', $page_id, 'page', true, $default_language_code);
527
-
528
- return (!empty($page_id) && $page_id == $front_page_id) ? true : $bool;
529
- }
530
-
531
- function wpml_ignore_lang_query_parameter($uri_parts) {
532
- global $permalink_manager_uris;
533
-
534
- foreach($permalink_manager_uris as &$uri) {
535
- $uri = trim(strtok($uri, '?'), "/");
536
- }
537
-
538
- return $uri_parts;
539
- }
540
-
541
- function wpml_redirect() {
542
- global $language_code, $wp_query;
543
-
544
- if(!empty($language_code) && defined('ICL_LANGUAGE_CODE') && ICL_LANGUAGE_CODE != $language_code && !empty($wp_query->query['do_not_redirect'])) {
545
- unset($wp_query->query['do_not_redirect']);
546
- }
547
- }
548
-
549
  /**
550
  * 2. AMP hooks
551
  */
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
20
  if(defined('AMP_QUERY_VAR')) {
21
  // Detect AMP endpoint
135
  else if(!empty($query_vars['up_username'])) {
136
  $wp_query->query_vars['do_not_redirect'] = 1;
137
  }
138
+ // The Events Calendar
139
+ else if(!empty($query_vars['eventDisplay'])) {
140
+ $wp_query->query_vars['do_not_redirect'] = 1;
141
+ }
142
  }
143
 
144
  // WPForo
151
  }
152
  }
153
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  /**
155
  * 2. AMP hooks
156
  */
includes/core/permalink-manager-uri-functions-post.php CHANGED
@@ -58,6 +58,9 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
58
  // Do not filter in WPML String Editor
59
  if(!empty($_REQUEST['icl_ajx_action']) && $_REQUEST['icl_ajx_action'] == 'icl_st_save_translation') { return $permalink; }
60
 
 
 
 
61
  $post = (is_integer($post)) ? get_post($post) : $post;
62
 
63
  // Start with homepage URL
@@ -512,6 +515,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
512
  // Check if native slug should be changed
513
  if(($mode == 'slugs') && ($old_post_name != $new_post_name)) {
514
  self::update_slug_by_id($new_post_name, $row['ID']);
 
515
  }
516
 
517
  if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
@@ -775,6 +779,12 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
775
  }
776
  $auto_update_uri = (!empty($auto_update_uri_current)) ? $auto_update_uri_current : $permalink_manager_options["general"]["auto_update_uris"];
777
 
 
 
 
 
 
 
778
  $default_uri = self::get_default_post_uri($post_id);
779
  $native_uri = self::get_default_post_uri($post_id, true);
780
  $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri;
@@ -793,11 +803,6 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
793
  $permalink_manager_uris[$post_id] = $new_uri;
794
  update_option('permalink-manager-uris', $permalink_manager_uris);
795
 
796
- // Update the slug (if changed)
797
- if(isset($_POST['permalink-manager-edit-uri-element-slug']) && isset($_POST['native_slug']) && ($_POST['native_slug'] !== $_POST['permalink-manager-edit-uri-element-slug'])) {
798
- self::update_slug_by_id($_POST['native_slug'], $post_id);
799
- }
800
-
801
  do_action('permalink-manager-updated-post-uri', $post_id, $new_uri, $old_uri, $native_uri, $default_uri, $single_update = true);
802
  }
803
 
58
  // Do not filter in WPML String Editor
59
  if(!empty($_REQUEST['icl_ajx_action']) && $_REQUEST['icl_ajx_action'] == 'icl_st_save_translation') { return $permalink; }
60
 
61
+ // Do not run when metaboxes are loaded with Gutenberg
62
+ if(!empty($_REQUEST['meta-box-loader'])) { return $permalink; }
63
+
64
  $post = (is_integer($post)) ? get_post($post) : $post;
65
 
66
  // Start with homepage URL
515
  // Check if native slug should be changed
516
  if(($mode == 'slugs') && ($old_post_name != $new_post_name)) {
517
  self::update_slug_by_id($new_post_name, $row['ID']);
518
+ clean_post_cache($row['ID']);
519
  }
520
 
521
  if(($old_uri != $new_uri) || ($old_post_name != $new_post_name)) {
779
  }
780
  $auto_update_uri = (!empty($auto_update_uri_current)) ? $auto_update_uri_current : $permalink_manager_options["general"]["auto_update_uris"];
781
 
782
+ // Update the slug (if changed)
783
+ if(isset($_POST['permalink-manager-edit-uri-element-slug']) && isset($_POST['native_slug']) && ($_POST['native_slug'] !== $_POST['permalink-manager-edit-uri-element-slug'])) {
784
+ self::update_slug_by_id($_POST['native_slug'], $post_id);
785
+ clean_post_cache($post_id);
786
+ }
787
+
788
  $default_uri = self::get_default_post_uri($post_id);
789
  $native_uri = self::get_default_post_uri($post_id, true);
790
  $old_uri = (isset($permalink_manager_uris[$post->ID])) ? $permalink_manager_uris[$post->ID] : $native_uri;
803
  $permalink_manager_uris[$post_id] = $new_uri;
804
  update_option('permalink-manager-uris', $permalink_manager_uris);
805
 
 
 
 
 
 
806
  do_action('permalink-manager-updated-post-uri', $post_id, $new_uri, $old_uri, $native_uri, $default_uri, $single_update = true);
807
  }
808
 
includes/views/permalink-manager-settings.php CHANGED
@@ -38,39 +38,67 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
38
  'type' => 'single_checkbox',
39
  'label' => __('Auto-update permalinks', 'permalink-manager'),
40
  'input_class' => '',
41
- 'description' => __('If enabled, the custom permalinks will be automatically updated every time the post is saved or updated.', 'permalink-manager')
42
- ),
43
- 'auto_remove_duplicates' => array(
44
- 'type' => 'single_checkbox',
45
- 'label' => __('Automatically remove broken URIs', 'permalink-manager'),
46
- 'input_class' => '',
47
- 'description' => sprintf(__('If enabled, the custom URIs assigned to removed posts & terms will be automatically removed.<br />To manually remove the duplicates please go <a href="%s">to this page</a>.', 'permalink-manager'), admin_url('tools.php?page=permalink-manager&section=tools&subsection=duplicates'))
48
  ),
49
  'force_custom_slugs' => array(
50
  'type' => 'select',
51
- 'label' => __('Use actual post/term titles (Force custom slugs)', 'permalink-manager'),
52
  'input_class' => 'settings-select',
53
- 'choices' => array(0 => __('No, use native slugs', 'permalink-manager'), 1 => __('Yes, use post/term titles', 'permalink-manager')),
54
- 'description' => __('If enabled, the slugs in the default custom permalinks will be recreated from the post titles.<br />This may cause permalinks duplicates when the post or term title is used more than once.', 'permalink-manager')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  ),
56
- )
57
- ),
58
- 'seo' => array(
59
- 'section_name' => __('SEO functions & redirects', 'permalink-manager'),
60
- 'container' => 'row',
61
- 'name' => 'general',
62
- 'fields' => array(
63
  'canonical_redirect' => array(
64
  'type' => 'single_checkbox',
65
  'label' => __('Canonical redirect', 'permalink-manager'),
66
  'input_class' => '',
67
- 'description' => __('If enabled, Permalink Manager will automatically redirect original (native) permalinks to actual (canonical) permalinks.', 'permalink-manager')
 
 
 
68
  ),
69
  'old_slug_redirect' => array(
70
  'type' => 'single_checkbox',
71
  'label' => __('Old slug redirect', 'permalink-manager'),
72
  'input_class' => '',
73
- 'description' => __('If enabled, Permalink Manager will automatically redirect old posts\' slugs to actual (canonical) permalinks (after the native slug is changed).', 'permalink-manager')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  ),
75
  'setup_redirects' => array(
76
  'type' => 'single_checkbox',
@@ -78,27 +106,28 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
78
  'input_class' => '',
79
  'pro' => true,
80
  'disabled' => true,
81
- 'description' => sprintf(__('If enabled, the redirect will be automatically created for <strong>earlier version of custom permalink</strong> after its changed in Permalink Manager (eg. with URI Editor or Regenerate/reset tool).<br />The old permalinks will be saved as <a href="%s" target="_blank">custom redirects</a>.', 'permalink-manager'), 'https://permalinkmanager.pro/docs/redirects/wordpress-custom-redirects/')
82
- ),
83
- 'trailing_slashes' => array(
84
- 'type' => 'select',
85
- 'label' => __('Trailing slashes (redirect)', 'permalink-manager'),
86
- 'input_class' => 'settings-select',
87
- 'choices' => array(0 => __('Use default settings', 'permalink-manager'), 1 => __('Add trailing slashes', 'permalink-manager'), 10 => __('Add trailing slashes (+ auto-redirect links without them)', 'permalink-manager'), 2 => __('Remove trailing slashes', 'permalink-manager'), 20 => __('Remove trailing slashes (+ auto-redirect links with them)', 'permalink-manager'),),
88
- 'description' => __('This option can be used to alter the native settings and control if trailing slash should be added or removed from the end of posts & terms permalinks.', 'permalink-manager')
89
  ),
90
  'sslwww_redirect' => array(
91
  'type' => 'single_checkbox',
92
- 'label' => __('Force HTTPS/WWW in URLs', 'permalink-manager'),
93
  'input_class' => '',
94
- 'description' => __('<strong>Please disable it, if you encounter any redirect loop issues.</strong>', 'permalink-manager')
 
 
 
95
  ),
96
- 'redirect' => array(
97
- 'type' => 'select',
98
- 'label' => __('Redirect mode', 'permalink-manager'),
99
- 'input_class' => 'settings-select',
100
- 'choices' => array(0 => __('Disable', 'permalink-manager'), "301" => __('Enable "301 redirect"', 'permalink-manager'), "302" => __('Enable "302 redirect"', 'permalink-manager')),
101
- 'description' => __('The selected mode will be used for URL redirects controlled by Permalink Manager.', 'permalink-manager')
 
102
  )
103
  )
104
  ),
@@ -109,25 +138,25 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
109
  'fields' => array(
110
  'fix_language_mismatch' => array(
111
  'type' => 'single_checkbox',
112
- 'label' => __('Fix WPML/Polylang language mismatch', 'permalink-manager'),
113
  'input_class' => '',
114
  'description' => __('If enabled, the plugin will load the adjacent translation of post when the custom permalink is detected, but the language code in the URL does not match the language code assigned to the post/term.', 'permalink-manager')
115
  ),
116
  'pmxi_import_support' => array(
117
  'type' => 'single_checkbox',
118
- 'label' => __('Disable support for WP All Import', 'permalink-manager'),
119
  'input_class' => '',
120
- 'description' => __('If checked, the custom URIs will not be assigned to the posts imported by Wp All Import Pro plugin.', 'permalink-manager')
121
  ),
122
  'yoast_breadcrumbs' => array(
123
  'type' => 'single_checkbox',
124
- 'label' => __('Filter breadcrumbs', 'permalink-manager'),
125
  'input_class' => '',
126
  'description' => __('If checked, the HTML breadcrumbs will be filtered by Permalink Manager to mimic the current URL structure.<br />Works with: <strong>WooCommerce, Yoast SEO, RankMath and SEOPress</strong> breadcrumbs.', 'permalink-manager')
127
  ),
128
  'partial_disable' => array(
129
  'type' => 'checkbox',
130
- 'label' => __('Exclude content types', 'permalink-manager'),
131
  'choices' => $content_types,
132
  'description' => __('Permalink Manager will ignore and not filter the custom permalinks of all selected above post types & taxonomies.', 'permalink-manager')
133
  ),
@@ -170,6 +199,15 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
170
  'choices' => array('edit_theme_options' => __('Administrator (edit_theme_options)', 'permalink-manager'), 'publish_pages' => __('Editor (publish_pages)', 'permalink-manager'), 'publish_posts' => __('Author (publish_posts)', 'permalink-manager'), 'edit_posts' => __('Contributor (edit_posts)', 'permalink-manager')),
171
  'description' => sprintf(__('Only the users who have selected capability will be able to access URI Editor.<br />The list of capabilities <a href="%s" target="_blank">can be found here</a>.', 'permalink-manager'), 'https://wordpress.org/support/article/roles-and-capabilities/#capability-vs-role-table')
172
  ),
 
 
 
 
 
 
 
 
 
173
  )
174
  )
175
  ));
38
  'type' => 'single_checkbox',
39
  'label' => __('Auto-update permalinks', 'permalink-manager'),
40
  'input_class' => '',
41
+ 'description' => sprintf('%s<br />%s',
42
+ __('<strong>Permalink Manager can automatically update the custom permalink after post or term is saved/updated.</strong>', 'permalink-manager'),
43
+ __('If enabled, Permalink Manager will always force the default custom permalink format (based on current <strong>Permastructure</strong> settings).', 'permalink-manager')
44
+ )
 
 
 
45
  ),
46
  'force_custom_slugs' => array(
47
  'type' => 'select',
48
+ 'label' => __('Slugs mode', 'permalink-manager'),
49
  'input_class' => 'settings-select',
50
+ 'choices' => array(0 => __('Use native slugs', 'permalink-manager'), 1 => __('Use actual titles as slugs', 'permalink-manager'), 2 => __('Inherit parents\' slugs', 'permalink-manager')),
51
+ 'description' => sprintf('%s<br />%s<br />%s',
52
+ __('<strong>Permalink Manager can use either native slugs or actual titles for custom permalinks.</strong>', 'permalink-manager'),
53
+ __('The native slug is generated from the initial title after the post or term is published.', 'permalink-manager'),
54
+ __('Use this field if you would like Permalink Manager to use the actual titles instead of native slugs.', 'permalink-manager')
55
+ )
56
+ ),
57
+ 'trailing_slashes' => array(
58
+ 'type' => 'select',
59
+ 'label' => __('Trailing slashes', 'permalink-manager'),
60
+ 'input_class' => 'settings-select',
61
+ 'choices' => array(0 => __('Use default settings', 'permalink-manager'), 1 => __('Add trailing slashes', 'permalink-manager'), 2 => __('Remove trailing slashes', 'permalink-manager')),
62
+ 'description' => __('This option can be used to alter the native settings and control if trailing slash should be added or removed from the end of posts & terms permalinks.', 'permalink-manager'),
63
+ 'description' => sprintf('%s<br />%s',
64
+ __('<strong>You can use this feature to either add or remove the slases from end of WordPress permalinks.</strong>', 'permalink-manager'),
65
+ __('Please use "<a href="#sslwww_redirect">Trailing slashes redirect</a>" field if you would like to force the settings with redirect.', 'permalink-manager')
66
+ )
67
  ),
 
 
 
 
 
 
 
68
  'canonical_redirect' => array(
69
  'type' => 'single_checkbox',
70
  'label' => __('Canonical redirect', 'permalink-manager'),
71
  'input_class' => '',
72
+ 'description' => sprintf('%s<br />%s',
73
+ __('<strong>Canonical redirect allows WordPress to "correct" the requested URL and redirect visitor to the canonical permalink.</strong>', 'permalink-manager'),
74
+ __('This feature will be also used to redirect (old) original permalinks to (new) custom permalinks set with Permalink Manager.', 'permalink-manager')
75
+ ),
76
  ),
77
  'old_slug_redirect' => array(
78
  'type' => 'single_checkbox',
79
  'label' => __('Old slug redirect', 'permalink-manager'),
80
  'input_class' => '',
81
+ 'description' => sprintf('%s<br />%s',
82
+ __('<strong>Old slug redirect is used by WordPress to provide a fallback for old version of slugs after they are changed.</strong>', 'permalink-manager'),
83
+ __('If enabled, the visitors trying to access the URL with the old slug will be redirected to the canonical permalink.', 'permalink-manager')
84
+ )
85
+ )
86
+ )
87
+ ),
88
+ 'seo' => array(
89
+ 'section_name' => __('Enhanced redirect', 'permalink-manager'),
90
+ 'container' => 'row',
91
+ 'name' => 'general',
92
+ 'fields' => array(
93
+ 'redirect' => array(
94
+ 'type' => 'select',
95
+ 'label' => __('Redirect mode', 'permalink-manager'),
96
+ 'input_class' => 'settings-select',
97
+ 'choices' => array(0 => __('Disable (Permalink Manager redirect functions)', 'permalink-manager'), "301" => __('301 redirect', 'permalink-manager'), "302" => __('302 redirect', 'permalink-manager')),
98
+ 'description' => sprintf('%s<br />%s',
99
+ __('<strong>Permalink Manager includes a set of hooks that allow to extend the redirect functions used natively by WordPress to avoid 404 errors.</strong>', 'permalink-manager'),
100
+ __('You can disable this feature if you do not want Permalink Manager to trigger any additional redirect functions at all.', 'permalink-manager')
101
+ )
102
  ),
103
  'setup_redirects' => array(
104
  'type' => 'single_checkbox',
106
  'input_class' => '',
107
  'pro' => true,
108
  'disabled' => true,
109
+ 'description' => sprintf('%s<br />%s',
110
+ __('<strong>Permalink Manager can automatically set-up extra redirects after the custom permalink is changed.</strong>', 'permalink-manager'),
111
+ __('If enabled, Permalink Manage will add redirect for earlier version of custom permalink after you change it (eg. with URI Editor or Regenerate/reset tool).', 'permalink-manager'),
112
+ __('You can disable this feature if you use another plugin for redirects, eg. Yoast SEO Premium or Redirection.', 'permalink-manager')
113
+ )
 
 
 
114
  ),
115
  'sslwww_redirect' => array(
116
  'type' => 'single_checkbox',
117
+ 'label' => __('Force HTTPS/WWW', 'permalink-manager'),
118
  'input_class' => '',
119
+ 'description' => sprintf('%s<br />%s',
120
+ __('<strong>You can use Permalink Manager to force SSL or "www" prefix in WordPress permalinks.</strong>', 'permalink-manager'),
121
+ __('Please disable it if you encounter any redirect loop issues.', 'permalink-manager')
122
+ )
123
  ),
124
+ 'trailing_slashes_redirect' => array(
125
+ 'type' => 'single_checkbox',
126
+ 'label' => __('Trailing slashes redirect', 'permalink-manager'),
127
+ 'input_class' => '',
128
+ 'description' => sprintf('%s',
129
+ __('<strong>Permalink Manager can force the trailing slashes settings in the custom permalinks with redirect.</strong>', 'permalink-manager')
130
+ )
131
  )
132
  )
133
  ),
138
  'fields' => array(
139
  'fix_language_mismatch' => array(
140
  'type' => 'single_checkbox',
141
+ 'label' => __('WPML/Polylang language mismatch', 'permalink-manager'),
142
  'input_class' => '',
143
  'description' => __('If enabled, the plugin will load the adjacent translation of post when the custom permalink is detected, but the language code in the URL does not match the language code assigned to the post/term.', 'permalink-manager')
144
  ),
145
  'pmxi_import_support' => array(
146
  'type' => 'single_checkbox',
147
+ 'label' => __('WP All Import support', 'permalink-manager'),
148
  'input_class' => '',
149
+ 'description' => __('If checked, the custom permalinks will not be saved for the posts imported with Wp All Import plugin.', 'permalink-manager')
150
  ),
151
  'yoast_breadcrumbs' => array(
152
  'type' => 'single_checkbox',
153
+ 'label' => __('Breadcrumbs support', 'permalink-manager'),
154
  'input_class' => '',
155
  'description' => __('If checked, the HTML breadcrumbs will be filtered by Permalink Manager to mimic the current URL structure.<br />Works with: <strong>WooCommerce, Yoast SEO, RankMath and SEOPress</strong> breadcrumbs.', 'permalink-manager')
156
  ),
157
  'partial_disable' => array(
158
  'type' => 'checkbox',
159
+ 'label' => __('Excluded content types', 'permalink-manager'),
160
  'choices' => $content_types,
161
  'description' => __('Permalink Manager will ignore and not filter the custom permalinks of all selected above post types & taxonomies.', 'permalink-manager')
162
  ),
199
  'choices' => array('edit_theme_options' => __('Administrator (edit_theme_options)', 'permalink-manager'), 'publish_pages' => __('Editor (publish_pages)', 'permalink-manager'), 'publish_posts' => __('Author (publish_posts)', 'permalink-manager'), 'edit_posts' => __('Contributor (edit_posts)', 'permalink-manager')),
200
  'description' => sprintf(__('Only the users who have selected capability will be able to access URI Editor.<br />The list of capabilities <a href="%s" target="_blank">can be found here</a>.', 'permalink-manager'), 'https://wordpress.org/support/article/roles-and-capabilities/#capability-vs-role-table')
201
  ),
202
+ 'auto_remove_duplicates' => array(
203
+ 'type' => 'select',
204
+ 'label' => __('Automatically fix broken URIs', 'permalink-manager'),
205
+ 'input_class' => 'settings-select',
206
+ 'choices' => array(0 => __('Disable', 'permalink-manager'), 1 => __('Fix URIs individually (during page load)', 'permalink-manager'), 2 => __('Bulk fix all URIs (once a day, in the background)', 'permalink-manager')),
207
+ 'description' => sprintf('%s',
208
+ __('Enable this option if you would like to automatically remove redundant permalinks & duplicated redirects.', 'permalink-manager')
209
+ )
210
+ ),
211
  )
212
  )
213
  ));
includes/views/permalink-manager-uri-editor-post.php CHANGED
@@ -233,7 +233,7 @@ 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');
233
  // Grab posts from database
234
  $sql_parts['start'] = "SELECT * FROM {$wpdb->posts} ";
235
  if($search_query) {
236
+ $sql_parts['where'] = "WHERE (LOWER(post_title) LIKE LOWER('%{$search_query}%') ";
237
 
238
  // Search in array with custom URIs
239
  $found = Permalink_Manager_Helper_Functions::search_uri($search_query, 'posts');
out/permalink-manager-admin.js CHANGED
@@ -227,11 +227,12 @@ jQuery(document).ready(function() {
227
  jQuery('#permalink-manager').on('change', 'select[name="auto_update_uri"]', function() {
228
  var selected = jQuery(this).find('option:selected');
229
  var auto_update_status = jQuery(selected).data('auto-update');
 
230
 
231
  if(auto_update_status == 1) {
232
- jQuery(custom_uri_input).attr("readonly", true);
233
  } else {
234
- jQuery(custom_uri_input).removeAttr("readonly", true);
235
  }
236
  });
237
  jQuery('select[name="auto_update_uri"]').trigger("change");
@@ -306,6 +307,9 @@ jQuery(document).ready(function() {
306
  jQuery(pm_container).find('.permalink-manager-gutenberg').replaceWith(html);
307
  jQuery(pm_container).LoadingOverlay("hide");
308
 
 
 
 
309
  if(wp && wp.data !== 'undefined') {
310
  wp.data.dispatch('core/editor').refreshPost();
311
  }
@@ -354,14 +358,17 @@ jQuery(document).ready(function() {
354
  /**
355
  * Help tooltips
356
  */
357
- if(jQuery('#permalink-manager .help_tooltip').length > 0) {
358
- new Tippy('#permalink-manager .help_tooltip', {
359
- position: 'top-start',
360
- arrow: true,
361
- theme: 'tippy-pm',
362
- distance: 20,
363
- });
 
 
364
  }
 
365
 
366
 
367
  /**
227
  jQuery('#permalink-manager').on('change', 'select[name="auto_update_uri"]', function() {
228
  var selected = jQuery(this).find('option:selected');
229
  var auto_update_status = jQuery(selected).data('auto-update');
230
+ var container = jQuery(this).parents('#permalink-manager');
231
 
232
  if(auto_update_status == 1) {
233
+ jQuery(container).find('input[name="custom_uri"]').attr("readonly", true);
234
  } else {
235
+ jQuery(container).find('input[name="custom_uri"]').removeAttr("readonly", true);
236
  }
237
  });
238
  jQuery('select[name="auto_update_uri"]').trigger("change");
307
  jQuery(pm_container).find('.permalink-manager-gutenberg').replaceWith(html);
308
  jQuery(pm_container).LoadingOverlay("hide");
309
 
310
+ jQuery(pm_container).find('select[name="auto_update_uri"]').trigger("change");
311
+ pm_help_tooltips();
312
+
313
  if(wp && wp.data !== 'undefined') {
314
  wp.data.dispatch('core/editor').refreshPost();
315
  }
358
  /**
359
  * Help tooltips
360
  */
361
+ function pm_help_tooltips() {
362
+ if(jQuery('#permalink-manager .help_tooltip').length > 0) {
363
+ new Tippy('#permalink-manager .help_tooltip', {
364
+ position: 'top-start',
365
+ arrow: true,
366
+ theme: 'tippy-pm',
367
+ distance: 20,
368
+ });
369
+ }
370
  }
371
+ pm_help_tooltips();
372
 
373
 
374
  /**
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.4
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.9.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.4' );
29
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
30
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
31
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__));
@@ -63,6 +63,7 @@ if(!class_exists('Permalink_Manager_Class')) {
63
  'admin-functions' => 'Permalink_Manager_Admin_Functions',
64
  'actions' => 'Permalink_Manager_Actions',
65
  'third-parties' => 'Permalink_Manager_Third_Parties',
 
66
  'core-functions' => 'Permalink_Manager_Core_Functions',
67
  'gutenberg' => 'Permalink_Manager_Gutenberg',
68
  'debug' => 'Permalink_Manager_Debug_Functions',
@@ -150,9 +151,6 @@ if(!class_exists('Permalink_Manager_Class')) {
150
  * Set the initial/default settings (including "Screen Options")
151
  */
152
  public function default_settings($settings) {
153
- $all_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
154
- $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
155
-
156
  $default_settings = apply_filters('permalink_manager_default_options', array(
157
  'screen-options' => array(
158
  'per_page' => 20,
@@ -166,9 +164,10 @@ if(!class_exists('Permalink_Manager_Class')) {
166
  'sslwww_redirect' => 0,
167
  'canonical_redirect' => 1,
168
  'old_slug_redirect' => 0,
169
- 'setup_redirects' => 1,
170
  'redirect' => '301',
171
  'trailing_slashes' => 0,
 
172
  'auto_remove_duplicates' => 1,
173
  'fix_language_mismatch' => 1,
174
  'pmxi_import_support' => 0,
@@ -176,7 +175,9 @@ if(!class_exists('Permalink_Manager_Class')) {
176
  'force_custom_slugs' => 0,
177
  'disable_slug_sanitization' => 0,
178
  'keep_accents' => 0,
179
- 'partial_disable' => array(),
 
 
180
  'deep_detect' => 1,
181
  'edit_uris_cap' => 'publish_posts',
182
  ),
@@ -236,25 +237,19 @@ if(!class_exists('Permalink_Manager_Class')) {
236
 
237
  // Adjust options structure
238
  if(!empty($permalink_manager_options['miscellaneous'])) {
239
- // Combine general & general
240
  $permalink_manager_unfiltered_options['general'] = array_merge($permalink_manager_unfiltered_options['general'], $permalink_manager_unfiltered_options['miscellaneous']);
241
 
242
  // Move licence key to different section
243
  $permalink_manager_unfiltered_options['licence']['licence_key'] = (!empty($permalink_manager_unfiltered_options['miscellaneous']['license_key'])) ? $permalink_manager_unfiltered_options['miscellaneous']['license_key'] : "";
244
-
245
- // Remove redundant keys
246
- unset($permalink_manager_unfiltered_options['general']['license_key']);
247
- unset($permalink_manager_unfiltered_options['miscellaneous']);
248
- unset($permalink_manager_unfiltered_options['permalink_manager_options']);
249
- unset($permalink_manager_unfiltered_options['_wp_http_referer']);
250
  }
251
 
252
- // Adjust "Force Custom Slugs" + "Sanitize" settings
253
- if(!empty($permalink_manager_options['general']['force_custom_slugs']) && $permalink_manager_options['general']['force_custom_slugs'] == 2) {
254
  $permalink_manager_unfiltered_options = $permalink_manager_options;
255
 
256
- $permalink_manager_unfiltered_options['general']['force_custom_slugs'] = 1;
257
- $permalink_manager_unfiltered_options['general']['disable_slug_sanitization'] = 1;
258
  }
259
 
260
  // Save the settings in database
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.5
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.0.0
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.5' );
29
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
30
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
31
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__));
63
  'admin-functions' => 'Permalink_Manager_Admin_Functions',
64
  'actions' => 'Permalink_Manager_Actions',
65
  'third-parties' => 'Permalink_Manager_Third_Parties',
66
+ 'language-plugins' => 'Permalink_Manager_Language_Plugins',
67
  'core-functions' => 'Permalink_Manager_Core_Functions',
68
  'gutenberg' => 'Permalink_Manager_Gutenberg',
69
  'debug' => 'Permalink_Manager_Debug_Functions',
151
  * Set the initial/default settings (including "Screen Options")
152
  */
153
  public function default_settings($settings) {
 
 
 
154
  $default_settings = apply_filters('permalink_manager_default_options', array(
155
  'screen-options' => array(
156
  'per_page' => 20,
164
  'sslwww_redirect' => 0,
165
  'canonical_redirect' => 1,
166
  'old_slug_redirect' => 0,
167
+ 'setup_redirects' => 0,
168
  'redirect' => '301',
169
  'trailing_slashes' => 0,
170
+ 'trailing_slash_redirect' => 0,
171
  'auto_remove_duplicates' => 1,
172
  'fix_language_mismatch' => 1,
173
  'pmxi_import_support' => 0,
175
  'force_custom_slugs' => 0,
176
  'disable_slug_sanitization' => 0,
177
  'keep_accents' => 0,
178
+ 'partial_disable' => array(
179
+ 'post_types' => array('attachment', 'tribe_events')
180
+ ),
181
  'deep_detect' => 1,
182
  'edit_uris_cap' => 'publish_posts',
183
  ),
237
 
238
  // Adjust options structure
239
  if(!empty($permalink_manager_options['miscellaneous'])) {
240
+ // Combine general & miscellaneous options
241
  $permalink_manager_unfiltered_options['general'] = array_merge($permalink_manager_unfiltered_options['general'], $permalink_manager_unfiltered_options['miscellaneous']);
242
 
243
  // Move licence key to different section
244
  $permalink_manager_unfiltered_options['licence']['licence_key'] = (!empty($permalink_manager_unfiltered_options['miscellaneous']['license_key'])) ? $permalink_manager_unfiltered_options['miscellaneous']['license_key'] : "";
 
 
 
 
 
 
245
  }
246
 
247
+ // Separate "Trailing slashes" & "Trailing slashes redirect" setting fields
248
+ if(!empty($permalink_manager_options['general']['trailing_slashes']) && $permalink_manager_options['general']['trailing_slashes'] >= 10) {
249
  $permalink_manager_unfiltered_options = $permalink_manager_options;
250
 
251
+ $permalink_manager_unfiltered_options['general']['trailing_slashes_redirect'] = 1;
252
+ $permalink_manager_unfiltered_options['general']['trailing_slashes'] = ($permalink_manager_options['general']['trailing_slashes'] == 10) ? 1 : 2;
253
  }
254
 
255
  // Save the settings in database