Permalink Manager Lite - Version 2.1.2.4

Version Description

Download this release

Release Info

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

Code changes from version 2.1.1 to 2.1.2.4

README.txt CHANGED
@@ -6,8 +6,8 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
6
  Tags: urls, permalinks, custom permalinks, url, permalink, woocommerce permalinks
7
  Requires at least: 4.4.0
8
  Requires PHP: 5.4
9
- Tested up to: 4.9
10
- Stable tag: 2.1.1
11
 
12
  Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
13
 
@@ -82,9 +82,30 @@ A. Currently there is no 100% guarantee that Permalink Manager will work correct
82
  5. A list of updated posts.
83
  6. Editable URI box in Post/Page/CPT edit pagees.
84
  7. Settings section.
 
85
 
86
  == Changelog ==
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  = 2.1.1 =
89
  * Support for draft custom permalinks
90
  * Support for WP All Import plugin, now the custom permalinks can be defined directly in XML, CSV, ZIP, GZIP, GZ, JSON, SQL, TXT, DAT or PSV import files.
6
  Tags: urls, permalinks, custom permalinks, url, permalink, woocommerce permalinks
7
  Requires at least: 4.4.0
8
  Requires PHP: 5.4
9
+ Tested up to: 5.0
10
+ Stable tag: 2.1.2.4
11
 
12
  Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
13
 
82
  5. A list of updated posts.
83
  6. Editable URI box in Post/Page/CPT edit pagees.
84
  7. Settings section.
85
+ 8. URI Editor in Gutenberg.
86
 
87
  == Changelog ==
88
 
89
+ = 2.1.2.3/2.1.2.4 =
90
+ * Hotfix for WPML - ?lang query parameter is now appended correctly
91
+ * Support for comment pages endpoint
92
+ * Minor code adjustments
93
+ * Metabox for Gutenberg enabled also for CPT
94
+ * Further improvements for redirect hooks
95
+ * Hotfix for WP Customizer
96
+ * Native slugs are saved correctly in Gutenberg editor
97
+ * New filter - "permalink_manager_filter_permastructure" + Permastructures can be now translated from admin panel
98
+
99
+ = 2.1.2.1/2.1.2.2 =
100
+ * Hotfix for "Force custom slugs" option - now special characters are not removed if "Yes, use post/term titles + do not strip special characters: .|-+" mode is set.
101
+ * Hotfix for custom fields support in custom permalinks
102
+
103
+ = 2.1.2 =
104
+ * Hotfix for WP All Import - default permalinks are now assigned correctly to imported posts + possibility to disable WP All Import custom URI functions in Permalink Manager settings
105
+ * Hotfix for Yoast SEO - notice displayed on author pages
106
+ * Adjustments for sanitize slug functions
107
+ * Basic support for Gutenberg added
108
+
109
  = 2.1.1 =
110
  * Support for draft custom permalinks
111
  * Support for WP All Import plugin, now the custom permalinks can be defined directly in XML, CSV, ZIP, GZIP, GZ, JSON, SQL, TXT, DAT or PSV import files.
includes/core/permalink-manager-actions.php CHANGED
@@ -8,8 +8,9 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
8
  add_action('admin_init', array($this, 'trigger_action'), 9);
9
  add_action('admin_init', array($this, 'extra_actions'));
10
 
11
- // Ajax-based bulk tools
12
  add_action('wp_ajax_pm_bulk_tools', array($this, 'pm_bulk_tools'));
 
13
 
14
  add_action('clean_permalinks_event', array($this, 'clean_permalinks_hook'));
15
  add_action('init', array($this, 'clean_permalinks_cronjob'));
@@ -189,6 +190,25 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
189
  die();
190
  }
191
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
  /**
193
  * Update all permalinks in "Permalink Editor"
194
  */
@@ -553,5 +573,3 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
553
  }
554
 
555
  }
556
-
557
- ?>
8
  add_action('admin_init', array($this, 'trigger_action'), 9);
9
  add_action('admin_init', array($this, 'extra_actions'));
10
 
11
+ // Ajax-based functions
12
  add_action('wp_ajax_pm_bulk_tools', array($this, 'pm_bulk_tools'));
13
+ add_action('wp_ajax_pm_save_permalink', array($this, 'pm_save_permalink'));
14
 
15
  add_action('clean_permalinks_event', array($this, 'clean_permalinks_hook'));
16
  add_action('init', array($this, 'clean_permalinks_cronjob'));
190
  die();
191
  }
192
 
193
+ /**
194
+ * Save permalink via AJAX
195
+ */
196
+ public function pm_save_permalink() {
197
+ $element_id = (!empty($_POST['permalink-manager-edit-uri-element-id'])) ? sanitize_text_field($_POST['permalink-manager-edit-uri-element-id']) : '';
198
+
199
+ if(!empty($element_id) && is_numeric($element_id)) {
200
+ Permalink_Manager_URI_Functions_Post::update_post_uri($element_id);
201
+
202
+ // Reload URI Editor & clean post cache
203
+ clean_post_cache($element_id);
204
+ $element = get_post($element_id);
205
+ $html = Permalink_Manager_Admin_Functions::display_uri_box($element, true);
206
+
207
+ echo $html;
208
+ die();
209
+ }
210
+ }
211
+
212
  /**
213
  * Update all permalinks in "Permalink Editor"
214
  */
573
  }
574
 
575
  }
 
 
includes/core/permalink-manager-admin-functions.php CHANGED
@@ -129,7 +129,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
129
  * Generate the fields
130
  */
131
  static public function generate_option_field($input_name, $args) {
132
- global $permalink_manager_options;
133
 
134
  // Reset $fields variables
135
  $fields = $section_name = $field_name = '';
@@ -212,7 +212,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
212
  $checked = ($value == 1) ? "checked='checked'" : "";
213
  $checkbox_label = (isset($args['checkbox_label'])) ? $args['checkbox_label'] : '';
214
 
215
- $fields .= "<input type='hidden' {$input_atts} value='0' name='{$input_name}' checked=\"checked\" />";
216
  $fields .= "<label for='{$input_name}'><input type='checkbox' {$input_atts} value='1' name='{$input_name}' {$checked} /> {$checkbox_label}</label>";
217
  $fields .= '</div>';
218
  break;
@@ -268,7 +268,75 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
268
 
269
  case 'permastruct' :
270
  $siteurl = Permalink_Manager_Helper_Functions::get_permalink_base();
271
- $fields .= "<div class=\"permastruct-container\"><span><code>{$siteurl}/</code></span><span><input type='text' {$input_atts} value='{$value}' name='{$input_name}'/></span></div>";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  break;
273
 
274
  default :
@@ -309,7 +377,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
309
  /**
310
  * Display the form
311
  */
312
- static public function get_the_form($fields = array(), $container = '', $button = array(), $sidebar = '', $nonce = array(), $wrap = false) {
313
  // 1. Check if the content will be displayed in columns and button details
314
  switch($container) {
315
  case 'columns-3' :
@@ -331,6 +399,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
331
  $button_attributes = (!empty($button['attributes'])) ? $button['attributes'] : '';
332
  $nonce_action = (!empty($nonce['action'])) ? $nonce['action'] : '';
333
  $nonce_name = (!empty($nonce['name'])) ? $nonce['name'] : '';
 
334
 
335
  // 2. Now get the HTML output (start section row container)
336
  $html = ($wrapper_class) ? "<div class=\"{$wrapper_class}\">" : '';
@@ -346,7 +415,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
346
 
347
  // 4. Start fields' section
348
  $html .= ($form_column_class) ? "<div class=\"{$form_column_class}\">" : "";
349
- $html .= "<form method=\"POST\">";
350
  $html .= ($wrap) ? "<table class=\"form-table\">" : "";
351
 
352
  // Loop through all fields assigned to this section
@@ -471,31 +540,6 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
471
  echo $html;
472
  }
473
 
474
- /**
475
- * Display error/info message
476
- */
477
- public static function get_alert_message($alert_content = "", $alert_type = "", $dismissable = true, $id = false) {
478
- // Ignore empty messages (just in case)
479
- if(empty($alert_content) || empty($alert_type)) {
480
- return "";
481
- }
482
-
483
- $class = ($dismissable) ? "is-dismissible" : "";
484
- $alert_id = ($id) ? " data-alert_id=\"{$id}\"" : "";
485
-
486
- $html = sprintf( "<div class=\"{$alert_type} permalink-manager-notice notice {$class}\"{$alert_id}> %s</div>", wpautop($alert_content) );
487
-
488
- return $html;
489
- }
490
-
491
- /**
492
- * Help tooltip
493
- */
494
- static function help_tooltip($text = '') {
495
- $html = " <a href=\"#\" title=\"{$text}\" class=\"help_tooltip\"><span class=\"dashicons dashicons-editor-help\"></span></a>";
496
- return $html;
497
- }
498
-
499
  /**
500
  * Display the table with updated slugs after one of the actions is triggered
501
  */
@@ -602,15 +646,25 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
602
  return $html;
603
  }
604
 
 
 
 
 
 
 
 
 
605
  /**
606
  * Display "Permalink Manager" box
607
  */
608
- public static function display_uri_box($element, $default_uri, $uri, $native_uri) {
609
- global $permalink_manager_options;
610
 
611
  if(!empty($element->ID)) {
612
  $id = $element_id = $element->ID;
613
  $native_slug = $element->post_name;
 
 
614
 
615
  // Auto-update settings
616
  $auto_update_val = get_post_meta($id, "auto_update_uri", true);
@@ -621,38 +675,55 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
621
  -1 => array("label" => __("No", "permalink-manager"), "atts" => "data-auto-update=\"0\""),
622
  1 => array("label" => __("Yes", "permalink-manager"), "atts" => "data-auto-update=\"1\"")
623
  );
624
- } else {
 
 
 
 
 
625
  $id = $element->term_id;
626
  $element_id = "tax-{$id}";
627
  $native_slug = $element->slug;
 
 
 
 
 
 
 
628
  }
629
 
630
  // Decode default URI
631
  $default_uri = urldecode($default_uri);
632
 
 
633
  // 1. Button
634
- $html = sprintf("<span><button type=\"button\" class=\"button button-small hide-if-no-js\" id=\"permalink-manager-toggle\">%s</button></span>", __("Permalink Manager", "permalink-manager"));
 
635
 
636
- $html .= "<div id=\"permalink-manager\" class=\"postbox permalink-manager-edit-uri-box\" style=\"display: none;\">";
637
 
638
- // 2. The heading
639
- $html .= "<a class=\"close-button\"><span class=\"screen-reader-text\">" . __("Close: ", "permalink-manager") . __("Permalink Manager", "permalink-manager") . "</span><span class=\"close-icon\" aria-hidden=\"false\"></span></a>";
640
- $html .= sprintf("<h2><span>%s</span></h2>", __("Permalink Manager", "permalink-manager"));
641
 
642
- // 3. The fields container [start]
643
- $html .= "<div class=\"inside\">";
 
 
 
644
 
645
  // 4. Custom URI
646
- if(!empty($element->ID) && get_option('page_on_front') == $id) {
647
- $custom_uri_field = Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("type" => "hidden", "extra_atts" => "data-default=\"{$default_uri}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat custom_uri", "value" => urldecode($uri)));
648
  $custom_uri_field .= __("The custom URI cannot be edited on frontpage.", "permalink-manager");
649
  } else {
650
- $custom_uri_field = Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("extra_atts" => "data-default=\"{$default_uri}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat custom_uri", "value" => urldecode($uri)));
651
  }
652
 
653
- $html .= sprintf("<div class=\"custom_uri_container\"><label for=\"custom_uri\" class=\"strong\">%s %s</label><span>%s</span><span class=\"duplicated_uri_alert\"></span></div>",
654
  __("Current URI", "permalink-manager"),
655
- ($element->ID) ? Permalink_Manager_Admin_Functions::help_tooltip(__("The custom URI can be edited only if 'Auto-update the URI' feature is not enabled.", "permalink-manager")) : "",
656
  $custom_uri_field
657
  );
658
 
