Permalink Manager Lite - Version 2.0.5.5

Version Description

  • Discount URLs for WooCommerce - now the shop clients can use coupons' custom URIs to easily apply the discount to the cart
  • Extra AJAX check for duplicated URIs in "Edit URI" box
  • Wordpress CronJobs for "Automatically remove duplicates" functionality
  • Extra improvements in "save_post/update_term" hooks
Download this release

Release Info

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

Code changes from version 2.0.5.4 to 2.0.5.5

README.txt CHANGED
@@ -7,7 +7,7 @@ Tags: urls, permalinks, custom permalinks, url, permalink, woocommerce permalink
7
  Requires at least: 4.0
8
  Requires PHP: 5.4
9
  Tested up to: 4.9
10
- Stable tag: 2.0.5.4
11
 
12
  Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
13
 
@@ -36,23 +36,23 @@ To improve the user experience, each tool allows also to filter the permalinks b
36
 
37
  = All features =
38
 
39
- * "Permalink Editor" - list of your permalinks (groupped by post types).
40
- * "Auto-update" URI
41
- * "Regenerate/Reset" permalinks, custom and native URIs (slugs).
42
- * "Find and replace" strings in permalinks, custom and native URIs (slugs).
43
- * Support for "Primary Term" functionality implemented in "Yoast SEO" plugin.
44
- * Optional redirect (301 or 302) from old (native) permalinks to new (custom) permalinks.
45
  * Possibility to disable native canonical redirects.
 
46
 
47
  = Additional features available in Permalink Manager Pro =
48
 
49
- * Priority support
50
- * Full support for taxonomies (categories, tags & custom taxonomies)
51
- * Extra redirects
52
- * Full support for WooCommerce (products, product tags, product categories)
53
- * "Stop-words" to keep your permalinks short & clean (pre-defined "stop-words" lists are available in 21 languages)
54
- * Add custom fields to the permalinks (Advanced Custom Fields compatible)
55
- * Import permalinks from "Custom Permalinks" plugin
 
56
 
57
  Buy <a href="https://permalinkmanager.pro?utm_source=wordpress">Permalink Manager Pro here</a>.
58
 