@@ -660,7 +731,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
660
  if(!empty($element->ID) && !empty($permalink_manager_options["general"]["show_native_slug_field"])) {
661
  $native_slug_field = Permalink_Manager_Admin_Functions::generate_option_field("native_slug", array("extra_atts" => "data-default=\"{$native_slug}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat native_slug", "value" => urldecode($native_slug)));
662
 
663
- $html .= sprintf("<div class=\"native_slug_container\"><label for=\"native_slug\" class=\"strong\">%s %s</label><span>%s</span></div>",
664
  __("Native slug", "permalink-manager"),
665
  Permalink_Manager_Admin_Functions::help_tooltip(__("The native slug is by default automatically used in native permalinks (when Permalink Manager is disabled).", "permalink-manager")),
666
  $native_slug_field
@@ -668,10 +739,10 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
668
  }
669
 
670
  // Three fields that should be hidden on front-page
671
- if(get_option('page_on_front') != $id) {
672
  // 6. Auto-update URI
673
  if(!empty($auto_update_choices)) {
674
- $html .= sprintf("<div><label for=\"auto_auri\" class=\"strong\">%s %s</label><span>%s</span></div>",
675
  __("Auto-update the URI", "permalink-manager"),
676
  Permalink_Manager_Admin_Functions::help_tooltip(__("If enabled, the 'Current URI' field will be automatically changed to 'Default URI' (displayed below) after the post is saved or updated.", "permalink-manager")),
677
  Permalink_Manager_Admin_Functions::generate_option_field("auto_update_uri", array("type" => "select", "input_class" => "widefat auto_update", "value" => $auto_update_val, "choices" => $auto_update_choices))
@@ -682,7 +753,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
682
  $html .= sprintf(
683
  "<div class=\"default-permalink-row columns-container\"><span class=\"column-3_4\"><strong>%s:</strong> %s</span><span class=\"column-1_4\"><a href=\"#\" class=\"restore-default\"><span class=\"dashicons dashicons-image-rotate\"></span> %s</a></span></div>",
684
  __("Default URI", "permalink-manager"), esc_html($default_uri),
685
- __("Restore to Default URI", "permalink-manager")
686
  );
687
 
688
  // 8. Native URI info
@@ -702,10 +773,19 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
702
  // 9. Custom redirects
703
  $html .= ($element->ID) ? self::display_redirect_panel($id) : self::display_redirect_panel("tax-{$id}");
704
 
 
 
 
 
 
 
 
 
705
  $html .= "</div>";
706
  $html .= "</div>";
707
 
708
- // 9. Append nonce field & element ID
 
709
  $html .= Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-edit-uri-element-id", array("type" => "hidden", "value" => $element_id));
710
  $html .= wp_nonce_field('permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false);
711
 
@@ -720,9 +800,8 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
720
 
721
  // Heading
722
  $html = sprintf(
723
- "<div class=\"permalink-manager redirects-row redirects-panel columns-container\"><div class=\"heading\"><span class=\"dashicons dashicons-edit\"></span> <a href=\"#\" id=\"toggle-redirect-panel\">%s <small>%s</small></a></span></div>",
724
- __("Manage redirects", "permalink-manager"),
725
- __("[click to open]", "permalink-manager")
726
  );
727
 
728
  $html .= "<div id=\"redirect-panel-inside\">";
@@ -740,11 +819,28 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
740
  }
741
 
742
  /**
743
- * Hide "Custom URI" column
744
  */
745
- function quick_edit_hide_column($hidden, $screen) {
746
- $hidden[] = 'permalink-manager-col';
747
- return $hidden;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  }
749
 
750
  /**
@@ -817,9 +913,9 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
817
  // Convert the output to JSON and stop the function
818
  echo json_encode($duplicates_array);
819
  } else if(!empty($_REQUEST['custom_uri']) && !empty($_REQUEST['element_id'])) {
820
- $is_duplicated = Permalink_Manager_Helper_Functions::is_uri_duplicated($uri, $element_id) ? $duplicate_alert : 0;
821
 
822
- echo $is_duplicated;
823
  }
824
 
825
  die();
129
  * Generate the fields
130
  */
131
  static public function generate_option_field($input_name, $args) {
132
+ global $permalink_manager_options, $permalink_manager_permastructs;
133
 
134
  // Reset $fields variables
135
  $fields = $section_name = $field_name = '';
212
  $checked = ($value == 1) ? "checked='checked'" : "";
213
  $checkbox_label = (isset($args['checkbox_label'])) ? $args['checkbox_label'] : '';
214
 
215
+ $fields .= "<input type='hidden' {$input_atts} value='0' name='{$input_name}' />";
216
  $fields .= "<label for='{$input_name}'><input type='checkbox' {$input_atts} value='1' name='{$input_name}' {$checked} /> {$checkbox_label}</label>";
217
  $fields .= '</div>';
218
  break;
268
 
269
  case 'permastruct' :
270
  $siteurl = Permalink_Manager_Helper_Functions::get_permalink_base();
271
+
272
+ if(!empty($args['post_type'])) {
273
+ $type = $args['post_type'];
274
+ $type_name = $type['name'];
275
+
276
+ $permastructures = $permalink_manager_permastructs['post_types'];
277
+ } else if(!empty($args['taxonomy'])) {
278
+ $type = $args['taxonomy'];
279
+ $type_name = $type['name'];
280
+
281
+ $permastructures = $permalink_manager_permastructs['taxonomies'];
282
+ } else {
283
+ break;
284
+ }
285
+
286
+ // Get permastructures
287
+ $default_permastruct = trim(Permalink_Manager_Helper_Functions::get_default_permastruct($type_name), "/");
288
+ $current_permastruct = isset($permastructures[$type_name]) ? $permastructures[$type_name] : $default_permastruct;
289
+
290
+ // Append extra attributes
291
+ $input_atts .= " data-default=\"{$default_permastruct}\"";
292
+ $input_atts .= " placeholder=\"{$default_permastruct}\"";
293
+
294
+ $fields .= "<div class=\"all-permastruct-container\">";
295
+
296
+ // 1. Default permastructure
297
+ $fields .= "<div class=\"permastruct-container\">";
298
+ $fields .= "<span><code>{$siteurl}/</code></span>";
299
+ $fields .= "<span><input type='text' {$input_atts} value='{$current_permastruct}' name='{$input_name}'/></span>";
300
+ $fields .= "</div>";
301
+
302
+ $fields .= "<div class=\"permastruct-toggle\">";
303
+
304
+ // 2A. Permastructure for each language
305
+ $languages = (array) Permalink_Manager_Third_Parties::get_all_languages(true);
306
+ if($languages) {
307
+ $fields .= sprintf(
308
+ "<h4>%s</h4><p class=\"permastruct-instruction\">%s</p>",
309
+ __("Permastructure translations", "permalink-manager"),
310
+ __("If you would like to translate the permastructures and set-up different permalink structure per language, please fill in the fields below. Otherwise the permastructure set for default language (see field above) will be applied.", "permalink-manager")
311
+ );
312
+
313
+ foreach($languages as $lang => $name) {
314
+ $current_lang_permastruct = isset($permastructures["{$type_name}_{$lang}"]) ? $permastructures["{$type_name}_{$lang}"] : $default_permastruct;
315
+
316
+ $fields .= "<label>{$name}</label>";
317
+ $fields .= "<div class=\"permastruct-container\">";
318
+ $fields .= "<span><code>{$siteurl}/</code></span>";
319
+ $fields .= sprintf("<span><input type='text' %s value='%s' name='%s'/></span>", $input_atts, $current_lang_permastruct, str_replace("]", "_{$lang}]", $input_name));
320
+ $fields .= "</div>";
321
+ }
322
+ }
323
+
324
+ // 2B. Restore default permalinks
325
+ $fields .= sprintf(
326
+ "<p class=\"default-permastruct-row columns-container\"><span class=\"column-2_4\"><strong>%s:</strong> %s</span><span class=\"column-2_4\"><a href=\"#\" class=\"restore-default\"><span class=\"dashicons dashicons-image-rotate\"></span> %s</a></span></p>",
327
+ __("Default permastructure", "permalink-manager"), esc_html($default_permastruct),
328
+ __("Restore default permastructure", "permalink-manager")
329
+ );
330
+ $fields .= "</div>";
331
+
332
+ // 3. Show toggle button
333
+ $fields .= sprintf(
334
+ "<p class=\"permastruct-toggle-button\"><a href=\"#\"><span class=\"dashicons dashicons-admin-settings\"></span> %s</a></p>",
335
+ __("Show additional settings", "permalink-manager")
336
+ );
337
+
338
+ $fields .= "</div>";
339
+
340
  break;
341
 
342
  default :
377
  /**
378
  * Display the form
379
  */
380
+ static public function get_the_form($fields = array(), $container = '', $button = array(), $sidebar = '', $nonce = array(), $wrap = false, $form_class = '') {
381
  // 1. Check if the content will be displayed in columns and button details
382
  switch($container) {
383
  case 'columns-3' :
399
  $button_attributes = (!empty($button['attributes'])) ? $button['attributes'] : '';
400
  $nonce_action = (!empty($nonce['action'])) ? $nonce['action'] : '';
401
  $nonce_name = (!empty($nonce['name'])) ? $nonce['name'] : '';
402
+ $form_classes = (!empty($form_class)) ? $form_class : '';
403
 
404
  // 2. Now get the HTML output (start section row container)
405
  $html = ($wrapper_class) ? "<div class=\"{$wrapper_class}\">" : '';
415
 
416
  // 4. Start fields' section
417
  $html .= ($form_column_class) ? "<div class=\"{$form_column_class}\">" : "";
418
+ $html .= "<form method=\"POST\" class=\"{$form_classes}\">";
419
  $html .= ($wrap) ? "<table class=\"form-table\">" : "";
420
 
421
  // Loop through all fields assigned to this section
540
  echo $html;
541
  }
542
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  /**
544
  * Display the table with updated slugs after one of the actions is triggered
545
  */
646
  return $html;
647
  }
648
 
649
+ /**
650
+ * Hide "Custom URI" column
651
+ */
652
+ function quick_edit_hide_column($hidden, $screen) {
653
+ $hidden[] = 'permalink-manager-col';
654
+ return $hidden;
655
+ }
656
+
657
  /**
658
  * Display "Permalink Manager" box
659
  */
660
+ public static function display_uri_box($element, $gutenberg = false) {
661
+ global $permalink_manager_options, $permalink_manager_uris;
662
 
663
  if(!empty($element->ID)) {
664
  $id = $element_id = $element->ID;
665
  $native_slug = $element->post_name;
666
+ $is_draft = (!empty($element->post_status) && (in_array($element->post_status, array('draft', 'auto-draft')))) ? true : false;
667
+ $is_front_page = Permalink_Manager_Helper_Functions::is_front_page($id);
668
 
669
  // Auto-update settings
670
  $auto_update_val = get_post_meta($id, "auto_update_uri", true);
675
  -1 => array("label" => __("No", "permalink-manager"), "atts" => "data-auto-update=\"0\""),
676
  1 => array("label" => __("Yes", "permalink-manager"), "atts" => "data-auto-update=\"1\"")
677
  );
678
+
679
+ // Get URIs
680
+ $uri = Permalink_Manager_URI_Functions_Post::get_post_uri($id, true, $is_draft);
681
+ $default_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
682
+ $native_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id, true);
683
+ } else if(class_exists('Permalink_Manager_URI_Functions_Tax')) {
684
  $id = $element->term_id;
685
  $element_id = "tax-{$id}";
686
  $native_slug = $element->slug;
687
+
688
+ // Get URIs
689
+ $uri = Permalink_Manager_URI_Functions_Tax::get_term_uri($element->term_id, true);
690
+ $default_uri = Permalink_Manager_URI_Functions_Tax::get_default_term_uri($element->term_id);
691
+ $native_uri = Permalink_Manager_URI_Functions_Tax::get_default_term_uri($element->term_id, true);
692
+ } else {
693
+ return;
694
  }
695
 
696
  // Decode default URI
697
  $default_uri = urldecode($default_uri);
698
 
699
+ // Start HTML output
700
  // 1. Button
701
+ if(!$gutenberg) {
702
+ $html = sprintf("<span><button type=\"button\" class=\"button button-small hide-if-no-js\" id=\"permalink-manager-toggle\">%s</button></span>", __("Permalink Manager", "permalink-manager"));
703
 
704
+ $html .= "<div id=\"permalink-manager\" class=\"postbox permalink-manager-edit-uri-box\" style=\"display: none;\">";
705
 
706
+ // 2. The heading
707
+ $html .= "<a class=\"close-button\"><span class=\"screen-reader-text\">" . __("Close: ", "permalink-manager") . __("Permalink Manager", "permalink-manager") . "</span><span class=\"close-icon\" aria-hidden=\"false\"></span></a>";
708
+ $html .= sprintf("<h2><span>%s</span></h2>", __("Permalink Manager", "permalink-manager"));
709
 
710
+ // 3. The fields container [start]
711
+ $html .= "<div class=\"inside\">";
712
+ } else {
713
+ $html = "<div class=\"permalink-manager-gutenberg permalink-manager-edit-uri-box\">";
714
+ }
715
 
716
  // 4. Custom URI
717
+ if(!empty($is_front_page)) {
718
+ $custom_uri_field = Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("type" => "hidden", "extra_atts" => "data-default=\"{$default_uri}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat custom_uri", "value" => rawurldecode($uri)));
719
  $custom_uri_field .= __("The custom URI cannot be edited on frontpage.", "permalink-manager");
720
  } else {
721
+ $custom_uri_field = Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("extra_atts" => "data-default=\"{$default_uri}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat custom_uri", "value" => rawurldecode($uri)));
722
  }
723
 
724
+ $html .= sprintf("<div class=\"custom_uri_container\"><p><label for=\"custom_uri\" class=\"strong\">%s %s</label></p><span>%s</span><span class=\"duplicated_uri_alert\"></span></div>",
725
  __("Current URI", "permalink-manager"),
726
+ ($element->ID) ? Permalink_Manager_Admin_Functions::help_tooltip(__("If custom URI is not defined, a default URI will be set (see below). The custom URI can be edited only if 'Auto-update the URI' feature is not enabled.", "permalink-manager")) : "",
727
  $custom_uri_field
728
  );
729
 
731
  if(!empty($element->ID) && !empty($permalink_manager_options["general"]["show_native_slug_field"])) {
732
  $native_slug_field = Permalink_Manager_Admin_Functions::generate_option_field("native_slug", array("extra_atts" => "data-default=\"{$native_slug}\" data-element-id=\"{$element_id}\"", "input_class" => "widefat native_slug", "value" => urldecode($native_slug)));
733
 
734
+ $html .= sprintf("<div class=\"native_slug_container\"><p><label for=\"native_slug\" class=\"strong\">%s %s</label></p><span>%s</span></div>",
735
  __("Native slug", "permalink-manager"),
736
  Permalink_Manager_Admin_Functions::help_tooltip(__("The native slug is by default automatically used in native permalinks (when Permalink Manager is disabled).", "permalink-manager")),
737
  $native_slug_field
739
  }
740
 
741
  // Three fields that should be hidden on front-page
742
+ if(empty($is_front_page)) {
743
  // 6. Auto-update URI
744
  if(!empty($auto_update_choices)) {
745
+ $html .= sprintf("<div><p><label for=\"auto_auri\" class=\"strong\">%s %s</label></p><span>%s</span></div>",
746
  __("Auto-update the URI", "permalink-manager"),
747
  Permalink_Manager_Admin_Functions::help_tooltip(__("If enabled, the 'Current URI' field will be automatically changed to 'Default URI' (displayed below) after the post is saved or updated.", "permalink-manager")),
748
  Permalink_Manager_Admin_Functions::generate_option_field("auto_update_uri", array("type" => "select", "input_class" => "widefat auto_update", "value" => $auto_update_val, "choices" => $auto_update_choices))
753
  $html .= sprintf(
754
  "<div class=\"default-permalink-row columns-container\"><span class=\"column-3_4\"><strong>%s:</strong> %s</span><span class=\"column-1_4\"><a href=\"#\" class=\"restore-default\"><span class=\"dashicons dashicons-image-rotate\"></span> %s</a></span></div>",
755
  __("Default URI", "permalink-manager"), esc_html($default_uri),
756
+ __("Restore Default URI", "permalink-manager")
757
  );
758
 
759
  // 8. Native URI info
773
  // 9. Custom redirects
774
  $html .= ($element->ID) ? self::display_redirect_panel($id) : self::display_redirect_panel("tax-{$id}");
775
 
776
+ // 10. Extra save button for Gutenberg
777
+ if($gutenberg) {
778
+ $html .= sprintf(
779
+ "<div class=\"default-permalink-row save-row columns-container hidden\"><div><a href=\"#\" class=\"button button-primary\" id=\"permalink-manager-save-button\">%s</a></div></div>",
780
+ __("Save permalink", "permalink-manager")
781
+ );
782
+ }
783
+
784
  $html .= "</div>";
785
  $html .= "</div>";
786
 
787
+ // 11. Append nonce field, element ID & native slug
788
+ $html .= Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-edit-uri-element-slug", array("type" => "hidden", "value" => $native_slug));
789
  $html .= Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-edit-uri-element-id", array("type" => "hidden", "value" => $element_id));
790
  $html .= wp_nonce_field('permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false);
791
 
800
 
801
  // Heading
802
  $html = sprintf(
803
+ "<div class=\"permalink-manager redirects-row redirects-panel columns-container\"><div><a class=\"button\" href=\"#\" id=\"toggle-redirect-panel\">%s</a></span></div>",
804
+ __("Manage redirects", "permalink-manager")
 
805
  );
806
 
807
  $html .= "<div id=\"redirect-panel-inside\">";
819
  }
820
 
821
  /**
822
+ * Display error/info message
823
  */
824
+ public static function get_alert_message($alert_content = "", $alert_type = "", $dismissable = true, $id = false) {
825
+ // Ignore empty messages (just in case)
826
+ if(empty($alert_content) || empty($alert_type)) {
827
+ return "";
828
+ }
829
+
830
+ $class = ($dismissable) ? "is-dismissible" : "";
831
+ $alert_id = ($id) ? " data-alert_id=\"{$id}\"" : "";
832
+
833
+ $html = sprintf( "<div class=\"{$alert_type} permalink-manager-notice notice {$class}\"{$alert_id}> %s</div>", wpautop($alert_content) );
834
+
835
+ return $html;
836
+ }
837
+
838
+ /**
839
+ * Help tooltip
840
+ */
841
+ static function help_tooltip($text = '') {
842
+ $html = " <a href=\"#\" title=\"{$text}\" class=\"help_tooltip\"><span class=\"dashicons dashicons-editor-help\"></span></a>";
843
+ return $html;
844
  }
845
 
846
  /**
913
  // Convert the output to JSON and stop the function
914
  echo json_encode($duplicates_array);
915
  } else if(!empty($_REQUEST['custom_uri']) && !empty($_REQUEST['element_id'])) {
916
+ $is_duplicated = Permalink_Manager_Helper_Functions::is_uri_duplicated($uri, $element_id);
917
 
918
+ echo ($is_duplicated) ? $duplicate_alert : 0;;
919
  }
920
 
921
  die();
includes/core/permalink-manager-core-functions.php CHANGED
@@ -19,7 +19,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
19
 
20
  // Redirect from old URIs to new URIs + adjust canonical redirect settings
21
  add_action( 'template_redirect', array($this, 'new_uri_redirect_and_404'), 1);
22
- add_action( 'parse_query', array($this, 'adjust_canonical_redirect'), 0, 1);
23
 
24
  // Case insensitive permalinks
25
  if(!empty($permalink_manager_options['general']['case_insensitive_permalinks'])) {
@@ -34,7 +34,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
34
  // Trailing slashes
35
  add_filter( 'permalink_manager_filter_final_term_permalink', array($this, 'control_trailing_slashes'), 9);
36
  add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
37
- add_filter( 'permalink_manager_filter_post_sample_permalink', array($this, 'control_trailing_slashes'), 9);
38
 
39
  // Replace empty placeholder tags & remove BOM
40
  add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5 );
@@ -68,12 +68,17 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
68
  $deep_detect_enabled = apply_filters('permalink-manager-deep-uri-detect', $permalink_manager_options['general']['deep_detect']);
69
 
70
  // Keep only the URI
71
- $request_url = trim(str_replace($home_url, "", $request_url), "/");
 
 
 
 
 
 
 
72
 
73
  // Get all the endpoints & pattern
74
  $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
75
- //$pattern = "/^(.+?)(?|\/({$endpoints})\/?([^\/]*)|()\/([\d+]))?\/?$/i";
76
- //$pattern = "/^(.+?)(?|\/({$endpoints})[\/$]([^\/]*)|()\/([\d+]))?\/?$/i";
77
  $pattern = "/^(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i";
78
 
79
  // Use default REGEX to detect post
@@ -86,6 +91,19 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
86
  // Allow to filter the results by third-parties + store the URI parts with $pm_query global
87
  $uri_parts = $pm_query = apply_filters('permalink-manager-detect-uri', $uri_parts, $request_url, $endpoints);
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  // Stop the function if $uri_parts is empty
90
  if(empty($uri_parts)) return $query;
91
 
@@ -226,6 +244,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
226
  $query['post_type'] = $post_type;
227
  } else if($post_type == 'page') {
228
  $query['pagename'] = $final_uri;
 
229
  } else if($post_type == 'post') {
230
  $query['name'] = $final_uri;
231
  } else if($post_type == 'attachment') {
@@ -335,8 +354,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
335
  $debug_info['taxonomy'] = $term_taxonomy;
336
  }
337
 
338
- $debug_txt = json_encode($debug_info);
339
- $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
340
  wp_die($debug_txt);
341
  }
342
 
@@ -390,7 +408,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
390
  $post = get_queried_object();
391
 
392
  // 2. Check if post object is defined
393
- if(empty($post->post_type) || (empty($post->post_content) && $post->post_type != 'attachment')) { return; }
394
 
395
  // 3. Check if pagination is detected
396
  $current_page = (!empty($wp_query->query_vars['page'])) ? $wp_query->query_vars['page'] : 1;
@@ -420,7 +438,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
420
  global $wp_query, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_external_redirects, $permalink_manager_options, $wp, $pm_query, $pm_uri_parts;
421
 
422
  // Do not redirect on author pages & front page
423
- if(is_author() || is_front_page() || is_home()) { return false; }
424
 
425
  // Unset 404 if custom URI is detected
426
  if(isset($pm_query['id'])) {
@@ -488,6 +506,8 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
488
  }
489
  }
490
  }
 
 
491
  }
492
 
493
  // Ignore WP-Content links
@@ -497,6 +517,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
497
  * 1C. Enhance native redirect
498
  */
499
  if(empty($wp_query->query_vars['do_not_redirect']) && $redirect_mode && !empty($queried_object) && empty($correct_permalink)) {
 
500
  // Affect only posts with custom URI and old URIs
501
  if(!empty($queried_object->ID) && isset($permalink_manager_uris[$queried_object->ID]) && empty($wp_query->query['preview'])) {
502
  // Ignore posts with specific statuses
@@ -518,6 +539,8 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
518
  // Get the real URL
519
  $correct_permalink = get_term_link($queried_object->term_id, $queried_object->taxonomy);
520
  }
 
 
521
  }
522
 
523
  /**
@@ -549,6 +572,8 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
549
  $redirect_mode = $trailing_slashes_redirect_mode;
550
  }
551
  }
 
 
552
  }
553
 
554
  /**
@@ -560,14 +585,37 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
560
  }
561
 
562
  /**
563
- * 3. Ignore default URIs (or do nothing if redirects are disabled)
564
  */
565
- if(!empty($correct_permalink) && !empty($redirect_mode)) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
566
  // Allow redirect
567
  $wp_query->query_vars['do_not_redirect'] = 0;
568
 
569
  // Append query string
570
- $correct_permalink = (!empty($query_string)) ? "{$correct_permalink}?{$query_string}" : $correct_permalink;
571
 
572
  // Remove double slash
573
  $correct_permalink = preg_replace('~(?<!https:|http:)[/\\\\]+~', "/", trim($correct_permalink));
@@ -601,17 +649,17 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
601
  }
602
 
603
  // Do nothing for posts and terms without custom URIs (when canonical redirect is enabled)
604
- $element = get_queried_object();
605
- if(!empty($element->ID)) {
606
- $custom_uri = (!empty($permalink_manager_uris[$element->ID])) ? $permalink_manager_uris[$element->ID] : "";
607
- } else if(!empty($element->term_id)) {
608
- $custom_uri = (!empty($permalink_manager_uris["tax-{$element->term_id}"])) ? $permalink_manager_uris["tax-{$element->term_id}"] : "";
 
 
609
  }
610
 
611
- //if(empty($custom_uri) && !empty($permalink_manager_options['general']['canonical_redirect'])) { return; }
612
- if(!empty($permalink_manager_options['general']['canonical_redirect'])) { return; }
613
-
614
  if(!($permalink_manager_options['general']['canonical_redirect']) || !empty($wp->query_vars['do_not_redirect'])) {
 
615
  remove_action('template_redirect', 'redirect_canonical');
616
  add_filter('wpml_is_redirected', '__return_false', 99, 2);
617
  add_filter('pll_check_canonical_url', '__return_false', 99, 2);
19
 
20
  // Redirect from old URIs to new URIs + adjust canonical redirect settings
21
  add_action( 'template_redirect', array($this, 'new_uri_redirect_and_404'), 1);
22
+ add_action( 'wp', array($this, 'adjust_canonical_redirect'), 0, 1);
23
 
24
  // Case insensitive permalinks
25
  if(!empty($permalink_manager_options['general']['case_insensitive_permalinks'])) {
34
  // Trailing slashes
35
  add_filter( 'permalink_manager_filter_final_term_permalink', array($this, 'control_trailing_slashes'), 9);
36
  add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
37
+ add_filter( 'permalink_manager_filter_post_sample_uri', array($this, 'control_trailing_slashes'), 9);
38
 
39
  // Replace empty placeholder tags & remove BOM
40
  add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5 );
68
  $deep_detect_enabled = apply_filters('permalink-manager-deep-uri-detect', $permalink_manager_options['general']['deep_detect']);
69
 
70
  // Keep only the URI
71
+ $request_url = str_replace($home_url, "", $request_url);
72
+
73
+ // Hotfix for language plugins
74
+ if(filter_var($request_url, FILTER_VALIDATE_URL)) {
75
+ $request_url = parse_url($request_url, PHP_URL_PATH);
76
+ }
77
+
78
+ $request_url = trim($request_url, "/");
79
 
80
  // Get all the endpoints & pattern
81
  $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
 
 
82
  $pattern = "/^(.+?)(?|\/({$endpoints})(?|\/(.*)|$)|\/()([\d]+)\/?)?$/i";
83
 
84
  // Use default REGEX to detect post
91
  // Allow to filter the results by third-parties + store the URI parts with $pm_query global
92
  $uri_parts = $pm_query = apply_filters('permalink-manager-detect-uri', $uri_parts, $request_url, $endpoints);
93
 
94
+ // Support comment pages
95
+ preg_match("/(.*)\/{$wp_rewrite->comments_pagination_base}-([\d]+)/", $request_url, $regex_parts);
96
+ if(!empty($regex_parts[2])) {
97
+ $uri_parts['uri'] = $regex_parts[1];
98
+ $uri_parts['endpoint'] = 'cpage';
99
+ $uri_parts['endpoint_value'] = $regex_parts[2];
100
+ }
101
+
102
+ // Support pagination endpoint
103
+ if($uri_parts['endpoint'] == $wp_rewrite->pagination_base) {
104
+ $uri_parts['endpoint'] = 'page';
105
+ }
106
+
107
  // Stop the function if $uri_parts is empty
108
  if(empty($uri_parts)) return $query;
109
 
244
  $query['post_type'] = $post_type;
245
  } else if($post_type == 'page') {
246
  $query['pagename'] = $final_uri;
247
+ $query['post_type'] = $post_type;
248
  } else if($post_type == 'post') {
249
  $query['name'] = $final_uri;
250
  } else if($post_type == 'attachment') {
354
  $debug_info['taxonomy'] = $term_taxonomy;
355
  }
356
 
357
+ $debug_txt = sprintf("<pre style=\"display:block;\">%s</pre>", print_r($debug_info, true));
 
358
  wp_die($debug_txt);
359
  }
360
 
408
  $post = get_queried_object();
409
 
410
  // 2. Check if post object is defined
411
+ if(empty($post->post_type)) { return; }
412
 
413
  // 3. Check if pagination is detected
414
  $current_page = (!empty($wp_query->query_vars['page'])) ? $wp_query->query_vars['page'] : 1;
438
  global $wp_query, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_external_redirects, $permalink_manager_options, $wp, $pm_query, $pm_uri_parts;
439
 
440
  // Do not redirect on author pages & front page
441
+ if(is_author() || is_front_page() || is_home() || is_feed()) { return false; }
442
 
443
  // Unset 404 if custom URI is detected
444
  if(isset($pm_query['id'])) {
506
  }
507
  }
508
  }
509
+
510
+ $redirect_type = (!empty($correct_permalink)) ? 'custom_redirect' : '-';
511
  }
512
 
513
  // Ignore WP-Content links
517
  * 1C. Enhance native redirect
518
  */
519
  if(empty($wp_query->query_vars['do_not_redirect']) && $redirect_mode && !empty($queried_object) && empty($correct_permalink)) {
520
+
521
  // Affect only posts with custom URI and old URIs
522
  if(!empty($queried_object->ID) && isset($permalink_manager_uris[$queried_object->ID]) && empty($wp_query->query['preview'])) {
523
  // Ignore posts with specific statuses
539
  // Get the real URL
540
  $correct_permalink = get_term_link($queried_object->term_id, $queried_object->taxonomy);
541
  }
542
+
543
+ $redirect_type = (!empty($correct_permalink)) ? 'native_redirect' : '-';
544
  }
545
 
546
  /**
572
  $redirect_mode = $trailing_slashes_redirect_mode;
573
  }
574
  }
575
+
576
+ $redirect_type = (!empty($correct_permalink)) ? 'slash_redirect' : '-';
577
  }
578
 
579
  /**
585
  }
586
 
587
  /**
588
+ * 4. Prevent redirect loop
589
  */
590
+ if(!empty($correct_permalink) && !empty($wp->request) && !empty($redirect_type) && $redirect_type != 'slash_redirect') {
591
+ $current_uri = trim($wp->request, "/");
592
+ $redirect_uri = trim(parse_url($correct_permalink, PHP_URL_PATH), "/");
593
+
594
+ $correct_permalink = ($redirect_uri == $current_uri) ? null : $correct_permalink;
595
+ }
596
+
597
+ /**
598
+ * 5. Debug redirect
599
+ */
600
+ if(isset($_REQUEST['debug_redirect'])) {
601
+ $debug_info['query_vars'] = $wp_query->query_vars;
602
+ $debug_info['redirect_url'] = (!empty($correct_permalink)) ? $correct_permalink : '-';
603
+ $debug_info['redirect_mode'] = (!empty($redirect_mode)) ? $redirect_mode : "-";
604
+ $debug_info['queried_object'] = (!empty($queried_object)) ? $queried_object : "-";
605
+
606
+ $debug_txt = sprintf("<pre style=\"display:block;\">%s</pre>", print_r($debug_info, true));
607
+ wp_die($debug_txt);
608
+ }
609
+
610
+ /**
611
+ * 6. Ignore default URIs (or do nothing if redirects are disabled)
612
+ */
613
+ if(!empty($correct_permalink) && is_string($correct_permalink) && !empty($redirect_mode)) {
614
  // Allow redirect
615
  $wp_query->query_vars['do_not_redirect'] = 0;
616
 
617
  // Append query string
618
+ $correct_permalink = (!empty($query_string)) ? sprintf("%s?%s", strtok($correct_permalink, "?"), $query_string) : $correct_permalink;
619
 
620
  // Remove double slash
621
  $correct_permalink = preg_replace('~(?<!https:|http:)[/\\\\]+~', "/", trim($correct_permalink));
649
  }
650
 
651
  // Do nothing for posts and terms without custom URIs (when canonical redirect is enabled)
652
+ if(is_singular() || is_tax() || is_category() || is_tag()) {
653
+ $element = get_queried_object();
654
+ if(!empty($element->ID)) {
655
+ $custom_uri = (!empty($permalink_manager_uris[$element->ID])) ? $permalink_manager_uris[$element->ID] : "";
656
+ } else if(!empty($element->term_id)) {
657
+ $custom_uri = (!empty($permalink_manager_uris["tax-{$element->term_id}"])) ? $permalink_manager_uris["tax-{$element->term_id}"] : "";
658
+ }
659
  }
660
 
 
 
 
661
  if(!($permalink_manager_options['general']['canonical_redirect']) || !empty($wp->query_vars['do_not_redirect'])) {
662
+ remove_action('template_redirect', 'wp_old_slug_redirect');
663
  remove_action('template_redirect', 'redirect_canonical');
664
  add_filter('wpml_is_redirected', '__return_false', 99, 2);
665
  add_filter('pll_check_canonical_url', '__return_false', 99, 2);
includes/core/permalink-manager-gutenberg.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Additional hooks for "Permalink Manager Pro"
5
+ */
6
+ class Permalink_Manager_Gutenberg extends Permalink_Manager_Class {
7
+
8
+ public function __construct() {
9
+ add_action('enqueue_block_editor_assets', array($this, 'init'));
10
+ }
11
+
12
+ public function init() {
13
+ // add_action('enqueue_block_editor_assets', array($this, 'pm_gutenberg_scripts'));
14
+ add_meta_box('permalink-manager', __('Permalink Manager', 'permalink-manager'), array($this, 'meta_box'), '', 'side', 'high' );
15
+ }
16
+
17
+ public function pm_gutenberg_scripts() {
18
+ wp_enqueue_script( 'permalink-manager-gutenberg', PERMALINK_MANAGER_URL . '/out/permalink-manager-gutenberg.js', array( 'wp-blocks', 'wp-element', 'wp-components', 'wp-i18n', ), PERMALINK_MANAGER_VERSION, true );
19
+ }
20
+
21
+ public function meta_box($post) {
22
+ global $permalink_manager_uris;
23
+
24
+ if(empty($post->ID)) {
25
+ return '';
26
+ }
27
+
28
+ // Display URI Editor
29
+ echo Permalink_Manager_Admin_Functions::display_uri_box($post, true);
30
+ }
31
+
32
+ }
33
+
34
+ ?>
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -306,22 +306,6 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
306
  return apply_filters("permalink-manager-endpoints", str_replace("/", "\/", $endpoints));
307
  }
308
 
309
- /**
310
- * Remove post tag from permastructure
311
- */
312
- static function remove_post_tag($permastruct) {
313
- $post_types = self::get_post_types_array('full');
314
-
315
- // Get all post tags
316
- $post_tags = array("%postname%", "%pagename%");
317
- foreach($post_types as $post_type) {
318
- $post_tags[] = "%{$post_type['name']}%";
319
- }
320
-
321
- $permastruct = str_replace($post_tags, "", $permastruct);
322
- return trim($permastruct, "/");
323
- }
324
-
325
  /**
326
  * Structure Tags & Rewrite functions
327
  */
@@ -383,6 +367,32 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
383
  return apply_filters('permalink_manager-filter-permalink-base', trim(get_option('home'), "/"), $element);
384
  }
385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  /**
387
  * Sanitize multidimensional array
388
  */
@@ -417,7 +427,7 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
417
 
418
  // Foree lowercase & hyphens
419
  $force_lowercase = (!is_null($force_lowercase)) ? $force_lowercase : apply_filters('permalink-manager-force-lowercase-uris', true);
420
- if(!is_null($sanitize_slugs)) {
421
  $sanitize_slugs = ($permalink_manager_options['general']['force_custom_slugs'] == 2) ? false : true;
422
  }
423
 
@@ -433,9 +443,10 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
433
  $clean = ($force_lowercase) ? strtolower(trim($clean, '-')) : trim($clean, '-');
434
 
435
  // Remove special characters
436
- if($sanitize_slugs) {
437
  $clean = preg_replace("/[\s_|+-]+/", "-", $clean);
438
- $clean = preg_replace("/[\.]+/", "", $clean);
 
439
  } else {
440
  $clean = preg_replace("/[\s]+/", "-", $clean);
441
  }
@@ -447,13 +458,23 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
447
  * Clear the URI
448
  */
449
  public static function clear_single_uri($uri) {
450
- $uri = preg_replace('/\s+/', '', $uri);
451
- $uri = str_replace('//', '/', $uri);
 
452
  $uri = trim($uri, "/");
453
 
454
  return $uri;
455
  }
456
 
 
 
 
 
 
 
 
 
 
457
  /**
458
  * Force custom slugs
459
  */
@@ -462,6 +483,7 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
462
 
463
  if(!empty($permalink_manager_options['general']['force_custom_slugs'])) {
464
  $title = (!empty($object->name)) ? $object->name : $object->post_title;
 
465
 
466
  $old_slug = basename($slug);
467
  $new_slug = self::sanitize_title($title, false, null, true);
@@ -539,7 +561,26 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
539
  $all_uris = $permalink_manager_uris;
540
  unset($permalink_manager_uris[$element_id]);
541
 
542
- return (in_array($uri, $permalink_manager_uris)) ? 1 : 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
  }