@@ -79,8 +79,8 @@ A. Yes, if you used Permalink Manager only to regenerate the slugs (native post
79
 
80
  It is because Permalink Manager overwrites one of the core Wordpress functionalities to bypass the rewrite rules ("regular expressions" to detect the posts/pages/taxonomies/etc. and another parameters from the URL) by using the array of custom permalinks (you can check them in "Debug" tab) that are used only by my plugin.
81
 
82
- = Q. Can I use Permalink Manager to alter the permalinks for taxonomies?
83
- A. This feature will be available in Permalink Manager Pro.
84
 
85
  = Q. Does this plugin support Buddypress?
86
  A. Currently there is no 100% guarantee that Permalink Manager will work correctly with Buddypress.
@@ -98,13 +98,18 @@ A. Currently there is no 100% guarantee that Permalink Manager will work correct
98
 
99
  == Changelog ==
100
 
 
 
 
 
 
 
101
  = 2.0.5.4 =
102
  * New filter - "permalink_manager_empty_tag_replacement"
103
  * Fix for term placeholder tags in taxonomies permastructures
104
  * Page pagination improvement (404 error page for non-existing pages)
105
  * New settings field for pagination redirect
106
  * Trailing slashes are no longer added to custom permalinks ended with extension, eg. .html, or .php
107
- * The attachment URI duplicates are removed if redirect for them is enabled in Yoast's SEO Premium plugin
108
 
109
  = 2.0.5.3 =
110
  * Hotfix for redirects - redirect chain no longer occurs (WPML)
7
  Requires at least: 4.0
8
  Requires PHP: 5.4
9
  Tested up to: 4.9
10
+ Stable tag: 2.0.5.5
11
 
12
  Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
13
 
36
 
37
  = All features =
38
 
39
+ * A completely custom permalink can be set for each post, page and public custom post type (+ categories, tags & custom taxonomies terms in Permalink Manager Pro).
40
+ * Permalinks lists ("URI Editor" groupped by post types & dates).
41
+ * Bulk tools: "Regenerate/Reset" + "Find and replace" for permalinks and custom & native URIs (slugs).
42
+ * Optional redirect (301 or 302): old (native) permalinks are redirected (by default) to new (custom) permalinks.
 
 
43
  * Possibility to disable native canonical redirects.
44
+ * Control trailing slashes settings.
45
 
46
  = Additional features available in Permalink Manager Pro =
47
 
48
+ * Full support for taxonomies (categories, tags & custom taxonomies).
49
+ * Full support for WooCommerce (products, product tags, product categories).
50
+ * WooCommerce Coupon URLs - custom URIs can be assigned to coupon codes (eg. http://shop.com/BLACKFRIDAY) that will automatically apply the discount to the cart
51
+ * Possibility to use custom fields inside permalinks (support for Advanced Custom Fields plugin).
52
+ * Extra redirects (possibility to set-up extra addresses (aliases) that would redirect to the custom URIs).
53
+ * "Stop-words" - user-defined words will be automatically removed from default permalinks.
54
+ * Import permalinks from "Custom Permalinks" plugin.
55
+ * Priority support.
56
 
57
  Buy <a href="https://permalinkmanager.pro?utm_source=wordpress">Permalink Manager Pro here</a>.
58
 
79
 
80
  It is because Permalink Manager overwrites one of the core Wordpress functionalities to bypass the rewrite rules ("regular expressions" to detect the posts/pages/taxonomies/etc. and another parameters from the URL) by using the array of custom permalinks (you can check them in "Debug" tab) that are used only by my plugin.
81
 
82
+ = Q. Can I use Permalink Manager to change the terms permalinks (eg. post or product categories)?
83
+ A. This feature is available only in Permalink Manager Pro.
84
 
85
  = Q. Does this plugin support Buddypress?
86
  A. Currently there is no 100% guarantee that Permalink Manager will work correctly with Buddypress.
98
 
99
  == Changelog ==
100
 
101
+ = 2.0.5.5 =
102
+ * Discount URLs for WooCommerce - now the shop clients can use coupons' custom URIs to easily apply the discount to the cart
103
+ * Extra AJAX check for duplicated URIs in "Edit URI" box
104
+ * Wordpress CronJobs for "Automatically remove duplicates" functionality
105
+ * Extra improvements in "save_post/update_term" hooks
106
+
107
  = 2.0.5.4 =
108
  * New filter - "permalink_manager_empty_tag_replacement"
109
  * Fix for term placeholder tags in taxonomies permastructures
110
  * Page pagination improvement (404 error page for non-existing pages)
111
  * New settings field for pagination redirect
112
  * Trailing slashes are no longer added to custom permalinks ended with extension, eg. .html, or .php
 
113
 
114
  = 2.0.5.3 =
115
  * Hotfix for redirects - redirect chain no longer occurs (WPML)
includes/core/permalink-manager-actions.php CHANGED
@@ -5,8 +5,14 @@
5
  class Permalink_Manager_Actions extends Permalink_Manager_Class {
6
 
7
  public function __construct() {
8
- add_action( 'admin_init', array($this, 'trigger_action'), 999 );
9
- add_action( 'admin_init', array($this, 'extra_actions') );
 
 
 
 
 
 
10
  }
11
 
12
  /**
@@ -49,7 +55,7 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
49
  if($updated_slugs_count > 0) {
50
  $updated_title = __('List of updated items', 'bis');
51
  $alert_content = sprintf( _n( '<strong>%d</strong> slug was updated!', '<strong>%d</strong> slugs were updated!', $updated_slugs_count, 'permalink-manager' ), $updated_slugs_count ) . ' ';
52
- $alert_content .= sprintf( __( '<a %s>Click here</a> to go to the list of updated slugs', 'permalink-manager' ), "href=\"#updated-list\" title=\"{$updated_title}\" class=\"thickbox\"");
53
 
54
  $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message($alert_content, 'updated');
55
  $permalink_manager_after_sections_html .= Permalink_Manager_Admin_Functions::display_updated_slugs($updated_slugs_array);
@@ -102,6 +108,9 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
102
  } else if(!empty($_REQUEST['remove-uri'])) {
103
  $uri_key = sanitize_text_field($_REQUEST['remove-uri']);
104
  self::force_clear_single_element_uris_and_redirects($uri_key);
 
 
 
105
  } else if(!empty($_POST['screen-options-apply'])) {
106
  self::save_screen_options();
107
  }
@@ -222,12 +231,21 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
222
  $removed_uris = 0;
223
  $removed_redirects = 0;
224
 
 
 
 
225
  // 1. Check if element exists
226
- if(is_numeric($element_id)) {
 
 
 
 
 
 
227
  $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->prefix}posts WHERE ID = {$element_id} AND post_status NOT IN ('auto-draft', 'trash') AND post_type != 'nav_menu_item'");
228
 
229
  // Remove custom URIs for removed, auto-draft posts or disabled post types
230
- $remove = (!empty($post_type)) ? Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type') : true;
231
 
232
  // Remove custom URIs for attachments redirected with Yoast's SEO Premium
233
  $yoast_permalink_options = (class_exists('WPSEO_Premium')) ? get_option('wpseo_permalinks') : array();
@@ -238,12 +256,6 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
238
  $remove = true;
239
  }
240
  }
241
- } else if(strpos($element_id, 'tax-') !== false) {
242
- $term_id = preg_replace("/[^0-9]/", "", $element_id);
243
- $taxonomy = $wpdb->get_var($wpdb->prepare("SELECT t.taxonomy FROM $wpdb->term_taxonomy AS t WHERE t.term_id = %s LIMIT 1", $term_id));
244
-
245
- // Remove custom URIs for removed terms or disabled taxonomies
246
- $remove = (!empty($taxonomy)) ? Permalink_Manager_Helper_Functions::is_disabled($taxonomy) : true;
247
  }
248
 
249
  // 2A. Remove ALL unused custom permalinks & redirects
@@ -307,6 +319,20 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
307
  }
308
  }
309
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  /**
311
  * "Find and replace" in "Tools"
312
  */
@@ -363,6 +389,64 @@ class Permalink_Manager_Actions extends Permalink_Manager_Class {
363
  Permalink_Manager_Third_Parties::import_custom_permalinks_uris();
364
  }
365
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
366
  }
367
 
368
  ?>
5
  class Permalink_Manager_Actions extends Permalink_Manager_Class {
6
 
7
  public function __construct() {
8
+ add_action('admin_init', array($this, 'trigger_action'), 999);
9
+ add_action('admin_init', array($this, 'extra_actions'));
10
+
11
+ add_action('clean_permalinks_event', array($this, 'clean_permalinks_hook'));
12
+ add_action('init', array($this, 'clean_permalinks_cronjob'));
13
+
14
+ // Hotfix for Multisite
15
+ add_filter('pre_update_option', array($this, 'update_custom_uris'), 9, 3);
16
  }
17
 
18
  /**
55
  if($updated_slugs_count > 0) {
56
  $updated_title = __('List of updated items', 'bis');
57
  $alert_content = sprintf( _n( '<strong>%d</strong> slug was updated!', '<strong>%d</strong> slugs were updated!', $updated_slugs_count, 'permalink-manager' ), $updated_slugs_count ) . ' ';
58
+ $alert_content .= sprintf( __( '<a %s>Click here</a> to go to the list of updated slugs', 'permalink-manager' ), "href=\"#updated-list\" title=\"{$updated_title}\"");
59
 
60
  $permalink_manager_before_sections_html .= Permalink_Manager_Admin_Functions::get_alert_message($alert_content, 'updated');
61
  $permalink_manager_after_sections_html .= Permalink_Manager_Admin_Functions::display_updated_slugs($updated_slugs_array);
108
  } else if(!empty($_REQUEST['remove-uri'])) {
109
  $uri_key = sanitize_text_field($_REQUEST['remove-uri']);
110
  self::force_clear_single_element_uris_and_redirects($uri_key);
111
+ } else if(!empty($_REQUEST['remove-redirect'])) {
112
+ $redirect_key = sanitize_text_field($_REQUEST['remove-redirect']);
113
+ self::force_clear_single_redirect($redirect_key);
114
  } else if(!empty($_POST['screen-options-apply'])) {
115
  self::save_screen_options();
116
  }
231
  $removed_uris = 0;
232
  $removed_redirects = 0;
233
 
234
+ // Only admin users can remove the broken URIs for removed post types & taxonomies
235
+ $check_if_exists = (is_admin()) ? true : false;
236
+
237
  // 1. Check if element exists
238
+ if(strpos($element_id, 'tax-') !== false) {
239
+ $term_id = preg_replace("/[^0-9]/", "", $element_id);
240
+ $taxonomy = $wpdb->get_var($wpdb->prepare("SELECT t.taxonomy FROM $wpdb->term_taxonomy AS t WHERE t.term_id = %s LIMIT 1", $term_id));
241
+
242
+ // Remove custom URIs for removed terms or disabled taxonomies
243
+ $remove = (!empty($taxonomy)) ? Permalink_Manager_Helper_Functions::is_disabled($taxonomy, 'taxonomy', $check_if_exists) : true;
244
+ } else if(is_numeric($element_id)) {
245
  $post_type = $wpdb->get_var("SELECT post_type FROM {$wpdb->prefix}posts WHERE ID = {$element_id} AND post_status NOT IN ('auto-draft', 'trash') AND post_type != 'nav_menu_item'");
246
 
247
  // Remove custom URIs for removed, auto-draft posts or disabled post types
248
+ $remove = (!empty($post_type)) ? Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type', $check_if_exists) : true;
249
 
250
  // Remove custom URIs for attachments redirected with Yoast's SEO Premium
251
  $yoast_permalink_options = (class_exists('WPSEO_Premium')) ? get_option('wpseo_permalinks') : array();
256
  $remove = true;
257
  }
258
  }
 
 
 
 
 
 
259
  }
260
 
261
  // 2A. Remove ALL unused custom permalinks & redirects
319
  }
320
  }
321
 
322
+ public static function force_clear_single_redirect($redirect_key) {
323
+ global $permalink_manager_redirects, $permalink_manager_before_sections_html;
324
+
325
+ preg_match("/redirect-([\d]+)_([\d]+)/", $redirect_key, $ids);
326
+
327
+ if(!empty($permalink_manager_redirects[$ids[2]][$ids[1]])) {
328
+ unset($permalink_manager_redirects[$ids[2]][$ids[1]]);
329
+
330
+ update_option('permalink-manager-redirects', array_filter($permalink_manager_redirects));
331
+
332
+ $permalink_manager_before_sections_html = Permalink_Manager_Admin_Functions::get_alert_message(__( 'The redirect was removed successfully!', 'permalink-manager' ), 'updated');
333
+ }
334
+ }
335
+
336
  /**
337
  * "Find and replace" in "Tools"
338
  */
389
  Permalink_Manager_Third_Parties::import_custom_permalinks_uris();
390
  }
391
 
392
+ /**
393
+ * "Automatically remove duplicates" (if enabled) in background
394
+ */
395
+ function clean_permalinks_hook() {
396
+ global $permalink_manager_uris, $permalink_manager_redirects;
397
+
398
+ // Backup the custom URIs
399
+ if(is_array($permalink_manager_uris)) {
400
+ update_option('permalink-manager-uris_backup', $permalink_manager_uris);
401
+ }
402
+ // Backup the custom redirects
403
+ if(is_array($permalink_manager_redirects)) {
404
+ update_option('permalink-manager-redirects_backup', $permalink_manager_redirects);
405
+ }
406
+
407
+ self::clear_all_uris();
408
+ }
409
+
410
+ function clean_permalinks_cronjob() {
411
+ global $permalink_manager_options;
412
+
413
+ $event_name = 'clean_permalinks_event';
414
+
415
+ // Set-up the "Automatically remove duplicates" function that runs in background once a day
416
+ if(!empty($permalink_manager_options['general']['auto_remove_duplicates'])) {
417
+ if(!wp_next_scheduled($event_name)) {
418
+ wp_schedule_event(time(), 'daily', $event_name);
419
+ }
420
+ } else if(wp_next_scheduled($event_name)) {
421
+ $event_timestamp = wp_next_scheduled($event_name);
422
+ wp_unschedule_event($event_timestamp, $event_name);
423
+ }
424
+ }
425
+
426
+ /**
427
+ * Hotfix for network
428
+ */
429
+ function update_custom_uris($new_value, $option, $old_value) {
430
+ global $wpdb;
431
+
432
+ // Trigger only if multisite is detected
433
+ if(!is_multisite() || $option !== 'permalink-manager-uris') { return $new_value; }
434
+
435
+ // Get non-cached array with URIs
436
+ $permalink_manager_uris_raw = $wpdb->get_var($wpdb->prepare("SELECT option_value FROM $wpdb->options WHERE option_name = %s LIMIT 1", $option));
437
+ $permalink_manager_uris = maybe_unserialize($permalink_manager_uris_raw);
438
+
439
+ // Check if old value differs from the array set with $permalink_manager_uris global (by default they should be identical)
440
+ $array_diff = array_diff((array) $permalink_manager_uris, (array) $old_value);
441
+
442
+ if($array_diff) {
443
+ // Stop the function
444
+ $new_value = $old_value;
445
+ }
446
+
447
+ return $new_value;
448
+ }
449
+
450
  }
451
 
452
  ?>
includes/core/permalink-manager-admin-functions.php CHANGED
@@ -17,7 +17,9 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
17
  add_action( 'admin_notices', array($this, 'display_global_notices'));
18
  add_action( 'wp_ajax_dismissed_notice_handler', array($this, 'hide_global_notice') );
19
 
20
- add_filter( "default_hidden_columns" , array($this, 'quick_edit_hide_column'), 10, 2 );
 
 
21
  }