544
 
545
  /**
306
  return apply_filters("permalink-manager-endpoints", str_replace("/", "\/", $endpoints));
307
  }
308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
  /**
310
  * Structure Tags & Rewrite functions
311
  */
367
  return apply_filters('permalink_manager-filter-permalink-base', trim(get_option('home'), "/"), $element);
368
  }
369
 
370
+ /**
371
+ * Remove post tag from permastructure
372
+ */
373
+ static function remove_post_tag($permastruct) {
374
+ $post_types = self::get_post_types_array('full');
375
+
376
+ // Get all post tags
377
+ $post_tags = array("%postname%", "%pagename%");
378
+ foreach($post_types as $post_type) {
379
+ $post_tags[] = "%{$post_type['name']}%";
380
+ }
381
+
382
+ $permastruct = str_replace($post_tags, "", $permastruct);
383
+ return trim($permastruct, "/");
384
+ }
385
+
386
+ /**
387
+ * Get front-page ID
388
+ */
389
+ static function is_front_page($page_id) {
390
+ $front_page_id = get_option('page_on_front');
391
+ $bool = (!empty($front_page_id) && $page_id == $front_page_id) ? true : false;
392
+
393
+ return apply_filters('permalink_manager_is_front_page', $bool, $page_id, $front_page_id);
394
+ }
395
+
396
  /**
397
  * Sanitize multidimensional array
398
  */
427
 
428
  // Foree lowercase & hyphens
429
  $force_lowercase = (!is_null($force_lowercase)) ? $force_lowercase : apply_filters('permalink-manager-force-lowercase-uris', true);
430
+ if(is_null($sanitize_slugs)) {
431
  $sanitize_slugs = ($permalink_manager_options['general']['force_custom_slugs'] == 2) ? false : true;
432
  }
433
 
443
  $clean = ($force_lowercase) ? strtolower(trim($clean, '-')) : trim($clean, '-');
444
 
445
  // Remove special characters
446
+ if($sanitize_slugs !== false) {
447
  $clean = preg_replace("/[\s_|+-]+/", "-", $clean);
448
+ $clean = preg_replace('/([\.]+)(?![a-z]{3,4}$)/i', '', $clean);
449
+ $clean = preg_replace('/([-\s+]\/[-\s+])/', '-', $clean);
450
  } else {
451
  $clean = preg_replace("/[\s]+/", "-", $clean);
452
  }
458
  * Clear the URI
459
  */
460
  public static function clear_single_uri($uri) {
461
+ $uri = preg_replace("/[\s_|+-]+/", "-", $uri);
462
+ $uri = preg_replace('/([-\s+]\/[-\s+])/', '-', $uri);
463
+ $uri = str_replace(array('-/', '/-', '//'), '/', $uri);
464
  $uri = trim($uri, "/");
465
 
466
  return $uri;
467
  }
468
 
469
+ /**
470
+ * Remove all slashes
471
+ */
472
+ public static function remove_slashes($uri) {
473
+ $uri = preg_replace("/[\/]+/", "", $uri);
474
+
475
+ return $uri;
476
+ }
477
+
478
  /**
479
  * Force custom slugs
480
  */
483
 
484
  if(!empty($permalink_manager_options['general']['force_custom_slugs'])) {
485
  $title = (!empty($object->name)) ? $object->name : $object->post_title;
486
+ $title = self::remove_slashes($title);
487
 
488
  $old_slug = basename($slug);
489
  $new_slug = self::sanitize_title($title, false, null, true);
561
  $all_uris = $permalink_manager_uris;
562
  unset($permalink_manager_uris[$element_id]);
563
 
564
+ if(in_array($uri, $permalink_manager_uris)) {
565
+ $all_duplicates = (array) array_keys($permalink_manager_uris, $uri);
566
+ $this_uri_lang = Permalink_Manager_Third_Parties::wpml_get_language_code($element_id);
567
+
568
+ if($this_uri_lang) {
569
+ foreach($all_duplicates as $key => $duplicated_id) {
570
+ $duplicated_uri_lang = Permalink_Manager_Third_Parties::wpml_get_language_code($duplicated_id);
571
+
572
+ if($duplicated_uri_lang !== $this_uri_lang) {
573
+ unset($all_duplicates[$key]);
574
+ }
575
+ }
576
+
577
+ return (count($all_duplicates) > 0) ? true : false;
578
+ } else {
579
+ return true;
580
+ }
581
+ } else {
582
+ return false;
583
+ }
584
  }
585
 
586
  /**
includes/core/permalink-manager-third-parties.php CHANGED
@@ -26,17 +26,17 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
26
  // URI Editor
27
  add_filter('permalink-manager-uri-editor-extra-info', array($this, 'wpml_lang_column_content_uri_editor'), 9, 3);
28
 
29
- if((isset($sitepress_settings['language_negotiation_type']) && in_array($sitepress_settings['language_negotiation_type'], array(1, 2))) || (isset($polylang->links_model->options['force_lang']) && in_array($polylang->links_model->options['force_lang'], array(1, 3)))) {
 
 
 
30
  add_filter('permalink-manager-detect-uri', array($this, 'wpml_detect_post'), 9, 3);
31
- add_filter('permalink_manager-filter-permalink-base', array($this, 'wpml_append_lang_prefix'), 9, 2);
32
  add_filter('template_redirect', array($this, 'wpml_redirect'), 0, 998 );
33
  } else if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 3) {
 
 
34
  add_filter('permalink-manager-detect-uri', array($this, 'wpml_ignore_lang_query_parameter'), 9);
35
-
36
- // Append query parameter
37
- add_filter('permalink_manager_filter_final_term_permalink', array($this, 'wpml_append_lang_query_parameter'), 9, 2);
38
- add_filter('permalink_manager_filter_final_post_permalink', array($this, 'wpml_append_lang_query_parameter'), 9, 2);
39
- add_filter('permalink_manager_filter_post_sample_permalink', array($this, 'wpml_append_lang_query_parameter'), 9, 2);
40
  }
41
 
42
  // Translate slugs
@@ -44,6 +44,9 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
44
  add_filter('permalink_manager_filter_post_type_slug', array($this, 'wpml_translate_post_type_slug'), 9, 3);
45
  // add_filter('permalink_manager_filter_taxonomy_slug', array($this, 'wpml_translate_taxonomy_slug'), 9, 3);
46
  }
 
 
 
47
  }
48
 
49
  // 2. AMP
@@ -53,10 +56,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
53
  add_filter('request', array($this, 'enable_amp'), 10, 1);
54
  }
55
 
56
- // 4. WP All Import
57
- add_action('pmxi_after_xml_import', array($this, 'pmxi_fix_permalinks'), 10);
58
-
59
- // 5. WooCommerce
60
  if(class_exists('WooCommerce')) {
61
  add_filter('request', array($this, 'woocommerce_detect'), 9, 1);
62
  add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
@@ -70,29 +70,31 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
70
  add_filter('request', 'Permalink_Manager_Pro_Functions::woocommerce_detect_coupon_code', 1, 1);
71
  add_filter('permalink-manager-disabled-post-types', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_uris', 9, 1);
72
  }
 
 
73
  }
74
 
75
- // 6. Theme My Login
76
  if(class_exists('Theme_My_Login')) {
77
  add_filter('permalink_manager_filter_final_post_permalink', array($this, 'tml_keep_query_parameters'), 9, 3);
78
  }
79
 
80
- // 7. Yoast SEO
81
  add_filter('wpseo_xml_sitemap_post_url', array($this, 'yoast_fix_sitemap_urls'));
82
 
83
- // 8. WooCommerce Wishlist Plugin
84
  if(function_exists('tinv_get_option')) {
85
  add_filter('permalink-manager-detect-uri', array($this, 'ti_woocommerce_wishlist_uris'), 15, 3);
86
  }
87
 
88
- // 9. Revisionize
89
  if(defined('REVISIONIZE_ROOT')) {
90
  add_action('revisionize_after_create_revision', array($this, 'revisionize_keep_post_uri'), 9, 2);
91
  add_action('revisionize_before_publish', array($this,'revisionize_clone_uri'), 9, 2);
92
  }
93
 
94
- // 10. WP All Import
95
- if(class_exists('PMXI_Plugin')) {
96
  add_action('pmxi_extend_options_featured', array($this, 'wpaiextra_uri_display'), 9, 2);
97
  add_filter('pmxi_options_options', array($this, 'wpai_api_options'));
98
  add_filter('pmxi_addons', array($this, 'wpai_api_register'));
@@ -115,6 +117,10 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
115
  if(!empty($query_vars['image_id']) && !empty($query_vars['gallery_id'])) {
116
  $wp_query->query_vars['do_not_redirect'] = 1;
117
  }
 
 
 
 
118
  }
119
  }
120
 
@@ -122,6 +128,13 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
122
  * 1. WPML filters
123
  */
124
  public static function wpml_get_language_code($element) {
 
 
 
 
 
 
 
125
  if(isset($element->post_type)) {
126
  $element_id = $element->ID;
127
  $element_type = $element->post_type;
@@ -129,7 +142,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
129
  $element_id = $element->term_taxonomy_id;
130
  $element_type = $element->taxonomy;
131
  } else {
132
- return false;
133
  }
134
 
135
  $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
@@ -152,6 +165,43 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
152
  return $def_lang;
153
  }
154
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
  function wpml_language_mismatch_fix($item_id, $uri_parts, $is_term = false) {
156
  global $wp, $language_code;
157
 
@@ -189,13 +239,13 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
189
 
190
  if(!empty($sitepress_settings['active_languages'])) {
191
  $languages_list = implode("|", $sitepress_settings['active_languages']);
192
- $default_language = $sitepress->get_default_language();
193
  } elseif(function_exists('pll_languages_list')) {
194
  $languages_array = pll_languages_list();
195
  $languages_list = (is_array($languages_array)) ? implode("|", $languages_array) : "";
196
- $default_language = pll_default_language();
197
  }
198
 
 
 
199
  // Fix for multidomain language configuration
200
  if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
201
  if(!empty($polylang->options['domains'])) {
@@ -205,7 +255,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
205
  }
206
 
207
  foreach($domains as &$domain) {
208
- $domain = preg_replace("/(http(s)?:\/\/(www\.)?)?(.+?)\/?$/", "http://$4", $domain);
209
  }
210
 
211
  $request_url = trim(str_replace($domains, "", $request_url), "/");
@@ -224,11 +274,15 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
224
  return $uri_parts;
225
  }
226
 
227
- function wpml_append_lang_prefix($base, $element) {
228
  global $sitepress_settings, $polylang, $permalink_manager_uris;
229
 
230
  $language_code = self::wpml_get_language_code($element);
231
  $default_language_code = self::get_default_language();
 
 
 
 
232
 
233
  // Last instance - use language paramater from &_GET array
234
  if(is_admin()) {
@@ -239,6 +293,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
239
  if(!empty($language_code)) {
240
  // A. Different domain per language
241
  if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
 
242
  if(!empty($polylang->options['domains'])) {
243
  $domains = $polylang->options['domains'];
244
  } else if(!empty($sitepress_settings['language_domains'])) {
@@ -257,17 +312,21 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
257
 
258
  // Append URL scheme
259
  if(!preg_match("~^(?:f|ht)tps?://~i", $base)) {
260
- $home_url = get_home_url();
261
  $scehme = parse_url($home_url, PHP_URL_SCHEME);
262
  $base = "{$scehme}://{$base}";
263
  }
264
  }
265
  }
266
- // B. Append prefix
 
 
 
 
 
 
 
 
267
  else {
268
- // Hide language code if "Use directory for default language" option is enabled
269
- $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'])) ? true : false;
270
-
271
  if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
272
  return $base;
273
  } else {
@@ -279,15 +338,23 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
279
  return $base;
280
  }
281
 
282
- function wpml_append_lang_query_parameter($permalink, $element) {
283
- $lang = self::wpml_get_language_code($element);
284
- $def_lang = self::get_default_language();
 
 
285
 
286
- if(!empty($lang) && ($def_lang != $lang)) {
287
- if(filter_var($permalink, FILTER_VALIDATE_URL)) {
288
- $permalink = add_query_arg('lang', $lang, $permalink);
 
 
 
 
 
 
289
  } else {
290
- $permalink .= "?lang={$lang}";
291
  }
292
  }
293
 
@@ -304,6 +371,21 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
304
  return $post_type_slug;
305
  }
306
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  function wpml_lang_column_uri_editor($columns) {
308
  if(class_exists('SitePress') || class_exists('Polylang')) {
309
  $columns['post_lang'] = __('Language', 'permalink-manager');
@@ -319,6 +401,13 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
319
  return $output;
320
  }
321
 
 
 
 
 
 
 
 
322
  function wpml_ignore_lang_query_parameter($uri_parts) {
323
  global $permalink_manager_uris;
324
 
@@ -365,7 +454,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
365
  }
366
 
367
  /**
368
- * 3. Custom Permalinks
369
  */
370
  public static function custom_permalinks_uris() {
371
  global $wpdb;
@@ -421,32 +510,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
421
  }
422
 
423
  /**
424
- * 4. WP All Import
425
- */
426
- function pmxi_fix_permalinks($import_id) {
427
- global $permalink_manager_uris, $wpdb;
428
-
429
- $post_ids = $wpdb->get_col($wpdb->prepare("SELECT post_id FROM {$wpdb->prefix}pmxi_posts WHERE import_id = %s", $import_id));
430
-
431
- // Just in case
432
- sleep(3);
433
-
434
- if(array($post_ids)) {
435
- foreach($post_ids as $id) {
436
- // Continue only if no custom URI is already assigned
437
- if(!empty($permalink_manager_uris[$id])) { continue; }
438
-
439
- // Get default post URI
440
- $new_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
441
- $permalink_manager_uris[$id] = $new_uri;
442
- }
443
- }
444
-
445
- update_option('permalink-manager-uris', $permalink_manager_uris);
446
- }
447
-
448
- /**
449
- * 5. WooCommerce
450
  */
451
  function woocommerce_detect($query) {
452
  global $woocommerce, $pm_query;
@@ -500,8 +564,21 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
500
  }
501
  }
502
 
 
 
 
 
 
 
 
 
 
 
 
 
 
503
  /**
504
- * 6. Theme My Login
505
  */
506
  function tml_keep_query_parameters($permalink, $post, $old_permalink) {
507
  // Get the query string from old permalink
@@ -511,7 +588,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
511
  }
512
 
513
  /**
514
- * 7. Fix Yoast's homepage URL
515
  */
516
  function yoast_fix_sitemap_urls($permalink) {
517
  if(class_exists('WPSEO_Utils')) {
@@ -525,7 +602,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
525
  }
526
 
527
  /**
528
- * 8. Support WooCommerce Wishlist Plugin
529
  */
530
  function ti_woocommerce_wishlist_uris($uri_parts, $request_url, $endpoints) {
531
  global $permalink_manager_uris, $wp;
@@ -550,7 +627,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
550
  }
551
 
552
  /**
553
- * 9. Revisionize
554
  */
555
  function revisionize_keep_post_uri($old_id, $new_id) {
556
  global $permalink_manager_uris;
@@ -576,7 +653,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
576
  }
577
 
578
  /**
579
- * 10. WP All Import
580
  */
581
  function wpaiextra_uri_display($post_type, $current_values) {
582
 
@@ -663,27 +740,25 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
663
  function wpai_api_import_function($importData, $parsedData) {
664
  global $permalink_manager_uris;
665
 
 
 
 
666
  // Get the parsed custom URI
667
  $index = (!empty($importData['i'])) ? $importData['i'] : false;
668
  $pid = (!empty($importData['pid'])) ? $importData['pid'] : false;
669
 
670
- if($pid && $index && !empty($parsedData['custom_uri'][$index])) {
671
- $custom_uri = $parsedData['custom_uri'][$index];
672
 
673
- // Store only URIs
674
- $custom_uri = parse_url($custom_uri, PHP_URL_PATH);
675
-
676
- // Sanitize the output
677
- $custom_uri = Permalink_Manager_Helper_Functions::sanitize_title($custom_uri);
678
-
679
- $permalink_manager_uris[$pid] = $custom_uri;
680
-
681
- update_option('permalink-manager-uris', $permalink_manager_uris);
682
  }
683
  }
684
 
685
  function wpai_save_redirects($pid) {
686
- global $permalink_manager_external_redirects;
687
 
688
  $external_url = get_post_meta($pid, '_external_redirect', true);
689
  $external_url = (empty($external_url)) ? get_post_meta($pid, 'external_redirect', true) : $external_url;
@@ -691,6 +766,16 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
691
  if($external_url && class_exists('Permalink_Manager_Pro_Functions')) {
692
  Permalink_Manager_Pro_Functions::save_external_redirect($external_url, $pid);
693
  }
 
 
 
 
 
 
 
 
 
 
694
  }
695
 
696
  }
26
  // URI Editor
27
  add_filter('permalink-manager-uri-editor-extra-info', array($this, 'wpml_lang_column_content_uri_editor'), 9, 3);
28
 
29
+ // Adjust front page ID
30
+ add_filter('permalink_manager_is_front_page', array($this, 'wpml_is_front_page'), 9, 3);
31
+
32
+ if((isset($sitepress_settings['language_negotiation_type']) && in_array($sitepress_settings['language_negotiation_type'], array(1, 2))) || (isset($polylang->links_model->options['force_lang']) && in_array($polylang->links_model->options['force_lang'], array(1, 2, 3)))) {
33
  add_filter('permalink-manager-detect-uri', array($this, 'wpml_detect_post'), 9, 3);
34
+ add_filter('permalink_manager-filter-permalink-base', array($this, 'wpml_prepend_lang_prefix'), 9, 2);
35
  add_filter('template_redirect', array($this, 'wpml_redirect'), 0, 998 );
36
  } else if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 3) {
37
+ add_filter('permalink_manager_filter_final_post_permalink', array($this, 'wpml_append_lang_prefix'), 5, 2);
38
+ add_filter('permalink_manager_filter_final_term_permalink', array($this, 'wpml_append_lang_prefix'), 5, 2);
39
  add_filter('permalink-manager-detect-uri', array($this, 'wpml_ignore_lang_query_parameter'), 9);
 
 
 
 
 
40
  }
41
 
42
  // Translate slugs
44
  add_filter('permalink_manager_filter_post_type_slug', array($this, 'wpml_translate_post_type_slug'), 9, 3);
45
  // add_filter('permalink_manager_filter_taxonomy_slug', array($this, 'wpml_translate_taxonomy_slug'), 9, 3);
46
  }
47
+
48
+ // Translate permastructure
49
+ add_filter('permalink_manager_filter_permastructure', array($this, 'wpml_translate_permastructure'), 9, 2);
50
  }
51
 
52
  // 2. AMP
56
  add_filter('request', array($this, 'enable_amp'), 10, 1);
57
  }
58
 
59
+ // 3. WooCommerce
 
 
 
60
  if(class_exists('WooCommerce')) {
61
  add_filter('request', array($this, 'woocommerce_detect'), 9, 1);
62
  add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
70
  add_filter('request', 'Permalink_Manager_Pro_Functions::woocommerce_detect_coupon_code', 1, 1);
71
  add_filter('permalink-manager-disabled-post-types', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_uris', 9, 1);
72
  }
73
+
74
+ add_action('woocommerce_product_import_inserted_product_object', array($this, 'woocommerce_generate_permalinks_after_import'), 9, 2);
75
  }
76
 
77
+ // 4. Theme My Login
78
  if(class_exists('Theme_My_Login')) {
79
  add_filter('permalink_manager_filter_final_post_permalink', array($this, 'tml_keep_query_parameters'), 9, 3);
80
  }
81
 
82
+ // 5. Yoast SEO
83
  add_filter('wpseo_xml_sitemap_post_url', array($this, 'yoast_fix_sitemap_urls'));
84
 
85
+ // 6. WooCommerce Wishlist Plugin
86
  if(function_exists('tinv_get_option')) {
87
  add_filter('permalink-manager-detect-uri', array($this, 'ti_woocommerce_wishlist_uris'), 15, 3);
88
  }
89
 
90
+ // 7. Revisionize
91
  if(defined('REVISIONIZE_ROOT')) {
92
  add_action('revisionize_after_create_revision', array($this, 'revisionize_keep_post_uri'), 9, 2);
93
  add_action('revisionize_before_publish', array($this,'revisionize_clone_uri'), 9, 2);
94
  }
95
 
96
+ // 8. WP All Import
97
+ if(class_exists('PMXI_Plugin') && (empty($permalink_manager_options['general']['pmxi_import_support']))) {
98
  add_action('pmxi_extend_options_featured', array($this, 'wpaiextra_uri_display'), 9, 2);
99
  add_filter('pmxi_options_options', array($this, 'wpai_api_options'));
100
  add_filter('pmxi_addons', array($this, 'wpai_api_register'));
117
  if(!empty($query_vars['image_id']) && !empty($query_vars['gallery_id'])) {
118
  $wp_query->query_vars['do_not_redirect'] = 1;
119
  }
120
+ // Ultimate member
121
+ else if(!empty($query_vars['um_user']) && !empty($query_vars['um_user'])) {
122
+ $wp_query->query_vars['do_not_redirect'] = 1;
123
+ }
124
  }
125
  }
126
 
128
  * 1. WPML filters
129
  */