22
 
23
  /**
@@ -99,7 +101,8 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
99
  wp_enqueue_script( 'permalink-manager-plugins', PERMALINK_MANAGER_URL . '/out/permalink-manager-plugins.js', array( 'jquery', ), PERMALINK_MANAGER_VERSION, false );
100
  wp_enqueue_script( 'permalink-manager', PERMALINK_MANAGER_URL . '/out/permalink-manager-admin.js', array( 'jquery', 'permalink-manager-plugins' ), PERMALINK_MANAGER_VERSION, false );
101
 
102
- wp_localize_script( 'permalink-manager', 'permalink_manager', array('url' => PERMALINK_MANAGER_URL) );
 
103
  }
104
 
105
  /**
@@ -549,20 +552,21 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
549
  * "Quick Edit" Box
550
  */
551
  public static function quick_edit_column_form($is_taxonomy = false) {
552
- $html = Permalink_Manager_Admin_Functions::generate_option_field('permalink-manager-quick-edit', array('value' => true, 'type' => 'hidden'));
553
  $html .= "<fieldset class=\"inline-edit-permalink\">";
554
  $html .= sprintf("<legend class=\"inline-edit-legend\">%s</legend>", __("Permalink Manager", "permalink-manager"));
555
 
556
  $html .= "<div class=\"inline-edit-col\">";
557
  $html .= sprintf("<label class=\"inline-edit-group\"><span class=\"title\">%s</span><span class=\"input-text-wrap\">%s</span></label>",
558
  __("Current URI", "permalink-manager"),
559
- Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("input_class" => "custom_uri", "value" => ''))
560
  );
561
  $html .= "</div>";
562
 
563
  $html .= "</fieldset>";
564
 
565
- // Append nonce field
 
566
  $html .= wp_nonce_field( 'permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false );
567
 
568
  return $html;
@@ -575,7 +579,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
575
  global $permalink_manager_options;
576
 
577
  if(!empty($element->ID)) {
578
- $id = $element->ID;
579
 
580
  // Auto-update settings
581
  $auto_update_val = get_post_meta($id, "auto_update_uri", true);
@@ -588,6 +592,7 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
588
  );
589
  } else {
590
  $id = $element->term_id;
 
591
  }
592
 
593
  // Decode default URI
@@ -607,13 +612,13 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
607
 
608
  // 4. Custom URI
609
  if(get_option('page_on_front') == $id) {
610
- $custom_uri_field = Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("type" => "hidden", "extra_atts" => "data-default=\"{$default_uri}\"", "input_class" => "widefat custom_uri", "value" => urldecode($uri)));
611
  $custom_uri_field .= __("The custom URI cannot be edited on frontpage.", "permalink-manager");
612
  } else {
613
- $custom_uri_field = Permalink_Manager_Admin_Functions::generate_option_field("custom_uri", array("extra_atts" => "data-default=\"{$default_uri}\"", "input_class" => "widefat custom_uri", "value" => urldecode($uri)));
614
  }
615
 