130
  public static function wpml_get_language_code($element) {
131
+ // Fallback
132
+ if(is_string($element) && strpos($element, 'tax-') !== false) {
133
+ $element = get_term($element);
134
+ } else if(is_numeric($element)) {
135
+ $element = get_post($element);
136
+ }
137
+
138
  if(isset($element->post_type)) {
139
  $element_id = $element->ID;
140
  $element_type = $element->post_type;
142
  $element_id = $element->term_taxonomy_id;
143
  $element_type = $element->taxonomy;
144
  } else {
145
+ return false;
146
  }
147
 
148
  $lang_code = apply_filters('wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
165
  return $def_lang;
166
  }
167
 
168
+ public static function get_all_languages($exclude_default_language = false) {
169
+ global $sitepress, $sitepress_settings, $polylang;
170
+
171
+ $languages_array = $active_languages = array();
172
+ $default_language = self::get_default_language();
173
+
174
+ if(!empty($sitepress_settings['active_languages'])) {
175
+ $languages_array = $sitepress_settings['active_languages'];
176
+ } elseif(function_exists('pll_languages_list')) {
177
+ $languages_array = pll_languages_list(array('fields' => null));
178
+ }
179
+
180
+ // Get native language names as value
181
+ if($languages_array) {
182
+ foreach($languages_array as $val) {
183
+ if(!empty($sitepress)) {
184
+ $lang = $val;
185
+ $lang_details = $sitepress->get_language_details($lang);
186
+ $language_name = $lang_details['native_name'];
187
+ } else if(!empty($val->name)) {
188
+ $lang = $val->slug;
189
+ $language_name = $val->name;
190
+ }
191
+
192
+ $active_languages[$lang] = (!empty($language_name)) ? sprintf('%s <span>(%s)</span>', $language_name, $lang) : '-';
193
+ }
194
+
195
+ // Exclude default language if needed
196
+ if($exclude_default_language && $default_language && !empty($active_languages[$default_language])) {
197
+ unset($active_languages[$default_language]);
198
+ }
199
+ }
200
+
201
+
202
+ return (array) $active_languages;
203
+ }
204
+
205
  function wpml_language_mismatch_fix($item_id, $uri_parts, $is_term = false) {
206
  global $wp, $language_code;
207
 
239
 
240
  if(!empty($sitepress_settings['active_languages'])) {
241
  $languages_list = implode("|", $sitepress_settings['active_languages']);
 
242
  } elseif(function_exists('pll_languages_list')) {
243
  $languages_array = pll_languages_list();
244
  $languages_list = (is_array($languages_array)) ? implode("|", $languages_array) : "";
 
245
  }
246
 
247
+ $default_language = self::get_default_language();
248
+
249
  // Fix for multidomain language configuration
250
  if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
251
  if(!empty($polylang->options['domains'])) {
255
  }
256
 
257
  foreach($domains as &$domain) {
258
+ $domain = preg_replace('/((http(s)?:\/\/(www\.)?)|(www\.))?(.+?)\/?$/', 'http://$6', $domain);
259
  }
260
 
261
  $request_url = trim(str_replace($domains, "", $request_url), "/");
274
  return $uri_parts;
275
  }
276
 
277
+ function wpml_prepend_lang_prefix($base, $element) {
278
  global $sitepress_settings, $polylang, $permalink_manager_uris;
279
 
280
  $language_code = self::wpml_get_language_code($element);
281
  $default_language_code = self::get_default_language();
282
+ $home_url = get_home_url();
283
+
284
+ // Hide language code if "Use directory for default language" option is enabled
285
+ $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'])) ? true : false;
286
 
287
  // Last instance - use language paramater from &_GET array
288
  if(is_admin()) {
293
  if(!empty($language_code)) {
294
  // A. Different domain per language
295
  if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 2) || (!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 3)) {
296
+
297
  if(!empty($polylang->options['domains'])) {
298
  $domains = $polylang->options['domains'];
299
  } else if(!empty($sitepress_settings['language_domains'])) {
312
 
313
  // Append URL scheme
314
  if(!preg_match("~^(?:f|ht)tps?://~i", $base)) {
 
315
  $scehme = parse_url($home_url, PHP_URL_SCHEME);
316
  $base = "{$scehme}://{$base}";
317
  }
318
  }
319
  }
320
+ // B. Prepend language code
321
+ else if(!empty($polylang->options['force_lang']) && $polylang->options['force_lang'] == 2) {
322
+ if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
323
+ return $base;
324
+ } else {
325
+ $base = preg_replace('/(https?:\/\/)/', "$1{$language_code}.", $home_url);
326
+ }
327
+ }
328
+ // C. Append prefix
329
  else {
 
 
 
330
  if($hide_prefix_for_default_lang && ($default_language_code == $language_code)) {
331
  return $base;
332
  } else {
338
  return $base;
339
  }
340
 
341
+ function wpml_append_lang_prefix($permalink, $element) {
342
+ global $sitepress_settings, $polylang, $permalink_manager_uris;
343
+
344
+ $language_code = self::wpml_get_language_code($element);
345
+ $default_language_code = self::get_default_language();
346
 
347
+ // Last instance - use language paramater from &_GET array
348
+ if(is_admin()) {
349
+ $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
350
+ }
351
+
352
+ // B. Append ?lang query parameter
353
+ if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 3) {
354
+ if($default_language_code == $language_code) {
355
+ return $permalink;
356
  } else {
357
+ $permalink .= "?lang={$language_code}";
358
  }
359
  }
360
 
371
  return $post_type_slug;
372
  }
373
 
374
+ function wpml_translate_permastructure($permastructure, $element) {
375
+ global $permalink_manager_permastructs;
376
+
377
+ // Get element language code
378
+ $language_code = self::wpml_get_language_code($element);
379
+
380
+ if(!empty($element->ID)) {
381
+ $translated_permastructure = (!empty($permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"])) ? $permalink_manager_permastructs["post_types"]["{$element->post_type}_{$language_code}"] : '';
382
+ } else if(!empty($element->term_id)) {
383
+ $translated_permastructure = (!empty($permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"])) ? $permalink_manager_permastructs["taxonomies"]["{$element->taxonomy}_{$language_code}"] : '';
384
+ }
385
+
386
+ return (!empty($translated_permastructure)) ? $translated_permastructure : $permastructure;
387
+ }
388
+
389
  function wpml_lang_column_uri_editor($columns) {
390
  if(class_exists('SitePress') || class_exists('Polylang')) {
391
  $columns['post_lang'] = __('Language', 'permalink-manager');
401
  return $output;
402
  }
403
 
404
+ function wpml_is_front_page($bool, $page_id, $front_page_id) {
405
+ $default_language_code = self::get_default_language();
406
+ $page_id = apply_filters('wpml_object_id', $page_id, 'page', true, $default_language_code);
407
+
408
+ return (!empty($page_id) && $page_id == $front_page_id) ? true : $bool;
409
+ }
410
+
411
  function wpml_ignore_lang_query_parameter($uri_parts) {
412
  global $permalink_manager_uris;
413
 
454
  }
455
 
456
  /**
457
+ * Parse Custom Permalinks
458
  */
459
  public static function custom_permalinks_uris() {
460
  global $wpdb;
510
  }
511
 
512
  /**
513
+ * 3. WooCommerce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  */
515
  function woocommerce_detect($query) {
516
  global $woocommerce, $pm_query;
564
  }
565
  }
566
 
567
+ function woocommerce_generate_permalinks_after_import($object, $data) {
568
+ global $permalink_manager_uris;
569
+
570
+ if(!empty($object)) {
571
+ $product_id = $object->get_id();
572
+ $product_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($product_id, false, true);
573
+
574
+ $permalink_manager_uris[$product_id] = $product_uri;
575
+
576
+ update_option('permalink-manager-uris', $permalink_manager_uris);
577
+ }
578
+ }
579
+
580
  /**
581
+ * 4. Theme My Login
582
  */
583
  function tml_keep_query_parameters($permalink, $post, $old_permalink) {
584
  // Get the query string from old permalink
588
  }
589
 
590
  /**
591
+ * 5. Fix Yoast's homepage URL
592
  */
593
  function yoast_fix_sitemap_urls($permalink) {
594
  if(class_exists('WPSEO_Utils')) {
602
  }
603
 
604
  /**
605
+ * 6. Support WooCommerce Wishlist Plugin
606
  */
607
  function ti_woocommerce_wishlist_uris($uri_parts, $request_url, $endpoints) {
608
  global $permalink_manager_uris, $wp;
627
  }
628
 
629
  /**
630
+ * 7. Revisionize
631
  */
632
  function revisionize_keep_post_uri($old_id, $new_id) {
633
  global $permalink_manager_uris;
653
  }
654
 
655
  /**
656
+ * 8. WP All Import
657
  */
658
  function wpaiextra_uri_display($post_type, $current_values) {
659
 
740
  function wpai_api_import_function($importData, $parsedData) {
741
  global $permalink_manager_uris;
742
 
743
+ // Check if post type is disabled
744
+ if(empty($parsedData) || Permalink_Manager_Helper_Functions::is_disabled($importData['post_type'], 'post_type')) { return; }
745
+
746
  // Get the parsed custom URI
747
  $index = (!empty($importData['i'])) ? $importData['i'] : false;
748
  $pid = (!empty($importData['pid'])) ? $importData['pid'] : false;
749
 
750
+ if($index && $pid && !empty($parsedData['custom_uri'][$index])) {
751
+ $custom_uri = Permalink_Manager_Helper_Functions::sanitize_title($parsedData['custom_uri'][$index]);
752
 
753
+ if(!empty($custom_uri)) {
754
+ $permalink_manager_uris[$pid] = $custom_uri;
755
+ update_option('permalink-manager-uris', $permalink_manager_uris);
756
+ }
 
 
 
 
 
757
  }
758
  }
759
 
760
  function wpai_save_redirects($pid) {
761
+ global $permalink_manager_external_redirects, $permalink_manager_uris;
762
 
763
  $external_url = get_post_meta($pid, '_external_redirect', true);
764
  $external_url = (empty($external_url)) ? get_post_meta($pid, 'external_redirect', true) : $external_url;
766
  if($external_url && class_exists('Permalink_Manager_Pro_Functions')) {
767
  Permalink_Manager_Pro_Functions::save_external_redirect($external_url, $pid);
768
  }
769
+
770
+ // Save custom URI only if the post type is not disabled (third parameter in get_default_post_uri() function)
771
+ if(empty($permalink_manager_uris[$pid])) {
772
+ $custom_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($pid, false, true);
773
+
774
+ if(!empty($custom_uri)) {
775
+ $permalink_manager_uris[$pid] = $custom_uri;
776
+ update_option('permalink-manager-uris', $permalink_manager_uris);
777
+ }
778
+ }
779
  }
780
 
781
  }
includes/core/permalink-manager-uri-functions-post.php CHANGED
@@ -60,7 +60,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
60
  if(!empty($post->post_type) && Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $permalink; }
61
 
62
  // 2A. Do not change permalink of frontpage
63
- if(get_option('page_on_front') == $post->ID) {
64
  return $permalink;
65
  }
66
  // 2B. Do not change permalink for drafts and future posts (+ remove trailing slash from them)
@@ -85,10 +85,12 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
85
  $permalink = "{$home_url}/" . urldecode("/{$permalink}");
86
  }
87
 
88
- // 6. Additional filter
89
- $permalink = apply_filters('permalink_manager_filter_final_post_permalink', user_trailingslashit($permalink), $post, $old_permalink);
90
-
91
- return $permalink;
 
 
92
  }
93
 
94
  /**
@@ -110,12 +112,19 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
110
  /**
111
  * Get the active URI
112
  */
113
- public static function get_post_uri($post_id, $native_uri = false) {
114
  global $permalink_manager_uris;
115
 
116
  // Check if input is post object
117
  $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
118
- $final_uri = (!empty($permalink_manager_uris[$post_id])) ? $permalink_manager_uris[$post_id] : self::get_default_post_uri($post_id, $native_uri);
 
 
 
 
 
 
 
119
 
120
  return $final_uri;
121
  }
@@ -123,22 +132,25 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
123
  /**
124
  * Get the default (not overwritten by the user) or native URI (unfiltered)
125
  */
126
- public static function get_default_post_uri($post, $native_uri = false) {
127
  global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $wp_post_types;
128
 
129
  // Load all bases & post
130
  $post = is_object($post) ? $post : get_post($post);
131
 
132
  // Check if post ID is defined (and front page permalinks should be empty)
133
- if(empty($post->ID) || (get_option('page_on_front') == $post->ID)) { return ''; }
 
134
  $post_id = $post->ID;
135
  $post_type = $post->post_type;
136
  $post_name = (empty($post->post_name)) ? Permalink_Manager_Helper_Functions::sanitize_title($post->post_title) : $post->post_name;
137
 
138
- // 1. Get the permastruct
 
 
 
139
  if($post_type == 'attachment') {
140
  $parent_page = ($post->post_parent > 0 && $post->post_parent != $post->ID) ? get_post($post->post_parent) : false;
141
- // $default_permastruct = ($parent_page) ? trim(get_page_uri($parent_page->ID), "/") . "/attachment" : "";
142
 
143
  if(!empty($parent_page->ID)) {
144
  $parent_page_uri = (!empty($permalink_manager_uris[$parent_page->ID])) ? $permalink_manager_uris[$parent_page->ID] : get_page_uri($parent_page->ID);
@@ -146,22 +158,20 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
146
  $parent_page_uri = "";
147
  }
148
 
149
- $default_permastruct = ($parent_page) ? trim($parent_page_uri, "/") . "/attachment" : "";
 
 
 
150
 
151
- if($native_uri) {
152
- $permastruct = $default_permastruct;
153
- } else {
154
- $permastruct = (!empty($permalink_manager_permastructs['post_types'][$post_type])) ? $permalink_manager_permastructs['post_types'][$post_type] : $default_permastruct;
155
- }
156
  } else {
157
- $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
158
- if($native_uri) {
159
- $permastruct = $default_permastruct;
160
- } else {
161
- $permastruct = (isset($permalink_manager_permastructs['post_types'][$post_type])) ? $permalink_manager_permastructs['post_types'][$post_type] : $default_permastruct;
162
- }
163
  }
164
- $default_base = (!empty($permastruct)) ? trim($permastruct, '/') : "";
 
 
165
 
166
  // 2A. Get the date
167
  $date = explode(" ", date('Y m d H i s', strtotime($post->post_date)));
@@ -174,18 +184,21 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
174
  }
175
 
176
  // 2C. Get the post type slug
177
- if(!empty($wp_post_types[$post_type]->rewrite['slug'])) {
178
- $post_type_slug = $wp_post_types[$post_type]->rewrite['slug'];
179
- } else if(is_string($wp_post_types[$post_type]->rewrite)) {
180
- $post_type_slug = $wp_post_types[$post_type]->rewrite;
181
- } else {
182
- $post_type_slug = $post_type;
183
  }
 
 
184
  $post_type_slug = apply_filters('permalink_manager_filter_post_type_slug', $post_type_slug, $post, $post_type);
 
185
 
186
  // 3B. Get the full slug
187
- $custom_slug = Permalink_Manager_Helper_Functions::force_custom_slugs($post_name, $post);
188
- $full_custom_slug = Permalink_Manager_Helper_Functions::force_custom_slugs($post_name, $post);
189
  $full_native_slug = $post_name;
190
 
191
  // 3A. Fix for hierarchical CPT (start)
@@ -262,14 +275,19 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
262
  else if(!empty($replacement_term->term_id) && strpos($default_uri, "%{$taxonomy}_flat%") === false && is_taxonomy_hierarchical($taxonomy)) {
263
  $mode = 2;
264
  }
265
- // 4C. Force flat term base - get highgest level term (if %taxonomy_flat% tag is used)
266
  else if(!$native_uri && strpos($default_uri, "%{$taxonomy}_flat%") !== false && !empty($terms) && empty($primary_term->slug)) {
267
  $mode = 3;
268
  }
269
- // 4D. Flat/non-hierarchical term base - get primary term (if set) or first term
270
- else {
271
  $mode = 4;
272
  }
 
 
 
 
 
273
 
274
  // Get the replacement slug (custom + native)
275
  $replacement = Permalink_Manager_Helper_Functions::get_term_full_slug($replacement_term, $terms, $mode, $native_uri);
@@ -283,9 +301,6 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
283
  }
284
  }
285
 
286
- // 5. Clear the URI
287
- $default_uri = Permalink_Manager_Helper_Functions::clear_single_uri($default_uri);
288
-
289
  return apply_filters('permalink_manager_filter_default_post_uri', $default_uri, $post->post_name, $post, $post_name, $native_uri);
290
  }
291
 
@@ -295,7 +310,10 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
295
  function exclude_homepage($uris) {
296
  // Find the homepage URI
297
  $homepage_id = get_option('page_on_front');
298
- if(is_array($uris) && !empty($uris[$homepage_id])) { unset($uris[$homepage_id]); }
 
 
 
299
 
300
  return $uris;
301
  }
@@ -381,8 +399,9 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
381
  // Get default & native URL
382
  $native_uri = self::get_default_post_uri($row['ID'], true);
383
  $default_uri = self::get_default_post_uri($row['ID']);
 
384
  $old_post_name = $row['post_name'];
385
- $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $default_uri;
386
 
387
  // Do replacement on slugs (non-REGEX)
388
  if(preg_match("/^\/.+\/[a-z]*$/i", $old_string)) {
@@ -397,7 +416,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
397
  $new_uri = ($mode != 'slugs') ? str_replace($old_string, $new_string, $old_uri) : $old_uri;
398
  }
399
 
400
- //print_r("{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n");
401
 
402
  // Check if native slug should be changed
403
  if(($mode == 'slugs') && ($old_post_name != $new_post_name)) {
@@ -448,7 +467,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
448
  $native_uri = self::get_default_post_uri($row['ID'], true);
449
  $default_uri = self::get_default_post_uri($row['ID']);
450
  $old_post_name = $row['post_name'];
451
- $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : $native_uri;
452
  $correct_slug = ($mode == 'slugs') ? sanitize_title($row['post_title']) : Permalink_Manager_Helper_Functions::sanitize_title($row['post_title']);
453
 
454
  // Process URI & slug
@@ -457,7 +476,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
457
 
458
  // Prepare the new URI
459
  if($mode == 'slugs') {
460
- $new_uri = $old_uri;
461
  } else if($mode == 'native') {
462
  $new_uri = $native_uri;
463
  } else {
@@ -566,42 +585,46 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
566
  $show_uri_editor = apply_filters("permalink_manager_hide_uri_editor_post_{$post->post_type}", true);
567
  if(!$show_uri_editor) { return $html; }
568
 
569
- $html = preg_replace("/(<strong>(.*)<\/strong>)(.*)/is", "$1 ", $html);
570
  $default_uri = self::get_default_post_uri($id);
571
  $native_uri = self::get_default_post_uri($id, true);
572
 
573
  // Make sure that home URL ends with slash
574
  $home_url = Permalink_Manager_Helper_Functions::get_permalink_base($post);
575
 
576
- // Do not change anything if post is not saved yet (display sample permalink instead)
577
- if(get_option('page_on_front') == $id) {
578
- $uri = $sample_permalink_uri = "";
579
- }
580
- else if($autosave || empty($post->post_status)) {
581
- $uri = $sample_permalink_uri = $default_uri;
582
- } else {
583
- $uri = $sample_permalink_uri = (!empty($permalink_manager_uris[$id])) ? $permalink_manager_uris[$id] : $native_uri;
584
  }
 
 
 
 
 
 
 
 
 
585
 
586
- // Decode URI & allow to filter it
587
- $sample_permalink_uri = apply_filters('permalink_manager_filter_post_sample_uri', urldecode($sample_permalink_uri), $post);
588
 
589
- // Prepare the sample & default permalink
590
- $sample_permalink = sprintf("{$home_url}/<span class=\"editable\">%s</span>", str_replace("//", "/", $sample_permalink_uri));
591
 
592
- // Allow to filter the sample permalink URL
593
- $sample_permalink = apply_filters('permalink_manager_filter_post_sample_permalink', $sample_permalink, $post);
 
594
 
595
  // Append new HTML output
596
- $html .= sprintf("<span class=\"sample-permalink-span\"><a id=\"sample-permalink\" href=\"%s\">%s</a></span>&nbsp;", strip_tags($sample_permalink), $sample_permalink);
597
- $html .= (!$autosave) ? Permalink_Manager_Admin_Functions::display_uri_box($post, $default_uri, $uri, $native_uri) : "";
598
 
599
  // Append hidden field with native slug
600
- // $html .= (!empty($post->post_name)) ? "<input id=\"new-post-slug\" value=\"{$post->post_name}\" autocomplete=\"off\" type=\"hidden\">" : "";
601
- $html .= (!empty($post->post_name)) ? "<span id=\"editable-post-name-full\">{$post->post_name}</span>" : "";
602
- // $html .= (!empty($post->post_name)) ? "<span id=\"editable-post-name-full\">{$uri}</span>" : "";
603
 
604
- return $html;
605
  }
606
 
607
  /**
@@ -639,12 +662,15 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
639
  function new_post_uri($post_id) {
640
  global $post, $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
641
 
642
- // Do not trigger if post is a revision
643
- if(wp_is_post_revision($post_id)) { return $post_id; }
644
 
645
  // Prevent language mismatch in MultilingualPress plugin
646
  if(is_admin() && !empty($post->ID) && $post->ID != $post_id) { return $post_id; }
647
 
 
 
 
648
  // Do not do anything if post is autosaved
649
  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
650
 
@@ -681,7 +707,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
681
  /**
682
  * Update URI from "Edit Post" admin page
683
  */
684
- function update_post_uri($post_id) {
685
  global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
686
 
687
  // Verify nonce at first
@@ -690,8 +716,8 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
690
  // Do not do anything if post is autosaved
691
  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
692
 
693
- // Do not do anything on in "Bulk Edit"
694
- if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
695
 
696
  // Do not do anything if the field with URI or element ID are not present
697
  if(!isset($_POST['custom_uri']) || empty($_POST['permalink-manager-edit-uri-element-id'])) { return $post_id; }
@@ -739,13 +765,11 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
739
  }
740
 
741
  // Save only changed URIs
742
- //if($new_uri != $old_uri) {
743
- $permalink_manager_uris[$post_id] = $new_uri;
744
- update_option('permalink-manager-uris', $permalink_manager_uris);
745
- //}
746
 
747
  // Update the slug (if changed)
748
- if(!empty($_POST['post_name']) && isset($_POST['native_slug']) && ($_POST['native_slug'] !== $_POST['post_name'])) {
749
  self::update_slug_by_id($_POST['native_slug'], $post_id);
750
  }
751
 
60
  if(!empty($post->post_type) && Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $permalink; }
61
 
62
  // 2A. Do not change permalink of frontpage
63
+ if(Permalink_Manager_Helper_Functions::is_front_page($post->ID)) {
64
  return $permalink;
65
  }
66
  // 2B. Do not change permalink for drafts and future posts (+ remove trailing slash from them)
85
  $permalink = "{$home_url}/" . urldecode("/{$permalink}");
86
  }
87
 
88
+ // 5. Allow to filter (do not filter in Customizer)
89
+ if(!(function_exists('is_customize_preview') && is_customize_preview())) {
90
+ return apply_filters('permalink_manager_filter_final_post_permalink', user_trailingslashit($permalink), $post, $old_permalink);
91
+ } else {
92
+ return $old_permalink;
93
+ }
94
  }
95
 
96
  /**
112
  /**
113
  * Get the active URI
114
  */
115
+ public static function get_post_uri($post_id, $native_uri = false, $is_draft = false) {
116
  global $permalink_manager_uris;
117
 
118
  // Check if input is post object
119
  $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
120
+
121
+ if(!empty($permalink_manager_uris[$post_id])) {
122
+ $final_uri = $permalink_manager_uris[$post_id];
123
+ } else if(!$is_draft) {
124
+ $final_uri = self::get_default_post_uri($post_id, $native_uri);
125
+ } else {
126
+ $final_uri = '';
127
+ }
128
 
129
  return $final_uri;
130
  }
132
  /**
133
  * Get the default (not overwritten by the user) or native URI (unfiltered)
134
  */
135
+ public static function get_default_post_uri($post, $native_uri = false, $check_if_disabled = false) {
136
  global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $wp_post_types;
137
 
138
  // Load all bases & post
139
  $post = is_object($post) ? $post : get_post($post);
140
 
141
  // Check if post ID is defined (and front page permalinks should be empty)
142
+ if(empty($post->ID) || Permalink_Manager_Helper_Functions::is_front_page($post->ID)) { return ''; }
143
+
144
  $post_id = $post->ID;
145
  $post_type = $post->post_type;
146
  $post_name = (empty($post->post_name)) ? Permalink_Manager_Helper_Functions::sanitize_title($post->post_title) : $post->post_name;
147
 
148
+ // 1A. Check if post type is allowed
149
+ if($check_if_disabled && Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) { return ''; }
150
+
151
+ // 1A. Get the native permastructure
152
  if($post_type == 'attachment') {
153
  $parent_page = ($post->post_parent > 0 && $post->post_parent != $post->ID) ? get_post($post->post_parent) : false;
 
154
 
155
  if(!empty($parent_page->ID)) {
156
  $parent_page_uri = (!empty($permalink_manager_uris[$parent_page->ID])) ? $permalink_manager_uris[$parent_page->ID] : get_page_uri($parent_page->ID);
158
  $parent_page_uri = "";
159
  }
160
 
161
+ $native_permastructure = ($parent_page) ? trim($parent_page_uri, "/") . "/attachment" : "";
162
+ } else {
163
+ $native_permastructure = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
164
+ }
165
 
166
+ // 1B. Get the permastructure
167
+ if($native_uri || empty($permalink_manager_permastructs['post_types'][$post_type])) {
168
+ $permastructure = $native_permastructure;
 
 
169
  } else {
170
+ $permastructure = apply_filters('permalink_manager_filter_permastructure', $permalink_manager_permastructs['post_types'][$post_type], $post);
 
 
 
 
 
171
  }
172
+
173
+ // 1C. Set the permastructure
174
+ $default_base = (!empty($permastructure)) ? trim($permastructure, '/') : "";
175
 
176
  // 2A. Get the date
177
  $date = explode(" ", date('Y m d H i s', strtotime($post->post_date)));
184
  }
185
 
186
  // 2C. Get the post type slug
187
+ if(!empty($wp_post_types[$post_type])) {
188
+ if(!empty($wp_post_types[$post_type]->rewrite['slug'])) {
189
+ $post_type_slug = $wp_post_types[$post_type]->rewrite['slug'];
190
+ } else if(is_string($wp_post_types[$post_type]->rewrite)) {
191
+ $post_type_slug = $wp_post_types[$post_type]->rewrite;
192
+ }
193
  }
194
+
195
+ $post_type_slug = (!empty($post_type_slug)) ? $post_type_slug : $post_type;
196
  $post_type_slug = apply_filters('permalink_manager_filter_post_type_slug', $post_type_slug, $post, $post_type);
197
+ $post_type_slug = preg_replace('/(%([^%]+)%\/?)/', '', $post_type_slug);
198
 
199
  // 3B. Get the full slug
200
+ $post_name = Permalink_Manager_Helper_Functions::remove_slashes($post_name);
201
+ $custom_slug = $full_custom_slug = Permalink_Manager_Helper_Functions::force_custom_slugs($post_name, $post);
202
  $full_native_slug = $post_name;
203
 
204
  // 3A. Fix for hierarchical CPT (start)
275
  else if(!empty($replacement_term->term_id) && strpos($default_uri, "%{$taxonomy}_flat%") === false && is_taxonomy_hierarchical($taxonomy)) {
276
  $mode = 2;
277
  }
278
+ // 4C. Force flat/non-hierarchical term base - get highgest level term (if %taxonomy_flat% tag is used and primary term is not set)
279
  else if(!$native_uri && strpos($default_uri, "%{$taxonomy}_flat%") !== false && !empty($terms) && empty($primary_term->slug)) {
280
  $mode = 3;
281
  }
282
+ // 4D. Flat/non-hierarchical term base - get first term (if primary term not set)
283
+ else if(empty($primary_term->slug)) {
284
  $mode = 4;
285
  }
286
+ // 4E. Flat/non-hierarchical term base - get and force primary term (if set)
287
+ else {
288
+ $mode = 5;
289
+ $replacement_term = $primary_term;
290
+ }
291
 
292
  // Get the replacement slug (custom + native)
293
  $replacement = Permalink_Manager_Helper_Functions::get_term_full_slug($replacement_term, $terms, $mode, $native_uri);
301
  }
302
  }
303
 
 
 
 
304
  return apply_filters('permalink_manager_filter_default_post_uri', $default_uri, $post->post_name, $post, $post_name, $native_uri);
305
  }
306
 
310
  function exclude_homepage($uris) {
311
  // Find the homepage URI
312
  $homepage_id = get_option('page_on_front');
313
+
314
+ if(is_array($uris) && !empty($uris[$homepage_id])) {
315
+ unset($uris[$homepage_id]);
316
+ }
317
 
318
  return $uris;
319
  }
399
  // Get default & native URL
400
  $native_uri = self::get_default_post_uri($row['ID'], true);
401
  $default_uri = self::get_default_post_uri($row['ID']);
402
+
403
  $old_post_name = $row['post_name'];
404
+ $old_uri = (isset($permalink_manager_uris[$row['ID']])) ? $permalink_manager_uris[$row['ID']] : $native_uri;
405
 
406
  // Do replacement on slugs (non-REGEX)
407
  if(preg_match("/^\/.+\/[a-z]*$/i", $old_string)) {
416
  $new_uri = ($mode != 'slugs') ? str_replace($old_string, $new_string, $old_uri) : $old_uri;
417
  }
418
 
419
+ // echo "{$old_uri} - {$new_uri} - {$native_uri} - {$default_uri} \n";
420
 
421
  // Check if native slug should be changed
422
  if(($mode == 'slugs') && ($old_post_name != $new_post_name)) {
467
  $native_uri = self::get_default_post_uri($row['ID'], true);
468
  $default_uri = self::get_default_post_uri($row['ID']);
469
  $old_post_name = $row['post_name'];
470
+ $old_uri = isset($permalink_manager_uris[$row['ID']]) ? trim($permalink_manager_uris[$row['ID']], "/") : '';
471
  $correct_slug = ($mode == 'slugs') ? sanitize_title($row['post_title']) : Permalink_Manager_Helper_Functions::sanitize_title($row['post_title']);
472
 
473
  // Process URI & slug
476
 
477
  // Prepare the new URI
478
  if($mode == 'slugs') {
479
+ $new_uri = ($old_uri) ? $old_uri : $native_uri;
480
  } else if($mode == 'native') {
481
  $new_uri = $native_uri;
482
  } else {
585
  $show_uri_editor = apply_filters("permalink_manager_hide_uri_editor_post_{$post->post_type}", true);
586
  if(!$show_uri_editor) { return $html; }
587
 
588
+ $new_html = preg_replace("/(<strong>(.*)<\/strong>)(.*)/is", "$1 ", $html);
589
  $default_uri = self::get_default_post_uri($id);
590
  $native_uri = self::get_default_post_uri($id, true);
591
 
592
  // Make sure that home URL ends with slash
593
  $home_url = Permalink_Manager_Helper_Functions::get_permalink_base($post);
594
 
595
+ // A. Display original permalink on front-page editor
596
+ if(Permalink_Manager_Helper_Functions::is_front_page($id)) {
597
+ preg_match('/href="([^"]+)"/mi', $html, $matches);
598
+ $sample_permalink = (!empty($matches[1])) ? $matches[1] : "";
 
 
 
 
599
  }
600
+ else {
601
+ // B. Do not change anything if post is not saved yet (display sample permalink instead)
602
+ if($autosave || empty($post->post_status)) {
603
+ $sample_permalink_uri = $default_uri;
604
+ }
605
+ // C. Display custom URI if set
606
+ else {
607
+ $sample_permalink_uri = (!empty($permalink_manager_uris[$id])) ? $permalink_manager_uris[$id] : $native_uri;
608
+ }
609
 
610
+ // Decode URI & allow to filter it
611
+ $sample_permalink_uri = apply_filters('permalink_manager_filter_post_sample_uri', urldecode($sample_permalink_uri), $post);
612
 
613
+ // Prepare the sample & default permalink
614
+ $sample_permalink = sprintf("%s/<span class=\"editable\">%s</span>", $home_url, str_replace("//", "/", $sample_permalink_uri));
615
 
616
+ // Allow to filter the sample permalink URL
617
+ // $sample_permalink = apply_filters('permalink_manager_filter_post_sample_permalink', $sample_permalink, $post);
618
+ }
619
 
620
  // Append new HTML output
621
+ $new_html .= sprintf("<span class=\"sample-permalink-span\"><a id=\"sample-permalink\" href=\"%s\">%s</a></span>&nbsp;", strip_tags($sample_permalink), $sample_permalink);
622
+ $new_html .= (!$autosave) ? Permalink_Manager_Admin_Functions::display_uri_box($post) : "";
623
 
624
  // Append hidden field with native slug
625
+ $new_html .= (!empty($post->post_name)) ? "<span id=\"editable-post-name-full\">{$post->post_name}</span>" : "";
 
 
626
 
627
+ return $new_html;
628
  }
629
 
630
  /**
662
  function new_post_uri($post_id) {
663
  global $post, $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
664
 
665
+ // Do not trigger if post is a revision or imported via WP All Import (URI should be set after the post meta is added)
666
+ if(wp_is_post_revision($post_id) || (!empty($_REQUEST['page']) && $_REQUEST['page'] == 'pmxi-admin-import')) { return $post_id; }
667
 
668
  // Prevent language mismatch in MultilingualPress plugin
669
  if(is_admin() && !empty($post->ID) && $post->ID != $post_id) { return $post_id; }
670
 
671
+ // Stop when products are imported with WooCommerce importer
672
+ if(!empty($_REQUEST['action']) && $_REQUEST['action'] == 'woocommerce_do_ajax_product_import') { return $post_id; }
673
+
674
  // Do not do anything if post is autosaved
675
  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
676
 
707
  /**
708
  * Update URI from "Edit Post" admin page
709
  */
710
+ static public function update_post_uri($post_id) {
711
  global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
712
 
713
  // Verify nonce at first
716
  // Do not do anything if post is autosaved
717
  if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return $post_id; }
718
 
719
+ // Do not do anything on in "Bulk Edit" or when the post is imported via WP All Import
720
+ if(!empty($_REQUEST['bulk_edit']) || (!empty($_REQUEST['page']) && $_REQUEST['page'] == 'pmxi-admin-import')) { return $post_id; }
721
 
722
  // Do not do anything if the field with URI or element ID are not present
723
  if(!isset($_POST['custom_uri']) || empty($_POST['permalink-manager-edit-uri-element-id'])) { return $post_id; }
765
  }
766
 
767
  // Save only changed URIs
768
+ $permalink_manager_uris[$post_id] = $new_uri;
769
+ update_option('permalink-manager-uris', $permalink_manager_uris);
 
 
770
 
771
  // Update the slug (if changed)
772
+ if(isset($_POST['permalink-manager-edit-uri-element-slug']) && isset($_POST['native_slug']) && ($_POST['native_slug'] !== $_POST['permalink-manager-edit-uri-element-slug'])) {
773
  self::update_slug_by_id($_POST['native_slug'], $post_id);
774
  }
775
 
includes/views/permalink-manager-permastructs.php CHANGED
@@ -61,17 +61,11 @@ class Permalink_Manager_Permastructs extends Permalink_Manager_Class {
61
  // 3. Append fields for all post types
62
  foreach($all_post_types as $post_type) {
63
 
64
- $default_permastruct = trim(Permalink_Manager_Helper_Functions::get_default_permastruct($post_type['name']), "/");
65
- $current_permastruct = isset($permalink_manager_permastructs['post_types'][$post_type['name']]) ? $permalink_manager_permastructs['post_types'][$post_type['name']] : $default_permastruct;
66
-
67
  $fields["post_types"]["fields"][$post_type['name']] = array(
68
  'label' => $post_type['label'],
69
  'container' => 'row',
70
  'input_class' => 'permastruct-field',
71
- 'after_description' => self::restore_default_row($default_permastruct),
72
- 'extra_atts' => "data-default=\"{$default_permastruct}\"",
73
- 'value' => $current_permastruct,
74
- 'placeholder' => $default_permastruct,
75
  'type' => 'permastruct'
76
  );
77
  }
@@ -79,17 +73,6 @@ class Permalink_Manager_Permastructs extends Permalink_Manager_Class {
79
  return apply_filters('permalink-manager-permastructs-fields', $fields);
80
  }
81
 
82
- /**
83
- * Restore default permastructure row
84
- */
85
- public static function restore_default_row($default_permastruct) {
86
- return sprintf(
87
- "<p class=\"default-permastruct-row columns-container\"><span class=\"column-2_4\"><strong>%s:</strong> %s</span><span class=\"column-2_4\"><a href=\"#\" class=\"restore-default\"><span class=\"dashicons dashicons-image-rotate\"></span> %s</a></span></p>",
88
- __("Default permastructure", "permalink-manager"), esc_html($default_permastruct),
89
- __("Restore to Default Permastructure", "permalink-manager")
90
- );
91
- }
92
-
93
  /**
94
  * Get the array with settings and render the HTML output
95
  */
61
  // 3. Append fields for all post types
62
  foreach($all_post_types as $post_type) {
63
 
 
 
 
64
  $fields["post_types"]["fields"][$post_type['name']] = array(
65
  'label' => $post_type['label'],
66
  'container' => 'row',
67
  'input_class' => 'permastruct-field',
68
+ 'post_type' => $post_type,
 
 
 
69
  'type' => 'permastruct'
70
  );
71
  }
73
  return apply_filters('permalink-manager-permastructs-fields', $fields);
74
  }
75
 
 
 
 
 
 
 
 
 
 
 
 
76
  /**
77
  * Get the array with settings and render the HTML output
78
  */
includes/views/permalink-manager-settings.php CHANGED
@@ -106,6 +106,12 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
106
  'input_class' => '',
107
  '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')
108
  ),
 
 
 
 
 
 
109
  'force_custom_slugs' => array(
110
  'type' => 'select',
111
  'label' => __('Force custom slugs', 'permalink-manager'),
106
  'input_class' => '',
107
  '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')
108
  ),
109
+ 'pmxi_import_support' => array(
110
+ 'type' => 'single_checkbox',
111
+ 'label' => __('Disable support for WP All Import', 'permalink-manager'),
112
+ 'input_class' => '',
113
+ 'description' => __('If checked, the custom URIs will not be assigned to the posts imported by Wp All Import Pro plugin.', 'permalink-manager')
114
+ ),
115
  'force_custom_slugs' => array(
116
  'type' => 'select',
117
  'label' => __('Force custom slugs', 'permalink-manager'),
includes/views/permalink-manager-tools.php CHANGED
@@ -200,7 +200,7 @@ class Permalink_Manager_Tools extends Permalink_Manager_Class {
200
  $sidebar = '<h3>' . __('Important notices', 'permalink-manager') . '</h3>';
201
  $sidebar .= self::display_instructions();
202
 
203
- $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __('Find and replace', 'permalink-manager'), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'find_and_replace'), true);
204
 
205
  return $output;
206
  }
@@ -270,7 +270,7 @@ class Permalink_Manager_Tools extends Permalink_Manager_Class {
270
  $sidebar = '<h3>' . __('Important notices', 'permalink-manager') . '</h3>';
271
  $sidebar .= self::display_instructions();
272
 
273
- $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Regenerate', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'regenerate'), true);
274
 
275
  return $output;
276
  }
200
  $sidebar = '<h3>' . __('Important notices', 'permalink-manager') . '</h3>';
201
  $sidebar .= self::display_instructions();
202
 
203
+ $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __('Find and replace', 'permalink-manager'), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'find_and_replace'), true, 'form-ajax');
204
 
205
  return $output;
206
  }
270
  $sidebar = '<h3>' . __('Important notices', 'permalink-manager') . '</h3>';
271
  $sidebar .= self::display_instructions();
272
 
273
+ $output = Permalink_Manager_Admin_Functions::get_the_form($fields, 'columns-3', array('text' => __( 'Regenerate', 'permalink-manager' ), 'class' => 'primary margin-top'), $sidebar, array('action' => 'permalink-manager', 'name' => 'regenerate'), true, 'form-ajax');
274
 
275
  return $output;
276
  }
out/permalink-manager-admin.css CHANGED
@@ -14,6 +14,8 @@
14
  #permalink-manager .small-select{height:24px;line-height:22px;padding:0 8px 1px;font-size:11px}
15
  #permalink-manager .lead{font-size:125%}
16
  #permalink-manager .licence-info{font-weight:bold}
 
 
17
 
18
  #permalink-manager .woocommerce-icon:before{font-family:"WooCommerce";font-style:normal}
19
  #permalink-manager .woocommerce-cart:before{content:"\e01d"}
@@ -75,13 +77,12 @@
75
 
76
  #permalink-manager .updated-slugs-table .row-title{max-width:400px}
77
 
78
-
79
  /**
80
  * Columns
81
  */
82
  #permalink-manager .columns-container{overflow:hidden;margin-left:-15px;margin-right:-15px;clear:both;display:block}
83
  #permalink-manager .columns-container > *{float:left;padding-left:15px;padding-right:15px;box-sizing:border-box;-webkit-box-sizing:border-box;overflow:hidden;display:block}
84
- #permalink-manager .columns-container a{color:#aaa}
85
  #permalink-manager .columns-container .column-1_2,#permalink-manager .columns-container .column-2_4{width:50%}
86
  #permalink-manager .columns-container .column-1_3{width:33.33%}
87
  #permalink-manager .columns-container .column-1_3:nth-of-type(3n+1){clear:left}
@@ -106,10 +107,10 @@
106
  #permalink-manager.permalink-manager-edit-uri-box .close-button{float:right;width:36px;height:36px;padding:0;cursor:pointer;display:block}
107
  #permalink-manager.permalink-manager-edit-uri-box .close-icon{margin-top:4px;-webkit-border-radius:50%;border-radius:50%;text-indent:-1px;color:#72777c;line-height:36px;display:block;text-align:center}
108
  #permalink-manager.permalink-manager-edit-uri-box .close-icon:before{content:"\f158";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}
109
- #permalink-manager .default-permalink-row,#permalink-manager .redirects-row{border-top:1px solid #eee;padding-top:10px}
110
- #permalink-manager .redirects-row{border-top:3px double #eee;padding-top:10px}
111
  #permalink-manager .default-permalink-row,#permalink-manager .default-permastruct-row,#permalink-manager .redirects-row{color:#aaa;font-size:90%}
112
- #permalink-manager .restore-default{display:inline-block;text-align:right;width:100%;border-radius:0;color:#959595;text-decoration:none}
 
113
  #permalink-manager .widefat,#permalink-manager #redirect-panel-inside,#permalink-manager #redirect-panel-inside table{width:100%!important}
114
  #permalink-manager .heading,#permalink-manager .heading a{margin:0;line-height:1.4;font-weight:600;text-decoration:none;color:#777}
115
  #permalink-manager.permalink-manager-edit-term .permalink-manager-edit-uri-box{display:block!important;margin:0}