616
- $html .= sprintf("<div><label for=\"custom_uri\" class=\"strong\">%s %s</label><span>%s</span></div>",
617
  __("Current URI", "permalink-manager"),
618
  ($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")) : "",
619
  $custom_uri_field
@@ -654,7 +659,8 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
654
  $html .= "</div>";
655
  $html .= "</div>";
656
 
657
- // 9. Append nonce field
 
658
  $html .= wp_nonce_field('permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false);
659
 
660
  return $html;
@@ -745,4 +751,31 @@ class Permalink_Manager_Admin_Functions extends Permalink_Manager_Class {
745
  echo $permalink_manager_before_sections_html;
746
  }
747
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
748
  }
17
  add_action( 'admin_notices', array($this, 'display_global_notices'));
18
  add_action( 'wp_ajax_dismissed_notice_handler', array($this, 'hide_global_notice') );
19
 
20
+ add_filter( 'default_hidden_columns', array($this, 'quick_edit_hide_column'), 10, 2 );
21
+
22
+ add_action( 'wp_ajax_detect_duplicates', array($this, 'ajax_detect_duplicates') );
23
  }
24
 
25
  /**
101
  wp_enqueue_script( 'permalink-manager-plugins', PERMALINK_MANAGER_URL . '/out/permalink-manager-plugins.js', array( 'jquery', ), PERMALINK_MANAGER_VERSION, false );
102
  wp_enqueue_script( 'permalink-manager', PERMALINK_MANAGER_URL . '/out/permalink-manager-admin.js', array( 'jquery', 'permalink-manager-plugins' ), PERMALINK_MANAGER_VERSION, false );
103
 
104
+ wp_localize_script( 'permalink-manager', 'permalink_manager', array('ajax_url' => admin_url('admin-ajax.php'), 'url' => PERMALINK_MANAGER_URL) );
105
+
106
  }
107
 
108
  /**
552
  * "Quick Edit" Box
553
  */
554
  public static function quick_edit_column_form($is_taxonomy = false) {
555
+ $html = self::generate_option_field('permalink-manager-quick-edit', array('value' => true, 'type' => 'hidden'));
556
  $html .= "<fieldset class=\"inline-edit-permalink\">";
557
  $html .= sprintf("<legend class=\"inline-edit-legend\">%s</legend>", __("Permalink Manager", "permalink-manager"));
558
 
559
  $html .= "<div class=\"inline-edit-col\">";
560
  $html .= sprintf("<label class=\"inline-edit-group\"><span class=\"title\">%s</span><span class=\"input-text-wrap\">%s</span></label>",
561
  __("Current URI", "permalink-manager"),
562
+ self::generate_option_field("custom_uri", array("input_class" => "custom_uri", "value" => ''))
563
  );
564
  $html .= "</div>";
565
 
566
  $html .= "</fieldset>";
567
 
568
+ // Append nonce field & element ID
569
+ $html .= Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-edit-uri-element-id", array("type" => "hidden", "input_class" => "permalink-manager-edit-uri-element-id", "value" => ""));
570
  $html .= wp_nonce_field( 'permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false );
571
 
572
  return $html;
579
  global $permalink_manager_options;
580
 
581
  if(!empty($element->ID)) {
582
+ $id = $element_id = $element->ID;
583
 
584
  // Auto-update settings
585
  $auto_update_val = get_post_meta($id, "auto_update_uri", true);
592
  );
593
  } else {
594
  $id = $element->term_id;
595
+ $element_id = "tax-{$id}";
596
  }
597
 
598
  // Decode default URI
612
 
613
  // 4. Custom URI
614
  if(get_option('page_on_front') == $id) {
615
+ $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)));
616
  $custom_uri_field .= __("The custom URI cannot be edited on frontpage.", "permalink-manager");
617
  } else {
618
+ $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)));
619
  }
620
 
621
+ $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>",
622
  __("Current URI", "permalink-manager"),
623
  ($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")) : "",
624
  $custom_uri_field
659
  $html .= "</div>";
660
  $html .= "</div>";
661
 
662
+ // 9. Append nonce field & element ID
663
+ $html .= Permalink_Manager_Admin_Functions::generate_option_field("permalink-manager-edit-uri-element-id", array("type" => "hidden", "value" => $element_id));
664
  $html .= wp_nonce_field('permalink-manager-edit-uri-box', 'permalink-manager-nonce', true, false);
665
 
666
  return $html;
751
  echo $permalink_manager_before_sections_html;
752
  }
753
 
754
+ /**
755
+ * Check if URI was used before
756
+ */
757
+ function ajax_detect_duplicates($uri = null, $element_id = null) {
758
+ $duplicate_alert = __("URI is already in use, please select another one!", "permalink-manager");
759
+
760
+ if(!empty($_REQUEST['custom_uris'])) {
761
+ // Sanitize the array
762
+ $custom_uris = Permalink_Manager_Helper_Functions::sanitize_array($_REQUEST['custom_uris']);
763
+ $duplicates_array = array();
764
+
765
+ // Check each URI
766
+ foreach($custom_uris as $element_id => $uri) {
767
+ $duplicates_array[$element_id] = Permalink_Manager_Helper_Functions::is_uri_duplicated($uri, $element_id) ? $duplicate_alert : 0;
768
+ }
769
+
770
+ // Convert the output to JSON and stop the function
771
+ echo json_encode($duplicates_array);
772
+ } else if(!empty($_REQUEST['custom_uri']) && !empty($_REQUEST['element_id'])) {
773
+ $is_duplicated = Permalink_Manager_Helper_Functions::is_uri_duplicated($uri, $element_id) ? $duplicate_alert : 0;
774
+
775
+ echo $is_duplicated;
776
+ }
777
+
778
+ die();
779
+ }
780
+
781
  }
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -51,10 +51,10 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
51
 
52
  $initial_disabled_post_types = array();
53
 