@@ -126,16 +127,26 @@
126
  .permalink-manager.postbox .heading{border-bottom:3px double #eee}
127
  .permalink-manager.postbox a{color:#444;text-decoration:none;white-space:nowrap}
128
 
 
 
 
 
 
 
 
 
129
  /**
130
  * Redirect panel
131
  */
132
- .permalink-manager #redirect-panel-inside{display:none}
133
- .permalink-manager #redirect-panel-inside,#permalink-manager #redirect-panel-inside p{margin-top:10px}
134
- .permalink-manager #redirect-panel-inside table{margin-bottom:10px}
135
- .permalink-manager #redirect-panel-inside table td{padding:5px 0;width:100%}
136
- .permalink-manager #redirect-panel-inside table td a{text-decoration:none;text-align:right}
137
- .permalink-manager #redirect-panel-inside .single-section{margin-left:-10px;margin-right:-10px;padding:10px;border-top:1px dashed #eee}
138
- .permalink-manager #redirect-panel-inside .single-section:last-of-type{padding-bottom:0}
 
 
139
  .permalink-manager .sample-row{display:none}
140
  .permalink-manager .redirects-panel-description{margin-bottom:10px}
141
  .permalink-manager .redirects-panel-description *{font-size:12px}
@@ -150,6 +161,18 @@
150
  */
151
  .tippy-tooltip.tippy-pm-theme{text-align:left;font-size:13px}
152
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  /**
154
  * TagEditor custom theme & "Stop Words"
155
  */
14
  #permalink-manager .small-select{height:24px;line-height:22px;padding:0 8px 1px;font-size:11px}
15
  #permalink-manager .lead{font-size:125%}
16
  #permalink-manager .licence-info{font-weight:bold}
17
+ #permalink-manager p label{font-size:13px;color:#555d66;font-weight:bold}
18
+ #permalink-manager a:focus{box-shadow:none}
19
 
20
  #permalink-manager .woocommerce-icon:before{font-family:"WooCommerce";font-style:normal}
21
  #permalink-manager .woocommerce-cart:before{content:"\e01d"}
77
 
78
  #permalink-manager .updated-slugs-table .row-title{max-width:400px}
79
 
 
80
  /**
81
  * Columns
82
  */
83
  #permalink-manager .columns-container{overflow:hidden;margin-left:-15px;margin-right:-15px;clear:both;display:block}
84
  #permalink-manager .columns-container > *{float:left;padding-left:15px;padding-right:15px;box-sizing:border-box;-webkit-box-sizing:border-box;overflow:hidden;display:block}
85
+ #permalink-manager .columns-container span a{color:#aaa}
86
  #permalink-manager .columns-container .column-1_2,#permalink-manager .columns-container .column-2_4{width:50%}
87
  #permalink-manager .columns-container .column-1_3{width:33.33%}
88
  #permalink-manager .columns-container .column-1_3:nth-of-type(3n+1){clear:left}
107
  #permalink-manager.permalink-manager-edit-uri-box .close-button{float:right;width:36px;height:36px;padding:0;cursor:pointer;display:block}
108
  #permalink-manager.permalink-manager-edit-uri-box .close-icon{margin-top:4px;-webkit-border-radius:50%;border-radius:50%;text-indent:-1px;color:#72777c;line-height:36px;display:block;text-align:center}
109
  #permalink-manager.permalink-manager-edit-uri-box .close-icon:before{content:"\f158";display:inline-block;font:400 20px/1 dashicons;speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none!important}
110
+ #permalink-manager .default-permalink-row,#permalink-manager .redirects-row{border-top:1px solid #eee;padding-top:15px}
 
111
  #permalink-manager .default-permalink-row,#permalink-manager .default-permastruct-row,#permalink-manager .redirects-row{color:#aaa;font-size:90%}
112
+ #permalink-manager .restore-default,#permalink-manager .permastruct-toggle-button a{display:inline-block;width:100%;border-radius:0;color:#959595;text-decoration:none}
113
+ #permalink-manager .restore-default{text-align:right}
114
  #permalink-manager .widefat,#permalink-manager #redirect-panel-inside,#permalink-manager #redirect-panel-inside table{width:100%!important}
115
  #permalink-manager .heading,#permalink-manager .heading a{margin:0;line-height:1.4;font-weight:600;text-decoration:none;color:#777}
116
  #permalink-manager.permalink-manager-edit-term .permalink-manager-edit-uri-box{display:block!important;margin:0}
127
  .permalink-manager.postbox .heading{border-bottom:3px double #eee}
128
  .permalink-manager.postbox a{color:#444;text-decoration:none;white-space:nowrap}
129
 
130
+ #permalink-manager .permalink-manager-gutenberg > div{margin-top:15px;}
131
+ #permalink-manager .permalink-manager-gutenberg .default-permalink-row > *{width:100%;float:none}
132
+ #permalink-manager .permalink-manager-gutenberg .restore-default{text-align:left;margin-top:15px}
133
+ #permalink-manager .permalink-manager-gutenberg .redirects-row{padding-top:15px}
134
+ #permalink-manager .permalink-manager-gutenberg .redirects-panel .heading{background:#eee;padding:15px 10px;margin-bottom:-15px;width:100%;display:block;font-size:110%}
135
+ #permalink-manager #redirect-panel-inside, #permalink-manager #redirect-panel-inside p{margin-top:15px}
136
+ #permalink-manager .redirects-panel-description *{font-size:11px}
137
+
138
  /**
139
  * Redirect panel
140
  */
141
+ #permalink-manager #redirect-panel-inside{display:none}
142
+ #permalink-manager #redirect-panel-inside,#permalink-manager #redirect-panel-inside p{margin-top:15px;}
143
+ #permalink-manager #redirect-panel-inside table{margin-bottom:10px;margin-top:-5px}
144
+ #permalink-manager #redirect-panel-inside table td{padding:5px 0;width:100%}
145
+ #permalink-manager #redirect-panel-inside table td a{text-decoration:none;text-align:right}
146
+ #permalink-manager #redirect-panel-inside .single-section{margin-left:-10px;margin-right:-10px;padding:10px;border-top:1px dashed #eee}
147
+ #permalink-manager #redirect-panel-inside .single-section:last-of-type{padding-bottom:0}
148
+ #permalink-manager #redirect-panel-inside .single-section:first-of-type{padding-top:0;border:0}
149
+ #permalink-manager #redirect-panel-inside .single-section > p:first-of-type{margin-top:0}
150
  .permalink-manager .sample-row{display:none}
151
  .permalink-manager .redirects-panel-description{margin-bottom:10px}
152
  .permalink-manager .redirects-panel-description *{font-size:12px}
161
  */
162
  .tippy-tooltip.tippy-pm-theme{text-align:left;font-size:13px}
163
 
164
+ /**
165
+ * Permastructures
166
+ */
167
+ #permalink-manager .all-permastruct-container
168
+ #permalink-manager .all-permastruct-container > *,#permalink-manager .all-permastruct-container .permastruct-toggle > *:last-child{margin-top:15px}
169
+ #permalink-manager .all-permastruct-container .permastruct-toggle{display:none}
170
+ #permalink-manager .all-permastruct-container h4{font-size:14px}
171
+ #permalink-manager .all-permastruct-container p{font-size:13px}
172
+ #permalink-manager .all-permastruct-container label{font-weight:600;margin-top:15px!important;font-size:13px;margin-bottom:5px!important;display:block;clear:both}
173
+ #permalink-manager .permastruct-toggle-button a{font-size:90%;padding-top:10px;font-weight:bold}
174
+
175
+
176
  /**
177
  * TagEditor custom theme & "Stop Words"
178
  */
out/permalink-manager-admin.js CHANGED
@@ -62,13 +62,13 @@ jQuery(document).ready(function() {
62
  /**
63
  * Toggle "Edit Redirects" box
64
  */
65
- jQuery('#toggle-redirect-panel').on('click', function() {
66
  jQuery('#redirect-panel-inside').slideToggle();
67
 
68
  return false;
69
  });
70
 
71
- jQuery('.permalink-manager.redirects-panel #permalink-manager-new-redirect').on('click', function() {
72
  // Find the table
73
  var table = jQuery(this).parents('.redirects-panel').find('table');
74
 
@@ -85,7 +85,7 @@ jQuery(document).ready(function() {
85
  return false;
86
  });
87
 
88
- jQuery('.permalink-manager.redirects-panel').on('click', '.remove-redirect', function() {
89
  var table = jQuery(this).closest('tr').remove();
90
  return false;
91
  });
@@ -201,9 +201,21 @@ jQuery(document).ready(function() {
201
  /**
202
  * Restore "Default URI"
203
  */
204
- jQuery('#permalink-manager .restore-default').on('click', function() {
205
- var input = jQuery(this).parents('.field-container, .permalink-manager-edit-uri-box').find('input.custom_uri');
206
- jQuery(input).val(jQuery(input).data('default')).trigger('keyup');
 
 
 
 
 
 
 
 
 
 
 
 
207
  return false;
208
  });
209
 
@@ -222,6 +234,49 @@ jQuery(document).ready(function() {
222
  });
223
  });
224
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
225
  /**
226
  * Check expiration date
227
  */
@@ -257,7 +312,7 @@ jQuery(document).ready(function() {
257
  }
258
  }
259
 
260
- jQuery('#permalink-manager #tools form').on('submit', function() {
261
  var data = jQuery(this).serialize() + '&action=' + 'pm_bulk_tools';
262
  var form = jQuery(this);
263
  var updated_count = total = progress = 0;
@@ -348,16 +403,6 @@ jQuery(document).ready(function() {
348
  return false;
349
  });
350
 
351
- /**
352
- * Help tooltips
353
- */
354
- new Tippy('#permalink-manager .help_tooltip', {
355
- position: 'top-start',
356
- arrow: true,
357
- theme: 'tippy-pm',
358
- distance: 20,
359
- });
360
-
361
  /**
362
  * Stop-words
363
  */
62
  /**
63
  * Toggle "Edit Redirects" box
64
  */
65
+ jQuery('#permalink-manager').on('click', '#toggle-redirect-panel', function() {
66
  jQuery('#redirect-panel-inside').slideToggle();
67
 
68
  return false;
69
  });
70
 
71
+ jQuery('#permalink-manager').on('click', '.permalink-manager.redirects-panel #permalink-manager-new-redirect', function() {
72
  // Find the table
73
  var table = jQuery(this).parents('.redirects-panel').find('table');
74
 
85
  return false;
86
  });
87
 
88
+ jQuery('#permalink-manager').on('click', '.remove-redirect', function() {
89
  var table = jQuery(this).closest('tr').remove();
90
  return false;
91
  });
201
  /**
202
  * Restore "Default URI"
203
  */
204
+ jQuery('#permalink-manager').on('click', '.restore-default', function() {
205
+ var input = jQuery(this).parents('.field-container, .permalink-manager-edit-uri-box, #permalink-manager .inside').find('input.custom_uri, input.permastruct-field');
206
+ var default_uri = jQuery(input).attr('data-default');
207
+
208
+ jQuery(input).val(default_uri).trigger('keyup');
209
+
210
+ return false;
211
+ });
212
+
213
+ /**
214
+ * Dispaly additional permastructure settings
215
+ */
216
+ jQuery('#permalink-manager').on('click', '.permastruct-toggle-button a', function() {
217
+ jQuery(this).parents('.field-container').find('.permastruct-toggle').slideToggle();
218
+
219
  return false;
220
  });
221
 
234
  });
235
  });
236
 
237
+ /**
238
+ * Save permalinks from Gutenberg with AJAX
239
+ */
240
+ jQuery('#permalink-manager .save-row.hidden').removeClass('hidden');
241
+ jQuery('#permalink-manager').on('click', '#permalink-manager-save-button', function() {
242
+ var pm_container = jQuery(this).parents('#permalink-manager');
243
+ var pm_fields = jQuery(pm_container).find("input, select");
244
+ var pm_data = jQuery(pm_fields).serialize() + '&action=' + 'pm_save_permalink';
245
+ var button = jQuery(this);
246
+
247
+ jQuery.ajax({
248
+ type: 'POST',
249
+ url: permalink_manager.ajax_url,
250
+ data: pm_data,
251
+ beforeSend: function() {
252
+ jQuery(pm_container).LoadingOverlay("show", {
253
+ background : "rgba(0, 0, 0, 0.1)",
254
+ });
255
+ },
256
+ success: function(html) {
257
+ jQuery(pm_container).find('.permalink-manager-gutenberg').replaceWith(html);
258
+ jQuery(pm_container).LoadingOverlay("hide");
259
+
260
+ if(wp && wp.data !== 'undefined') {
261
+ wp.data.dispatch('core/editor').refreshPost();
262
+ }
263
+ }
264
+ });
265
+
266
+ return false;
267
+ });
268
+
269
+ /**
270
+ * Help tooltips
271
+ */
272
+ new Tippy('#permalink-manager .help_tooltip', {
273
+ position: 'top-start',
274
+ arrow: true,
275
+ theme: 'tippy-pm',
276
+ distance: 20,
277
+ });
278
+
279
+
280
  /**
281
  * Check expiration date
282
  */
312
  }
313
  }
314
 
315
+ jQuery('#permalink-manager #tools form.form-ajax').on('submit', function() {
316
  var data = jQuery(this).serialize() + '&action=' + 'pm_bulk_tools';
317
  var form = jQuery(this);
318
  var updated_count = total = progress = 0;
403
  return false;
404
  });
405
 
 
 
 
 
 
 
 
 
 
 
406
  /**
407
  * Stop-words
408
  */
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.1.1
8
  * Author: Maciej Bis
9
  * Author URI: http://maciejbis.net/
10
  * License: GPL-2.0+
@@ -21,7 +21,7 @@ if (!defined('WPINC')) {
21
  // Define the directories used to load plugin files.
22
  define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
23
  define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
24
- define( 'PERMALINK_MANAGER_VERSION', '2.1.1' );
25
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
26
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
27
  define( 'PERMALINK_MANAGER_BASENAME', dirname(plugin_basename(__FILE__)));
@@ -157,7 +157,7 @@ class Permalink_Manager_Class {
157
  'canonical_redirect' => 1,
158
  'trailing_slashes' => 0,
159
  'pagination_redirect' => 0,
160
- 'auto_remove_duplicates' => 0,
161
  'partial_disable' => array(),
162
  'deep_detect' => 1,
163
  'fix_language_mismatch' => 1
@@ -182,18 +182,18 @@ class Permalink_Manager_Class {
182
  */
183
  public function default_alerts($alerts) {
184
  $default_alerts = apply_filters('permalink-manager-default-alerts', array(
185
- 'october2018' => array(
186
  'txt' => sprintf(
187
  __("Get access to extra features: full taxonomy and WooCommerce support, possibility to use custom fields inside the permalinks and more!<br /><strong>Buy Permalink Manager Pro <a href=\"%s\" target=\"_blank\">here</a> and save %s using \"%s\" coupon code!</strong> Valid until %s!", "permalink-manager"),
188
  PERMALINK_MANAGER_WEBSITE,
189
- '30&#37;',
190
- 'OCTOBER',
191
- '31st October'
192
  ),
193
  'type' => 'notice-info',
194
  'show' => 'pro_hide',
195
  'plugin_only' => true,
196
- 'until' => '2018-11-01'
197
  )
198
  ));
199
 
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.1.2.4
8
  * Author: Maciej Bis
9
  * Author URI: http://maciejbis.net/
10
  * License: GPL-2.0+
21
  // Define the directories used to load plugin files.
22
  define( 'PERMALINK_MANAGER_PLUGIN_NAME', 'Permalink Manager' );
23
  define( 'PERMALINK_MANAGER_PLUGIN_SLUG', 'permalink-manager' );
24
+ define( 'PERMALINK_MANAGER_VERSION', '2.1.2.4' );
25
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
26
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit(dirname(__FILE__)) );
27
  define( 'PERMALINK_MANAGER_BASENAME', dirname(plugin_basename(__FILE__)));
157
  'canonical_redirect' => 1,
158
  'trailing_slashes' => 0,
159
  'pagination_redirect' => 0,
160
+ 'auto_remove_duplicates' => 1,
161
  'partial_disable' => array(),
162
  'deep_detect' => 1,
163
  'fix_language_mismatch' => 1
182
  */
183
  public function default_alerts($alerts) {
184
  $default_alerts = apply_filters('permalink-manager-default-alerts', array(
185
+ 'spring' => array(
186
  'txt' => sprintf(
187
  __("Get access to extra features: full taxonomy and WooCommerce support, possibility to use custom fields inside the permalinks and more!<br /><strong>Buy Permalink Manager Pro <a href=\"%s\" target=\"_blank\">here</a> and save %s using \"%s\" coupon code!</strong> Valid until %s!", "permalink-manager"),
188
  PERMALINK_MANAGER_WEBSITE,
189
+ '20&#37;',
190
+ 'SPRING',
191
+ '31.03'
192
  ),
193
  'type' => 'notice-info',
194
  'show' => 'pro_hide',
195
  'plugin_only' => true,
196
+ 'until' => '2018-04-01'
197
  )
198
  ));
199