54
- // Disable post types without permalink settings
55
  if(!empty($wp_rewrite)){
56
  foreach($wp_post_types as $post_type) {
57
- $is_publicly_queryable = (empty($post_type->publicly_queryable) || empty($post_type->public)) ? false : true;
58
 
59
  if(!$is_publicly_queryable && !in_array($post_type->name, array('post', 'page', 'attachment'))) {
60
  $initial_disabled_post_types[] = $post_type->name;
@@ -77,16 +77,16 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
77
  return apply_filters('permalink-manager-disabled-taxonomies', $disabled_taxonomies);
78
  }
79
 
80
- static public function is_disabled($content_name, $content_type = 'post_type') {
81
  $out = false;
82
 
83
  if($content_type == 'post_type') {
84
  $disabled_post_types = self::get_disabled_post_types();
85
- $post_type_exists = get_post_type_object($content_name);
86
  $out = ((is_array($disabled_post_types) && in_array($content_name, $disabled_post_types)) || empty($post_type_exists)) ? true : false;
87
  } else {
88
  $disabled_taxonomies = self::get_disabled_taxonomies();
89
- $taxonomy_exists = taxonomy_exists($content_name);
90
  $out = ((is_array($disabled_taxonomies) && in_array($content_name, $disabled_taxonomies)) || empty($taxonomy_exists)) ? true : false;
91
  }
92
 
51
 
52
  $initial_disabled_post_types = array();
53
 
54
+ // Disable post types that are not publicly_queryable
55
  if(!empty($wp_rewrite)){
56
  foreach($wp_post_types as $post_type) {
57
+ $is_publicly_queryable = (empty($post_type->publicly_queryable) && empty($post_type->public)) ? false : true;
58
 
59
  if(!$is_publicly_queryable && !in_array($post_type->name, array('post', 'page', 'attachment'))) {
60
  $initial_disabled_post_types[] = $post_type->name;
77
  return apply_filters('permalink-manager-disabled-taxonomies', $disabled_taxonomies);
78
  }
79
 
80
+ static public function is_disabled($content_name, $content_type = 'post_type', $check_if_exists = true) {
81
  $out = false;
82
 
83
  if($content_type == 'post_type') {
84
  $disabled_post_types = self::get_disabled_post_types();
85
+ $post_type_exists = ($check_if_exists) ? post_type_exists($content_name) : true;
86
  $out = ((is_array($disabled_post_types) && in_array($content_name, $disabled_post_types)) || empty($post_type_exists)) ? true : false;
87
  } else {
88
  $disabled_taxonomies = self::get_disabled_taxonomies();
89
+ $taxonomy_exists = ($check_if_exists) ? taxonomy_exists($content_name) : true;
90
  $out = ((is_array($disabled_taxonomies) && in_array($content_name, $disabled_taxonomies)) || empty($taxonomy_exists)) ? true : false;
91
  }
92
 
includes/core/permalink-manager-third-parties.php CHANGED
@@ -45,6 +45,16 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
45
  if(class_exists('WooCommerce')) {
46
  add_filter('request', array($this, 'woocommerce_detect'), 9, 1);
47
  add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
 
 
 
 
 
 
 
 
 
 
48
  }
49
 
50
  // 6. Theme My Login
45
  if(class_exists('WooCommerce')) {
46
  add_filter('request', array($this, 'woocommerce_detect'), 9, 1);
47
  add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
48
+
49
+ if(class_exists('WooCommerce') && class_exists('Permalink_Manager_Pro_Functions')) {
50
+ if(is_admin()){
51
+ add_filter('woocommerce_coupon_data_tabs', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_tabs');
52
+ add_action('woocommerce_coupon_data_panels', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_panel');
53
+ add_action('woocommerce_coupon_options_save', 'Permalink_Manager_Pro_Functions::woocommerce_save_coupon_uri', 9, 2);
54
+ }
55
+ add_filter('request', 'Permalink_Manager_Pro_Functions::woocommerce_detect_coupon_code', 1, 1);
56
+ add_filter('permalink-manager-disabled-post-types', 'Permalink_Manager_Pro_Functions::woocommerce_coupon_uris', 9, 1);
57
+ }
58
  }
59
 
60
  // 6. Theme My Login
includes/core/permalink-manager-uri-functions-post.php CHANGED
@@ -36,6 +36,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
36
 
37
  // Add "URI Editor" to "Quick Edit" for all post_types
38
  foreach($post_types as $post_type) {
 
39
  // Check if post type is allowed
40
  if(Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) { continue; }
41
 
@@ -116,8 +117,8 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
116
 
117
  // Check if input is post object
118
  $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
119
-
120
  $final_uri = (!empty($permalink_manager_uris[$post_id])) ? $permalink_manager_uris[$post_id] : self::get_default_post_uri($post_id, $native_uri);
 
121
  return $final_uri;
122
  }
123
 
@@ -509,7 +510,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
509
  $native_uri = self::get_default_post_uri($id, true);
510
  $default_uri = self::get_default_post_uri($id);
511
 
512
- $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : $native_uri;
513
 
514
  // Process new values - empty entries will be treated as default values
515
  $new_uri = preg_replace('/\s+/', '', $new_uri);
@@ -548,9 +549,6 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
548
  // Detect auto drafts
549
  $autosave = (!empty($new_title) && empty($new_slug)) ? true : false;
550
 
551
- // Do not do anything if new slug is empty or page is front-page
552
- // if(get_option('page_on_front') == $id) { return $html; }
553
-
554
  // Check if post type is disabled
555
  if(Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $html; }
556
 
@@ -582,7 +580,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
582
 
583
  // Append new HTML output
584
  $html .= sprintf("<span class=\"sample-permalink-span\"><a href=\"%s\">%s</a></span>&nbsp;", strip_tags($sample_permalink), $sample_permalink);
585
- $html .= Permalink_Manager_Admin_Functions::display_uri_box($post, $default_uri, $uri, $native_uri, "{$home_url}{$prefix}");
586
 
587
  // Append hidden field with native slug
588
  $html .= (!empty($post->post_name)) ? "<input id=\"new-post-slug\" value=\"{$post->post_name}\" autocomplete=\"off\" type=\"hidden\">" : "";
@@ -598,8 +596,10 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
598
  }
599
 
600
  function quick_edit_column_content($column_name, $post_id) {
 
 
601
  if($column_name == "permalink-manager-col") {
602
- echo urldecode(self::get_post_uri($post_id));
603
  }
604
  }
605
 
@@ -659,8 +659,11 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
659
  // Do not do anything on in "Bulk Edit"
660
  if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
661
 
662
- // Do not do anything if the field with URI is not present
663
- if(!isset($_POST['custom_uri'])) { return $post_id; }
 
 
 
664
 
665
  // Fix for revisions
666
  $is_revision = wp_is_post_revision($post_id);
36
 
37
  // Add "URI Editor" to "Quick Edit" for all post_types
38
  foreach($post_types as $post_type) {
39
+
40
  // Check if post type is allowed
41
  if(Permalink_Manager_Helper_Functions::is_disabled($post_type, 'post_type')) { continue; }
42
 
117
 
118
  // Check if input is post object
119
  $post_id = (isset($post_id->ID)) ? $post_id->ID : $post_id;
 
120
  $final_uri = (!empty($permalink_manager_uris[$post_id])) ? $permalink_manager_uris[$post_id] : self::get_default_post_uri($post_id, $native_uri);
121
+
122
  return $final_uri;
123
  }
124
 
510
  $native_uri = self::get_default_post_uri($id, true);
511
  $default_uri = self::get_default_post_uri($id);
512
 
513
+ $old_uri = isset($old_uris[$id]) ? trim($old_uris[$id], "/") : "";
514
 
515
  // Process new values - empty entries will be treated as default values
516
  $new_uri = preg_replace('/\s+/', '', $new_uri);
549
  // Detect auto drafts
550
  $autosave = (!empty($new_title) && empty($new_slug)) ? true : false;
551
 
 
 
 
552
  // Check if post type is disabled
553
  if(Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $html; }
554
 
580
 
581
  // Append new HTML output
582
  $html .= sprintf("<span class=\"sample-permalink-span\"><a href=\"%s\">%s</a></span>&nbsp;", strip_tags($sample_permalink), $sample_permalink);
583
+ $html .= (!$autosave) ? Permalink_Manager_Admin_Functions::display_uri_box($post, $default_uri, $uri, $native_uri, "{$home_url}{$prefix}") : "";
584
 
585
  // Append hidden field with native slug
586
  $html .= (!empty($post->post_name)) ? "<input id=\"new-post-slug\" value=\"{$post->post_name}\" autocomplete=\"off\" type=\"hidden\">" : "";
596
  }
597
 
598
  function quick_edit_column_content($column_name, $post_id) {
599
+ global $permalink_manager_uris;
600
+
601
  if($column_name == "permalink-manager-col") {
602
+ echo (!empty($permalink_manager_uris[$post_id])) ? urldecode($permalink_manager_uris[$post_id]) : '';
603
  }
604
  }
605
 
659
  // Do not do anything on in "Bulk Edit"
660
  if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
661
 
662
+ // Do not do anything if the field with URI or element ID are not present
663
+ if(!isset($_POST['custom_uri']) || empty($_POST['permalink-manager-edit-uri-element-id'])) { return $post_id; }
664
+
665
+ // Hotfix
666
+ if($_POST['permalink-manager-edit-uri-element-id'] != $post_id) { return $post_id; }
667
 
668
  // Fix for revisions
669
  $is_revision = wp_is_post_revision($post_id);
includes/views/permalink-manager-tools.php CHANGED
@@ -66,16 +66,18 @@ class Permalink_Manager_Tools extends Permalink_Manager_Class {
66
  // Detect duplicate type
67
  preg_match("/(redirect-([\d]+)_)?(?:(tax-)?([\d]*))/", $item_id, $parts);
68
 
69
- $redirect_type = (!empty($parts[1])) ? __('Extra Redirect', 'permalink-manager') : __('Custom URI', 'permalink-manager');
 
70
  $detected_id = $parts[4];
71
  $detected_index = $parts[2];
72
  $detected_term = (!empty($parts[3])) ? true : false;
 
73
 
74
  // Get term
75
  if($detected_term && !empty($detected_id)) {
76
  $term = get_term($detected_id);
77
  if(!empty($term->name)) {
78
- $title = $post->post_title;
79
  $edit_label = "<span class=\"dashicons dashicons-edit\"></span>" . __("Edit term", "permalink-manager");
80
  $edit_link = get_edit_tag_link($term->term_id, $term->taxonomy);
81
  } else {
@@ -87,7 +89,7 @@ class Permalink_Manager_Tools extends Permalink_Manager_Class {
87
  // Get post
88
  else if(!empty($detected_id)) {
89
  $post = get_post($detected_id);
90
- if(!empty($post->post_title)) {
91
  $title = $post->post_title;
92
  $edit_label = "<span class=\"dashicons dashicons-edit\"></span>" . __("Edit post", "permalink-manager");
93
  $edit_link = get_edit_post_link($post->ID);
@@ -101,13 +103,13 @@ class Permalink_Manager_Tools extends Permalink_Manager_Class {
101
  }
102
 
103
  $html .= sprintf(
104
- //'<td><a href="%1$s" target="_blank">%2$s</a>%3$s</td><td>%4$s</td><td class="actions"><a href="%1$s" target="_blank"><span class="dashicons dashicons-edit"></span> %5$s</a> | <a class="remove-duplicate-link" href="%6$s"><span class="dashicons dashicons-trash"></span> %7$s</a></td>',
105
- '<td><a href="%1$s" target="_blank">%2$s</a>%3$s</td><td>%4$s</td><td class="actions"><a href="%1$s" target="_blank">%5$s</a></td>',
106
  $edit_link,
107
  $title,
108
  " <small>#{$detected_id}</small>",
109
- $redirect_type,
110
- $edit_label
 
111
  );
112
  $html .= "</tr>";
113
  }
66
  // Detect duplicate type
67
  preg_match("/(redirect-([\d]+)_)?(?:(tax-)?([\d]*))/", $item_id, $parts);
68
 
69
+ $is_extra_redirect = (!empty($parts[1])) ? true : false;
70
+ $duplicate_type = ($is_extra_redirect) ? __('Extra Redirect', 'permalink-manager') : __('Custom URI', 'permalink-manager');
71
  $detected_id = $parts[4];
72
  $detected_index = $parts[2];
73
  $detected_term = (!empty($parts[3])) ? true : false;
74
+ $remove_link = ($is_extra_redirect) ? sprintf(" <a href=\"%s\"><span class=\"dashicons dashicons-trash\"></span> %s</a>", admin_url("tools.php?page=permalink-manager&section=tools&subsection=duplicates&remove-redirect={$item_id}"), __("Remove Redirect")) : "";
75
 
76
  // Get term
77
  if($detected_term && !empty($detected_id)) {
78
  $term = get_term($detected_id);
79
  if(!empty($term->name)) {
80
+ $title = $term->name;
81
  $edit_label = "<span class=\"dashicons dashicons-edit\"></span>" . __("Edit term", "permalink-manager");
82
  $edit_link = get_edit_tag_link($term->term_id, $term->taxonomy);
83
  } else {
89
  // Get post
90
  else if(!empty($detected_id)) {
91
  $post = get_post($detected_id);
92
+ if(!empty($post->post_title) && post_type_exists($post->post_type)) {
93
  $title = $post->post_title;
94
  $edit_label = "<span class=\"dashicons dashicons-edit\"></span>" . __("Edit post", "permalink-manager");
95
  $edit_link = get_edit_post_link($post->ID);
103
  }
104
 
105
  $html .= sprintf(
106
+ '<td><a href="%1$s">%2$s</a>%3$s</td><td>%4$s</td><td class="actions"><a href="%1$s" target="_blank">%5$s</a>%6$s</td>',
 
107
  $edit_link,
108
  $title,
109
  " <small>#{$detected_id}</small>",
110
+ $duplicate_type,
111
+ $edit_label,
112
+ $remove_link
113
  );
114
  $html .= "</tr>";
115
  }
includes/views/permalink-manager-uri-editor-post.php CHANGED
@@ -81,7 +81,7 @@ class Permalink_Manager_URI_Editor_Post extends WP_List_Table {
81
  $uri = Permalink_Manager_URI_Functions_Post::get_post_uri($item['ID'], true);
82
  $uri = (!empty($permalink_manager_options['general']['decode_uris'])) ? urldecode($uri) : $uri;
83
 
84
- $field_args_base = array('type' => 'text', 'value' => $uri, 'without_label' => true, 'input_class' => '');
85
  $permalink = get_permalink($item['ID']);
86
  $post_statuses_array = get_post_statuses();
87
 
@@ -90,8 +90,11 @@ class Permalink_Manager_URI_Editor_Post extends WP_List_Table {
90
 
91
  switch( $column_name ) {
92
  case 'item_uri':
93
- $output = Permalink_Manager_Admin_Functions::generate_option_field("uri[{$item['ID']}]", $field_args_base);
 
 
94
  $output .= sprintf("<a class=\"small post_permalink\" href=\"%s\" target=\"_blank\"><span class=\"dashicons dashicons-admin-links\"></span> %s</a>", $permalink, urldecode($permalink));
 
95
  return $output;
96
 
97
  case 'item_title':
81
  $uri = Permalink_Manager_URI_Functions_Post::get_post_uri($item['ID'], true);
82
  $uri = (!empty($permalink_manager_options['general']['decode_uris'])) ? urldecode($uri) : $uri;
83
 
84
+ $field_args_base = array('type' => 'text', 'value' => $uri, 'without_label' => true, 'input_class' => 'custom_uri', 'extra_atts' => "data-element-id=\"{$item['ID']}\"");
85
  $permalink = get_permalink($item['ID']);
86
  $post_statuses_array = get_post_statuses();
87
 
90
 
91
  switch( $column_name ) {
92
  case 'item_uri':
93
+ $output = '<div class="custom_uri_container">';
94
+ $output .= Permalink_Manager_Admin_Functions::generate_option_field("uri[{$item['ID']}]", $field_args_base);
95
+ $output .= "<span class=\"duplicated_uri_alert\"></span>";
96
  $output .= sprintf("<a class=\"small post_permalink\" href=\"%s\" target=\"_blank\"><span class=\"dashicons dashicons-admin-links\"></span> %s</a>", $permalink, urldecode($permalink));
97
+ $output .= '</div>';
98
  return $output;
99
 
100
  case 'item_title':
out/permalink-manager-admin.css CHANGED
@@ -50,6 +50,7 @@
50
  #permalink-manager .section-notes ol li:last-of-type{margin-bottom:0}
51
  #permalink-manager .short-pre,#permalink-manager .short-textarea{height:150px;overflow:auto;max-width:100%;display:block}
52
  #permalink-manager .structure-tags-list{margin-top:15px}
 
53
 
54
  #permalink-manager .checkbox_actions{padding-top:10px;border-top:1px solid #ddd}
55
  #permalink-manager .extra-links,.permalink-manager-screen-options .extra-links{margin-top:5px;font-size:12px}
@@ -132,6 +133,11 @@
132
  .permalink-manager .redirects-panel-description{margin-bottom:10px}
133
  .permalink-manager .redirects-panel-description *{font-size:12px}
134
 
 
 
 
 
 
135
  /**
136
  * Tippy.js custom theme
137
  */
50
  #permalink-manager .section-notes ol li:last-of-type{margin-bottom:0}
51
  #permalink-manager .short-pre,#permalink-manager .short-textarea{height:150px;overflow:auto;max-width:100%;display:block}
52
  #permalink-manager .structure-tags-list{margin-top:15px}
53
+ #permalink-manager .duplicated_uri_alert,.permalink-manager .duplicated_uri_alert{display:block;font-weight:bold;font-size:90%;margin-top:8px;color:#dc3232}
54
 
55
  #permalink-manager .checkbox_actions{padding-top:10px;border-top:1px solid #ddd}
56
  #permalink-manager .extra-links,.permalink-manager-screen-options .extra-links{margin-top:5px;font-size:12px}
133
  .permalink-manager .redirects-panel-description{margin-bottom:10px}
134
  .permalink-manager .redirects-panel-description *{font-size:12px}
135
 
136
+ /**
137
+ * Coupon panel
138
+ */
139
+ #permalink-manager-coupon-url > p:last-of-type{font-size:13px}
140
+
141
  /**
142
  * Tippy.js custom theme
143
  */
out/permalink-manager-admin.js CHANGED
@@ -5,7 +5,7 @@ jQuery(document).ready(function() {
5
  */
6
  var checkbox_actions = ['select_all', 'unselect_all'];
7
  checkbox_actions.forEach(function(element) {
8
- jQuery('.' + element).on('click', function() {
9
  jQuery(this).parents('.field-container').find('.checkboxes input[type="checkbox"]').each(function() {
10
  var action = (element == 'select_all') ? true : false;
11
  jQuery(this).prop('checked', action);
@@ -15,7 +15,7 @@ jQuery(document).ready(function() {
15
  });
16
  });
17
 
18
- jQuery('.checkboxes label').not('input').on('click', function(ev) {
19
  var input = jQuery(this).find("input");
20
  if(!jQuery(ev.target).is("input")) {
21
  input.prop('checked', !(input.prop("checked")));
@@ -25,7 +25,7 @@ jQuery(document).ready(function() {
25
  /**
26
  * Filter by dates in "Permalink editor"
27
  */
28
- jQuery('#months-filter-button').on('click', function() {
29
  var filter_name = jQuery("#months-filter-select").attr('name');
30
  var filter_value = jQuery("#months-filter-select").val();
31
  var url = jQuery(this).parent().data('filter-url');
@@ -39,7 +39,7 @@ jQuery(document).ready(function() {
39
  /**
40
  * Filter by content types in "Tools"
41
  */
42
- jQuery('*[data-field="content_type"] select').on('change', function() {
43
  var content_type = jQuery(this).val();
44
  if(content_type == 'post_types') {
45
  jQuery(this).parents('.form-table').find('*[data-field="post_types"],*[data-field="post_statuses"]').removeClass('hidden');
@@ -98,6 +98,88 @@ jQuery(document).ready(function() {
98
  jQuery('.sample-permalink-span .editable').text(jQuery(this).val());
99
  });
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  /**
102
  * Disable "Edit URI" input if URI should be updated automatically
103
  */
@@ -115,7 +197,7 @@ jQuery(document).ready(function() {
115
  /**
116
  * Restore "Default URI"
117
  */
118
- jQuery('.restore-default').on('click', function() {
119
  var input = jQuery(this).parents('.field-container, .permalink-manager-edit-uri-box').find('input[data-default]');
120
  jQuery(input).val(jQuery(input).data('default')).trigger('keyup');
121
  return false;
@@ -127,7 +209,7 @@ jQuery(document).ready(function() {
127
  jQuery(document).on('click', '.permalink-manager-notice.is-dismissible .notice-dismiss', function() {
128
  var alert_id = jQuery(this).closest('.permalink-manager-notice').data('alert_id');
129
 
130
- jQuery.ajax(ajaxurl, {
131
  type: 'POST',
132
  data: {
133
  action: 'dismissed_notice_handler',
@@ -139,7 +221,7 @@ jQuery(document).ready(function() {
139
  /**
140
  * Help tooltips
141
  */
142
- new Tippy('.help_tooltip', {
143
  position: 'top-start',
144
  arrow: true,
145
  theme: 'tippy-pm',
@@ -149,7 +231,7 @@ jQuery(document).ready(function() {
149
  /**
150
  * Stop-words
151
  */
152
- var stop_words_input = '.field-container textarea.stop_words';
153
 
154
  if(jQuery(stop_words_input).length > 0) {
155
  var stop_words = new TIB(document.querySelector(stop_words_input), {
@@ -165,12 +247,12 @@ jQuery(document).ready(function() {
165
  };
166
 
167
  // Remove all words
168
- jQuery('.field-container .clear_all_words').on('click', function() {
169
  stop_words.reset();
170
  });
171
 
172
  // Load stop-words list
173
- jQuery('#load_stop_words_button').on('click', function() {
174
  var lang = jQuery( ".load_stop_words option:selected" ).val();
175
  if(lang) {
176
  var json_url = permalink_manager.url + "/includes/ext/stopwords-json/dist/" + lang + ".json";
@@ -214,6 +296,9 @@ jQuery(document).ready(function() {
214
 
215
  // Fill with the Custom URI
216
  custom_uri_field.val(custom_uri);
 
 
 
217
  }
218
  }
219
  }
@@ -238,6 +323,9 @@ jQuery(document).ready(function() {
238
 
239
  // Fill with the Custom URI
240
  custom_uri_field.val(custom_uri);
 
 
 
241
  }
242
  }
243
  }
5
  */
6
  var checkbox_actions = ['select_all', 'unselect_all'];
7
  checkbox_actions.forEach(function(element) {
8
+ jQuery('#permalink-manager .' + element).on('click', function() {
9
  jQuery(this).parents('.field-container').find('.checkboxes input[type="checkbox"]').each(function() {
10
  var action = (element == 'select_all') ? true : false;
11
  jQuery(this).prop('checked', action);
15
  });
16
  });
17
 
18
+ jQuery('#permalink-manager .checkboxes label').not('input').on('click', function(ev) {
19
  var input = jQuery(this).find("input");
20
  if(!jQuery(ev.target).is("input")) {
21
  input.prop('checked', !(input.prop("checked")));
25
  /**
26
  * Filter by dates in "Permalink editor"
27
  */
28
+ jQuery('#permalink-manager #months-filter-button').on('click', function() {
29
  var filter_name = jQuery("#months-filter-select").attr('name');
30
  var filter_value = jQuery("#months-filter-select").val();
31
  var url = jQuery(this).parent().data('filter-url');
39
  /**
40
  * Filter by content types in "Tools"
41
  */
42
+ jQuery('#permalink-manager *[data-field="content_type"] select').on('change', function() {
43
  var content_type = jQuery(this).val();
44
  if(content_type == 'post_types') {
45
  jQuery(this).parents('.form-table').find('*[data-field="post_types"],*[data-field="post_statuses"]').removeClass('hidden');
98
  jQuery('.sample-permalink-span .editable').text(jQuery(this).val());
99
  });
100
 
101
+ /**
102
+ * Synchronize "Coupon URI" input field with the final permalink
103
+ */
104
+ jQuery('#permalink-manager-coupon-url input[name="custom_uri"]').on('keyup change', function() {
105
+ var uri = jQuery(this).val();
106
+ jQuery('#permalink-manager-coupon-url code span').text(uri);
107
+
108
+ if(!uri) {
109
+ jQuery('#permalink-manager-coupon-url .coupon-full-url').addClass("hidden");
110
+ } else {
111
+ jQuery('#permalink-manager-coupon-url .coupon-full-url').removeClass("hidden");
112
+ }
113
+ });
114
+
115
+ function permalink_manager_duplicate_check(custom_uri_input = false, multi = false) {
116
+ var all_custom_uris_values = {};
117
+
118
+ if(custom_uri_input) {
119
+ var custom_uri = jQuery(custom_uri_input).val();
120
+ var element_id = jQuery(custom_uri_input).attr("data-element-id");
121
+
122
+ all_custom_uris_values[element_id] = custom_uri;
123
+ } else {
124
+ jQuery('.custom_uri').each(function(i, obj) {
125
+ var field_name = jQuery(obj).attr('data-element-id');
126
+ all_custom_uris_values[field_name] = jQuery(obj).val();
127
+ });
128
+ }
129
+
130
+ if(all_custom_uris_values) {
131
+ jQuery.ajax(permalink_manager.ajax_url, {
132
+ type: 'POST',
133
+ async: true,
134
+ data: {
135
+ action: 'detect_duplicates',
136
+ custom_uris: all_custom_uris_values
137
+ },
138
+ success: function(data) {
139
+ if(data.length > 5) {
140
+ var results = JSON.parse(data);
141
+
142
+ // Loop through results
143
+ jQuery.each(results, function(key, is_duplicate) {
144
+ var alert_container = jQuery('.custom_uri[data-element-id="' + key + '"]').parents('.custom_uri_container').find('.duplicated_uri_alert');
145
+
146
+ if(is_duplicate) {
147
+ jQuery(alert_container).text(is_duplicate);
148
+ } else {
149
+ jQuery(alert_container).empty();
150
+ }
151
+ });
152
+ }
153
+ }
154
+ });
155
+ }
156
+ }
157
+
158
+ /**
159
+ * Check if a single custom URI is not duplicated
160
+ */
161
+ var custom_uri_check_timeout = null;
162
+ jQuery('.custom_uri_container input[name="custom_uri"], .custom_uri_container input.custom_uri').each(function() {
163
+ var input = this;
164
+
165
+ jQuery(this).on('keyup change', function() {
166
+ clearTimeout(custom_uri_check_timeout);
167
+
168
+ // Wait until user finishes typing
169
+ custom_uri_check_timeout = setTimeout(function() {
170
+ permalink_manager_duplicate_check(input);
171
+ }, 500);
172
+ });
173
+
174
+ });
175
+
176
+ /**
177
+ * Check if a all any of displayed custom URIs is not duplicated
178
+ */
179
+ if(jQuery('.custom_uri').length > 0) {
180
+ permalink_manager_duplicate_check(false, true);
181
+ }
182
+
183
  /**
184
  * Disable "Edit URI" input if URI should be updated automatically
185
  */
197
  /**
198
  * Restore "Default URI"
199
  */
200
+ jQuery('#permalink-manager .restore-default').on('click', function() {
201
  var input = jQuery(this).parents('.field-container, .permalink-manager-edit-uri-box').find('input[data-default]');
202
  jQuery(input).val(jQuery(input).data('default')).trigger('keyup');
203
  return false;
209
  jQuery(document).on('click', '.permalink-manager-notice.is-dismissible .notice-dismiss', function() {
210
  var alert_id = jQuery(this).closest('.permalink-manager-notice').data('alert_id');
211
 
212
+ jQuery.ajax(permalink_manager.ajax_url, {
213
  type: 'POST',
214
  data: {
215
  action: 'dismissed_notice_handler',
221
  /**
222
  * Help tooltips
223
  */
224
+ new Tippy('#permalink-manager .help_tooltip', {
225
  position: 'top-start',
226
  arrow: true,
227
  theme: 'tippy-pm',
231
  /**
232
  * Stop-words
233
  */
234
+ var stop_words_input = '#permalink-manager .field-container textarea.stop_words';
235
 
236
  if(jQuery(stop_words_input).length > 0) {
237
  var stop_words = new TIB(document.querySelector(stop_words_input), {
247
  };
248
 
249
  // Remove all words
250
+ jQuery('#permalink-manager .field-container .clear_all_words').on('click', function() {
251
  stop_words.reset();
252
  });
253
 
254
  // Load stop-words list
255
+ jQuery('#permalink-manager #load_stop_words_button').on('click', function() {
256
  var lang = jQuery( ".load_stop_words option:selected" ).val();
257
  if(lang) {
258
  var json_url = permalink_manager.url + "/includes/ext/stopwords-json/dist/" + lang + ".json";
296
 
297
  // Fill with the Custom URI
298
  custom_uri_field.val(custom_uri);
299
+
300
+ // Set the element ID
301
+ jQuery('#edit-' + post_id).find('.permalink-manager-edit-uri-element-id').val(post_id);
302
  }
303
  }
304
  }
323
 
324
  // Fill with the Custom URI
325
  custom_uri_field.val(custom_uri);
326
+
327
+ // Set the element ID
328
+ jQuery('#edit-' + term_id).find('.permalink-manager-edit-uri-element-id').val("tax-" + term_id);
329
  }
330
  }
331
  }
permalink-manager.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
 
3
  /**
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.0.5.4
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.0.5.4' );
25
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
26
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
27
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
@@ -153,7 +153,7 @@ class Permalink_Manager_Class {
153
  'redirect' => '301',
154
  'canonical_redirect' => 1,
155
  'trailing_slashes' => 0,
156
- 'pagination_redirect' => 1,
157
  'auto_remove_duplicates' => 0,
158
  'partial_disable' => array(),
159
  'deep_detect' => 1
@@ -178,15 +178,15 @@ class Permalink_Manager_Class {
178
  */
179
  public function default_alerts($alerts) {
180
  $default_alerts = apply_filters('permalink-manager-default-alerts', array(
181
- '01.2018' => array(
182
  'txt' => sprintf(
183
- __("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 20&#37; using \"NEWYEAR\" coupon code!</strong> Valid until 31.01!", "permalink-manager"),
184
  PERMALINK_MANAGER_WEBSITE
185
  ),
186
  'type' => 'notice-info',
187
  'show' => 'pro_hide',
188
  'plugin_only' => true,
189
- 'until' => '2018-01-31'
190
  )
191
  ));
192
 
1
  <?php
2
 
3
  /**
4
+ * Plugin Name: Permalink Manager Pro
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.0.5.5
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.0.5.5' );
25
  define( 'PERMALINK_MANAGER_FILE', __FILE__ );
26
  define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
27
  define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
153
  'redirect' => '301',
154
  'canonical_redirect' => 1,
155
  'trailing_slashes' => 0,
156
+ 'pagination_redirect' => 0,
157
  'auto_remove_duplicates' => 0,
158
  'partial_disable' => array(),
159
  'deep_detect' => 1
178
  */
179
  public function default_alerts($alerts) {
180
  $default_alerts = apply_filters('permalink-manager-default-alerts', array(
181
+ 'october' => array(
182
  'txt' => sprintf(
183
+ __("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 20&#37; using \"OCTOBER\" coupon code!</strong> Valid until 31.10!", "permalink-manager"),
184
  PERMALINK_MANAGER_WEBSITE
185
  ),
186
  'type' => 'notice-info',
187
  'show' => 'pro_hide',
188
  'plugin_only' => true,
189
+ 'until' => '2017-10-31'
190
  )
191
  ));
192