Permalink Manager Lite - Version 2.0.5.2

Version Description

Download this release

Release Info

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

Code changes from version 2.0.5.1 to 2.0.5.2

README.txt CHANGED
@@ -4,10 +4,10 @@ Donate link: https://www.paypal.me/Bismit
4
  License: GPLv3
5
  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.0
8
  Requires PHP: 5.4
9
  Tested up to: 4.9
10
- Stable tag: 2.0.5.1
11
 
12
  Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
13
 
@@ -98,8 +98,14 @@ A. Currently there is no 100% guarantee that Permalink Manager will work correct
98
 
99
  == Changelog ==
100
 
101
- = 2.0.5.1 =
102
  * Hotfix for REGEX rule
 
 
 
 
 
 
103
 
104
  = 2.0.5 =
105
  * Now, the duplicates and unused custom permalinks can be automatically removed
@@ -107,10 +113,7 @@ A. Currently there is no 100% guarantee that Permalink Manager will work correct
107
  * "Disable slug appendix" field is no longer needed
108
  * %{taxonomy}_flat% tag enhanced for post types permastructures
109
  * Fix for WPML language prefixes in REGEX rule used to detect URIs
110
- * Possibility to disable Permalink Manager functions for particular post types or taxonomies
111
-
112
- = 2.0.5 =
113
- * Hotfix for Yoast's SEO attachment redirect
114
 
115
  = 2.0.4.3 =
116
  * Hotfix for problem with custom URIs for new terms & posts
4
  License: GPLv3
5
  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.0
8
  Requires PHP: 5.4
9
  Tested up to: 4.9
10
+ Stable tag: 2.0.5.2
11
 
12
  Advanced plugin that allows to set-up custom permalinks (bulk editors included), slugs and permastructures (WooCommerce compatible).
13
 
98
 
99
  == Changelog ==
100
 
101
+ = 2.0.5.1/2.0.5.2 =
102
  * Hotfix for REGEX rule
103
+ * yoast_attachment_redirect setting removed (it is no longer needed)
104
+ * yoast_primary_term setting replaced with "permalink-manager-primary-term" filter
105
+ * Hotfix for WP All Import
106
+ * Hotfix for WooCommerce endpoints
107
+ * Better support for Polylang
108
+ * Support for Theme My Login plugin
109
 
110
  = 2.0.5 =
111
  * Now, the duplicates and unused custom permalinks can be automatically removed
113
  * "Disable slug appendix" field is no longer needed
114
  * %{taxonomy}_flat% tag enhanced for post types permastructures
115
  * Fix for WPML language prefixes in REGEX rule used to detect URIs
116
+ * Possibility to disable Permalink Manager functions for particular post types or taxonomies
 
 
 
117
 
118
  = 2.0.4.3 =
119
  * Hotfix for problem with custom URIs for new terms & posts
includes/core/permalink-manager-core-functions.php CHANGED
@@ -10,22 +10,24 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
10
  }
11
 
12
  function init_hooks() {
13
- // Use the URIs set in this plugin + redirect from old URIs to new URIs + adjust canonical redirect settings
14
- add_filter( 'request', array($this, 'detect_post'), 0, 1 );
15
-
16
- // Trailing slashes
17
- add_filter( 'permalink_manager_filter_final_term_permalink', array($this, 'control_trailing_slashes'), 9);
18
- add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
19
- add_filter( 'permalink_manager_filter_post_sample_permalink', array($this, 'control_trailing_slashes'), 9);
20
-
21
- // Redirects
22
- add_filter( 'redirect_canonical', array($this, 'fix_canonical_redirect'), 9, 2);
23
- add_action( 'template_redirect', array($this, 'redirect_to_new_uri'), 0);
24
- add_action( 'parse_request', array($this, 'disable_canonical_redirect'), 0, 1);
25
-
26
- // Case insensitive permalinks
27
- add_action( 'parse_request', array($this, 'case_insensitive_permalinks'), 0);
28
- add_action( 'parse_request', array($this, 'fix_pagination_pages'), 0);
 
 
29
  }
30
 
31
  /**
@@ -34,35 +36,32 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
34
  function detect_post($query) {
35
  global $wpdb, $wp, $wp_rewrite, $permalink_manager_uris, $wp_filter, $permalink_manager_options, $pm_item_id;
36
 
37
- // Check if any custom URI is used
38
  if(!(is_array($permalink_manager_uris)) || empty($query)) return $query;
39
 
40
  // Used in debug mode & endpoints
41
  $old_query = $query;
42
 
43
  /**
44
- * 1. Prepare URL and check if it is correct
45
  */
46
- $protocol = stripos($_SERVER['SERVER_PROTOCOL'], 'https') === true ? 'https://' : 'http://';
47
- $request_url = "{$protocol}{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}";
48
- $home_url = trim(rtrim(get_option('home'), '/'));
49
- $home_url = ($protocol == 'https://') ? str_replace("http://", "https://", $home_url) : str_replace("https://", "http://", $home_url); // Adjust prefix (it should be the same in both request & home_url)
50
 
51
  if(filter_var($request_url, FILTER_VALIDATE_URL)) {
52
  // Check if "Deep Detect" is enabled
53
  $deep_detect_enabled = apply_filters('permalink-manager-deep-uri-detect', $permalink_manager_options['general']['deep_detect']);
54
 
55
- // Remove .html suffix and domain name from URL and query (URLs ended with .html will work as aliases)
56
  $request_url = trim(str_replace($home_url, "", $request_url), "/");
57
 
58
- // Remove querystrings from URI
59
- $request_url = urldecode(strtok($request_url, '?'));
60
-
61
- // Get all the endpoints
62
  $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
 
63
 
64
  // Use default REGEX to detect post
65
- preg_match("/^(.+?)(?|\/({$endpoints})\/([^\/]+)|()\/([\d+]))?\/?$/i", $request_url, $regex_parts);
66
  $uri_parts['lang'] = false;
67
  $uri_parts['uri'] = (!empty($regex_parts[1])) ? $regex_parts[1] : "";
68
  $uri_parts['endpoint'] = (!empty($regex_parts[2])) ? $regex_parts[2] : "";
@@ -84,10 +83,10 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
84
  $uri = trim($uri, "/");
85
 
86
  // Decode both Request URI & URIs array
87
- /*$uri = urldecode($uri);
88
  foreach ($permalink_manager_uris as $key => $value) {
89
  $permalink_manager_uris[$key] = urldecode($value);
90
- }*/
91
 
92
  // Ignore URLs with no URI grabbed
93
  if(empty($uri)) return $query;
@@ -156,8 +155,6 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
156
  }
157
  }
158
 
159
- // Make the redirects more clever - see redirect_to_new_uri() method
160
- $query['do_not_redirect'] = 1;
161
  $query[$query_parameter] = $final_uri;
162
  } else {
163
  $broken_uri = true;
@@ -194,27 +191,28 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
194
  }
195
 
196
  // Alter query parameters
197
- if($post_to_load->post_type == 'page') {
198
  $query['pagename'] = $final_uri;
199
- } else if($post_to_load->post_type == 'post') {
200
  $query['name'] = $final_uri;
201
- } else if($post_to_load->post_type == 'attachment') {
202
  $query['attachment'] = $final_uri;
203
  } else {
 
 
 
 
204
  $query['name'] = $final_uri;
205
  $query['post_type'] = $post_type;
206
- $query[$post_type] = $final_uri;
207
  }
208
-
209
- // Make the redirects more clever - see redirect_to_new_uri() method
210
- $query['do_not_redirect'] = 1;
211
  } else {
212
  $broken_uri = true;
213
  }
214
  }
215
 
216
  /**
217
- * 2C. Auto-remove removed term custom URI & redirects (works if enabled in plugin settings)
218
  */
219
  if(!empty($broken_uri) && !empty($permalink_manager_options['general']['auto_remove_duplicates'])) {
220
  $remove_broken_uri = Permalink_Manager_Actions::clear_single_element_uris_and_redirects($element_id);
@@ -227,7 +225,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
227
  }
228
 
229
  /**
230
- * 2D. Endpoints
231
  */
232
  if($element_id && (!empty($endpoint)) || !empty($endpoint_value)) {
233
  $endpoint = ($endpoint) ? str_replace(array('page', 'trackback'), array('paged', 'tb'), $endpoint) : "page";
@@ -239,10 +237,15 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
239
  } else {
240
  $query[$endpoint] = $endpoint_value;
241
  }
 
 
 
 
 
242
  }
243
 
244
  /**
245
- * 2D Endpoints - check if any endpoint is set with $_GET parameter
246
  */
247
  if($deep_detect_enabled && !empty($_GET)) {
248
  $get_endpoints = array_intersect($wp->public_query_vars, array_keys($_GET));
@@ -258,17 +261,33 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
258
  }
259
 
260
  /**
261
- * Global with detected item id
 
 
 
 
 
 
 
 
 
 
262
  */
263
  if(!empty($element_id)) {
264
  $pm_item_id = $element_id;
 
 
 
265
  }
266
  }
267
 
268
- // Debug mode
 
 
269
  if(isset($_REQUEST['debug_url'])) {
270
  $debug_info['old_query_vars'] = $old_query;
271
  $debug_info['new_query_vars'] = $query;
 
272
 
273
  $debug_txt = json_encode($debug_info);
274
  $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
@@ -286,9 +305,9 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
286
 
287
  $trailing_slash_setting = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : "";
288
 
289
- if($trailing_slash_setting == 1) {
290
  $permalink = trailingslashit($permalink);
291
- } else if($trailing_slash_setting > 1) {
292
  $permalink = untrailingslashit($permalink);
293
  }
294
 
@@ -323,12 +342,17 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
323
  /**
324
  * Redirects
325
  */
326
- function redirect_to_new_uri() {
327
- global $wp_query, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wp;
328
 
329
  // Do not redirect on author pages & front page
330
  if(is_author() || is_front_page() || is_home()) { return false; }
331
 
 
 
 
 
 
332
  // Sometimes $wp_query indicates the wrong object if requested directly
333
  $queried_object = get_queried_object();
334
 
@@ -339,6 +363,9 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
339
  // Get query string
340
  $query_string = $_SERVER['QUERY_STRING'];
341
 
 
 
 
342
  /**
343
  * 1A. Custom redirects
344
  */
@@ -385,7 +412,7 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
385
  $correct_permalink = get_permalink($queried_object->ID);
386
  }
387
  // Affect only terms with custom URI and old URIs
388
- else if(!empty($queried_object->term_id) && isset($permalink_manager_uris["tax-{$queried_object->term_id}"])) {
389
  // Check if taxonomy is allowed
390
  if(Permalink_Manager_Helper_Functions::is_disabled($queried_object->taxonomy, "taxonomy")) { return ''; }
391
 
@@ -398,19 +425,23 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
398
  * 2. Check trailing slashes
399
  */
400
  if($trailing_slashes_mode) {
 
401
  $old_request = strtok($_SERVER['REQUEST_URI'], "?");
 
 
 
402
  $ends_with_slash = (substr($old_request, -1) == "/") ? true : false;
403
 
404
  // Homepage should be ignored
405
  if($old_request != "/") {
406
  // 2A. Force trailing slashes
407
  if($trailing_slashes_mode == 10 && $ends_with_slash == false) {
408
- $correct_permalink = (!empty($correct_permalink)) ? "{$correct_permalink}/" : rtrim(get_option('home'), "/") . $old_request . "/";
409
  }
410
  // 2B. Remove trailing slashes
411
  else if($trailing_slashes_mode == 20 && $ends_with_slash == true) {
412
- $correct_permalink = (!empty($correct_permalink)) ? $correct_permalink : rtrim(get_option('home'), "/") . $old_request;
413
- $correct_permalink = rtrim($correct_permalink, "/");
414
  }
415
  }
416
  }
@@ -427,18 +458,38 @@ class Permalink_Manager_Core_Functions extends Permalink_Manager_Class {
427
  }
428
  }
429
 
430
- function fix_canonical_redirect($redirect_url, $requested_url) {
431
- global $permalink_manager_options;
 
 
 
 
 
 
 
 
432
 
433
- // Trailing slash (use redirect_to_new_uri() function instead)
434
- if(substr($redirect_url, 0, -1) != '/' && $permalink_manager_options['general']['trailing_slashes'] > 1) {
435
- $redirect_url = false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
436
  }
437
- return $redirect_url;
438
- }
439
 
440
- function disable_canonical_redirect() {
441
- global $permalink_manager_options, $wp_filter, $wp;
442
 
443
  if(!($permalink_manager_options['general']['canonical_redirect']) || !empty($wp->query_vars['do_not_redirect'])) {
444
  remove_action('template_redirect', 'redirect_canonical');
10
  }
11
 
12
  function init_hooks() {
13
+ // Trigger only in front-end
14
+ if(!is_admin()) {
15
+ // Use the URIs set in this plugin
16
+ add_filter( 'request', array($this, 'detect_post'), 0, 1 );
17
+
18
+ // Trailing slashes
19
+ add_filter( 'permalink_manager_filter_final_term_permalink', array($this, 'control_trailing_slashes'), 9);
20
+ add_filter( 'permalink_manager_filter_final_post_permalink', array($this, 'control_trailing_slashes'), 9);
21
+ add_filter( 'permalink_manager_filter_post_sample_permalink', array($this, 'control_trailing_slashes'), 9);
22
+
23
+ // Redirect from old URIs to new URIs + adjust canonical redirect settings
24
+ add_action( 'template_redirect', array($this, 'new_uri_redirect_and_404'), 1);
25
+ add_action( 'wp', array($this, 'adjust_canonical_redirect'), 0, 1);
26
+
27
+ // Case insensitive permalinks
28
+ add_action( 'parse_request', array($this, 'case_insensitive_permalinks'), 0);
29
+ add_action( 'parse_request', array($this, 'fix_pagination_pages'), 0);
30
+ }
31
  }
32
 
33
  /**
36
  function detect_post($query) {
37
  global $wpdb, $wp, $wp_rewrite, $permalink_manager_uris, $wp_filter, $permalink_manager_options, $pm_item_id;
38
 
39
+ // Check if any custom URI is used and we are not in WP-Admin dashboard
40
  if(!(is_array($permalink_manager_uris)) || empty($query)) return $query;
41
 
42
  // Used in debug mode & endpoints
43
  $old_query = $query;
44
 
45
  /**
46
+ * 1. Prepare URL and check if it is correct (make sure that both requested URL & home_url share the same protoocl and get rid of www prefix)
47
  */
48
+ $request_url = sprintf("http://%s%s", str_replace("www.", "", $_SERVER['HTTP_HOST']), strtok($_SERVER['REQUEST_URI'], "?"));
49
+ $raw_home_url = trim(get_option('home'));
50
+ $home_url = preg_replace("/http(s)?:\/\/(www\.)?(.+?)\/?$/", "http://$3", $raw_home_url);
 
51
 
52
  if(filter_var($request_url, FILTER_VALIDATE_URL)) {
53
  // Check if "Deep Detect" is enabled
54
  $deep_detect_enabled = apply_filters('permalink-manager-deep-uri-detect', $permalink_manager_options['general']['deep_detect']);
55
 
56
+ // Keep only the URI
57
  $request_url = trim(str_replace($home_url, "", $request_url), "/");
58
 
59
+ // Get all the endpoints & pattern
 
 
 
60
  $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
61
+ $pattern = "/^(.+?)(?|\/({$endpoints})\/?([^\/]*)|()\/([\d+]))?\/?$/i";
62
 
63
  // Use default REGEX to detect post
64
+ preg_match($pattern, $request_url, $regex_parts);
65
  $uri_parts['lang'] = false;
66
  $uri_parts['uri'] = (!empty($regex_parts[1])) ? $regex_parts[1] : "";
67
  $uri_parts['endpoint'] = (!empty($regex_parts[2])) ? $regex_parts[2] : "";
83
  $uri = trim($uri, "/");
84
 
85
  // Decode both Request URI & URIs array
86
+ $uri = urldecode($uri);
87
  foreach ($permalink_manager_uris as $key => $value) {
88
  $permalink_manager_uris[$key] = urldecode($value);
89
+ }
90
 
91
  // Ignore URLs with no URI grabbed
92
  if(empty($uri)) return $query;
155
  }
156
  }
157
 
 
 
158
  $query[$query_parameter] = $final_uri;
159
  } else {
160
  $broken_uri = true;
191
  }
192
 
193
  // Alter query parameters
194
+ if($post_type == 'page') {
195
  $query['pagename'] = $final_uri;
196
+ } else if($post_type == 'post') {
197
  $query['name'] = $final_uri;
198
+ } else if($post_type == 'attachment') {
199
  $query['attachment'] = $final_uri;
200
  } else {
201
+ // Get the query var
202
+ $post_type_object = get_post_type_object($post_type);
203
+ $query_var = (!empty($post_type_object->query_var)) ? $post_type_object->query_var : $post_type;
204
+
205
  $query['name'] = $final_uri;
206
  $query['post_type'] = $post_type;
207
+ $query[$query_var] = $final_uri;
208
  }
 
 
 
209
  } else {
210
  $broken_uri = true;
211
  }
212
  }
213
 
214
  /**
215
+ * 4. Auto-remove removed term custom URI & redirects (works if enabled in plugin settings)
216
  */
217
  if(!empty($broken_uri) && !empty($permalink_manager_options['general']['auto_remove_duplicates'])) {
218
  $remove_broken_uri = Permalink_Manager_Actions::clear_single_element_uris_and_redirects($element_id);
225
  }
226
 
227
  /**
228
+ * 5A. Endpoints
229
  */
230
  if($element_id && (!empty($endpoint)) || !empty($endpoint_value)) {
231
  $endpoint = ($endpoint) ? str_replace(array('page', 'trackback'), array('paged', 'tb'), $endpoint) : "page";
237
  } else {
238
  $query[$endpoint] = $endpoint_value;
239
  }
240
+
241
+ // Fix for attachments
242
+ if(!empty($query['attachment'])) {
243
+ $query = array('attachment' => $query['attachment'], 'do_not_redirect' => 1);
244
+ }
245
  }
246
 
247
  /**
248
+ * 5B. Endpoints - check if any endpoint is set with $_GET parameter
249
  */
250
  if($deep_detect_enabled && !empty($_GET)) {
251
  $get_endpoints = array_intersect($wp->public_query_vars, array_keys($_GET));
261
  }
262
 
263
  /**
264
+ * 6. WWW prefix mismatch detect
265
+ */
266
+ $home_url_has_www = (strpos($raw_home_url, 'www.') !== false) ? true : false;
267
+ $requested_url_has_www = (strpos($_SERVER['HTTP_HOST'], 'www.') !== false) ? true : false;
268
+
269
+ if($home_url_has_www != $requested_url_has_www) {
270
+ unset($query['do_not_redirect']);
271
+ }
272
+
273
+ /**
274
+ * 7. Set global with detected item id
275
  */
276
  if(!empty($element_id)) {
277
  $pm_item_id = $element_id;
278
+
279
+ // Make the redirects more clever - see new_uri_redirect_and_404() method
280
+ $query['do_not_redirect'] = 1;
281
  }
282
  }
283
 
284
+ /**
285
+ * 8. Debug mode
286
+ */
287
  if(isset($_REQUEST['debug_url'])) {
288
  $debug_info['old_query_vars'] = $old_query;
289
  $debug_info['new_query_vars'] = $query;
290
+ $debug_info['detected_id'] = $pm_item_id;
291
 
292
  $debug_txt = json_encode($debug_info);
293
  $debug_txt = "<textarea style=\"width:100%;height:300px\">{$debug_txt}</textarea>";
305
 
306
  $trailing_slash_setting = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : "";
307
 
308
+ if(in_array($trailing_slash_setting, array(1, 10))) {
309
  $permalink = trailingslashit($permalink);
310
+ } else if(in_array($trailing_slash_setting, array(2, 20))) {
311
  $permalink = untrailingslashit($permalink);
312
  }
313
 
342
  /**
343
  * Redirects
344
  */
345
+ function new_uri_redirect_and_404() {
346
+ global $wp_query, $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wp, $pm_item_id;
347
 
348
  // Do not redirect on author pages & front page
349
  if(is_author() || is_front_page() || is_home()) { return false; }
350
 
351
+ // Unset 404 if custom URI is detected
352
+ if(isset($pm_item_id)) {
353
+ $wp_query->is_404 = false;
354
+ }
355
+
356
  // Sometimes $wp_query indicates the wrong object if requested directly
357
  $queried_object = get_queried_object();
358
 
363
  // Get query string
364
  $query_string = $_SERVER['QUERY_STRING'];
365
 
366
+ // Get home URL
367
+ $home_url = rtrim(get_option('home'), "/");
368
+
369
  /**
370
  * 1A. Custom redirects
371
  */
412
  $correct_permalink = get_permalink($queried_object->ID);
413
  }
414
  // Affect only terms with custom URI and old URIs
415
+ else if(!empty($queried_object->term_id) && isset($permalink_manager_uris["tax-{$queried_object->term_id}"]) && defined('PERMALINK_MANAGER_PRO')) {
416
  // Check if taxonomy is allowed
417
  if(Permalink_Manager_Helper_Functions::is_disabled($queried_object->taxonomy, "taxonomy")) { return ''; }
418
 
425
  * 2. Check trailing slashes
426
  */
427
  if($trailing_slashes_mode) {
428
+ $home_dir = parse_url($home_url, PHP_URL_PATH);
429
  $old_request = strtok($_SERVER['REQUEST_URI'], "?");
430
+
431
+ // Fix for WP installed in directories
432
+ $old_request = ltrim(str_replace($home_dir, "", $old_request), "/");
433
  $ends_with_slash = (substr($old_request, -1) == "/") ? true : false;
434
 
435
  // Homepage should be ignored
436
  if($old_request != "/") {
437
  // 2A. Force trailing slashes
438
  if($trailing_slashes_mode == 10 && $ends_with_slash == false) {
439
+ $correct_permalink = (!empty($correct_permalink)) ? "{$correct_permalink}/" : "{$home_url}/{$old_request}/";
440
  }
441
  // 2B. Remove trailing slashes
442
  else if($trailing_slashes_mode == 20 && $ends_with_slash == true) {
443
+ $correct_permalink = (!empty($correct_permalink)) ? $correct_permalink : "{$home_url}/{$old_request}";
444
+ $correct_permalink = trim($correct_permalink, "/");
445
  }
446
  }
447
  }
458
  }
459
  }
460
 
461
+ function adjust_canonical_redirect() {
462
+ global $permalink_manager_options, $permalink_manager_uris, $wp, $wp_rewrite;
463
+
464
+ // Adjust rewrite settings for trailing slashes
465
+ $trailing_slash_setting = (!empty($permalink_manager_options['general']['trailing_slashes'])) ? $permalink_manager_options['general']['trailing_slashes'] : "";
466
+ if(in_array($trailing_slash_setting, array(1, 10))) {
467
+ $wp_rewrite->use_trailing_slashes = true;
468
+ } else if(in_array($trailing_slash_setting, array(2, 20))) {
469
+ $wp_rewrite->use_trailing_slashes = false;
470
+ }
471
 
472
+ // Get endpoints
473
+ $endpoints = Permalink_Manager_Helper_Functions::get_endpoints();
474
+ $endpoints_array = ($endpoints) ? explode("|", $endpoints) : array();
475
+
476
+ // Check if any endpoint is called (fix for feed and similar endpoints)
477
+ foreach($endpoints_array as $endpoint) {
478
+ if(!empty($wp->query_vars[$endpoint])) {
479
+ $wp->query_vars['do_not_redirect'] = 1;
480
+ break;
481
+ }
482
+ }
483
+
484
+ // Do nothing for posts and terms without custom URIs (when canonical redirect is enabled)
485
+ $element = get_queried_object();
486
+ if(!empty($element->ID)) {
487
+ $custom_uri = (!empty($permalink_manager_uris[$element->ID])) ? $permalink_manager_uris[$element->ID] : "";
488
+ } else if(!empty($element->term_id)) {
489
+ $custom_uri = (!empty($permalink_manager_uris["tax-{$element->term_id}"])) ? $permalink_manager_uris["tax-{$element->term_id}"] : "";
490
  }
 
 
491
 
492
+ if(empty($custom_uri) && !empty($permalink_manager_options['general']['canonical_redirect'])) { return; }
 
493
 
494
  if(!($permalink_manager_options['general']['canonical_redirect']) || !empty($wp->query_vars['do_not_redirect'])) {
495
  remove_action('template_redirect', 'redirect_canonical');
includes/core/permalink-manager-helper-functions.php CHANGED
@@ -30,7 +30,9 @@ class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
30
  static function get_primary_term($post_id, $taxonomy, $slug_only = true) {
31
  global $permalink_manager_options;
32
 
33
- if($permalink_manager_options['general']['yoast_primary_term'] == 1 && class_exists('WPSEO_Primary_Term')) {
 
 
34
  $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
35
  $primary_term = get_term($primary_term->get_primary_term());
36
 
30
  static function get_primary_term($post_id, $taxonomy, $slug_only = true) {
31
  global $permalink_manager_options;
32
 
33
+ $primary_term_enabled = apply_filters('permalink-manager-primary-term', true);
34
+
35
+ if($primary_term_enabled && class_exists('WPSEO_Primary_Term')) {
36
  $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
37
  $primary_term = get_term($primary_term->get_primary_term());
38
 
includes/core/permalink-manager-third-parties.php CHANGED
@@ -10,10 +10,10 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
10
  }
11
 
12
  function init_hooks() {
13
- global $sitepress_settings, $permalink_manager_options;
14
 
15
- // 1. WPML
16
- if($sitepress_settings) {
17
  // Detect Post/Term function
18
  add_filter('permalink-manager-detected-post-id', array($this, 'wpml_language_mismatch_fix'), 9, 3);
19
  add_filter('permalink-manager-detected-term-id', array($this, 'wpml_language_mismatch_fix'), 9, 3);
@@ -21,8 +21,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
21
  // URI Editor
22
  add_filter('permalink-manager-uri-editor-extra-info', array($this, 'wpml_lang_column_content_uri_editor'), 9, 3);
23
 
24
- // Split the current URL into subparts (check if WPML is active)
25
- if(isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 1) {
26
  add_filter('permalink-manager-detect-uri', array($this, 'wpml_detect_post'), 9, 3);
27
  add_filter('permalink-manager-post-permalink-prefix', array($this, 'wpml_element_lang_prefix'), 9, 3);
28
  add_filter('permalink-manager-term-permalink-prefix', array($this, 'wpml_element_lang_prefix'), 9, 3);
@@ -39,24 +38,19 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
39
  add_filter('request', array($this, 'enable_amp'), 10, 1);
40
  }
41
 
42
- // 3. Yoast SEO
43
- if(class_exists('WPSEO_Options')) {
44
- $yoast_permalink_options = get_option('wpseo_permalinks');
45
-
46
- // Redirect attachment to parent post/page enabled
47
- if(!empty($yoast_permalink_options['redirectattachment']) && !empty($permalink_manager_options['general']['yoast_attachment_redirect'])) {
48
- add_filter('permalink-manager-detected-initial-id', array($this, 'yoast_detect_attachment'), 9, 3);
49
- }
50
- }
51
-
52
- // 5. WP All Import
53
  add_action('pmxi_after_xml_import', array($this, 'pmxi_fix_permalinks'), 10);
54
 
55
- // 6. WooCommerce
56
  if(class_exists('WooCommerce')) {
57
  add_filter('request', array($this, 'woocommerce_detect'), 9, 1);
58
  add_filter('template_redirect', array($this, 'woocommerce_checkout_fix'), 9);
59
  }
 
 
 
 
 
60
  }
61
 
62
  /**
@@ -82,12 +76,16 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
82
  }
83
 
84
  function wpml_detect_post($uri_parts, $request_url, $endpoints) {
85
- global $sitepress_settings;
86
 
87
  if(!empty($sitepress_settings['active_languages'])) {
88
  $languages_list = implode("|", $sitepress_settings['active_languages']);
89
- //preg_match("/^(?:(\w{2})\/)?(.+?)(?:\/({$endpoints}))?(?:\/([\d+]))?\/?$/i", $request_url, $regex_parts);
 
 
 
90
 
 
91
  preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})\/([^\/]+)|\/()([\d+]))?\/?$/i", $request_url, $regex_parts);
92
 
93
  $uri_parts['lang'] = (!empty($regex_parts[1])) ? $regex_parts[1] : "";
@@ -100,30 +98,34 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
100
  }
101
 
102
  function wpml_element_lang_prefix($prefix, $element, $edit_uri_box = false) {
103
- global $sitepress_settings;
104
 
105
  if(isset($element->post_type)) {
106
  $post = (is_integer($element)) ? get_post($element) : $element;
107
- $lang_details = apply_filters('wpml_element_language_details', NULL, array('element_id' => $post->ID, 'element_type' => $post->post_type));
 
108
  } else {
109
  $term = (is_numeric($element)) ? get_term(intval($element)) : $element;
110
- $lang_details = apply_filters('wpml_element_language_details', NULL, array('element_id' => $term->term_id, 'element_type' => $term->taxonomy));
 
111
  }
112
 
113
- $prefix = (!empty($lang_details->language_code)) ? $lang_details->language_code : '';
114
 
115
  if($edit_uri_box) {
116
  // Last instance - use language paramater from &_GET array
117
- $prefix = (empty($prefix) && !empty($_GET['lang'])) ? $_GET['lang'] : $prefix;
118
  }
119
 
120
  // Append slash to the end of language code if it is not empty
121
- if(!empty($prefix)) {
122
- $prefix = "{$prefix}/";
123
 
124
  // Hide language code if "Use directory for default language" option is enabled
125
  $default_language = Permalink_Manager_Helper_Functions::get_language();
126
- if(isset($sitepress_settings['urls']['directory_for_default_language']) && isset($lang_details->language_code) && ($sitepress_settings['urls']['directory_for_default_language'] == 0) && ($default_language == $lang_details->language_code)) {
 
 
127
  $prefix = "";
128
  }
129
  }
@@ -132,23 +134,26 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
132
  }
133
 
134
  function wpml_lang_column_uri_editor($columns) {
135
- if(class_exists('SitePress')) {
136
  $columns['post_lang'] = __('Language', 'permalink-manager');
137
  }
138
 
139
  return $columns;
140
  }
141
 
142
- function wpml_lang_column_content_uri_editor($output, $column, $item) {
143
- if(isset($item->post_type)) {
144
- $post = (is_integer($item)) ? get_post($item) : $item;
145
- $lang_details = apply_filters('wpml_element_language_details', NULL, array('element_id' => $post->ID, 'element_type' => $post->post_type));
 
146
  } else {
147
- $term = (is_integer($item)) ? get_term(intval($item)) : $item;
148
- $lang_details = apply_filters('wpml_element_language_details', NULL, array('element_id' => $term->term_id, 'element_type' => $term->taxonomy));
 
149
  }
150
 
151
- $output .= (!empty($lang_details->language_code)) ? sprintf(" | <span><strong>%s:</strong> %s</span>", __("Language"), $lang_details->language_code) : "";
 
152
 
153
  return $output;
154
  }
@@ -199,35 +204,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
199
  }
200
 
201
  /**
202
- * 3. Yoast SEO
203
- */
204
- function yoast_detect_attachment($item_id, $uri_parts, $request_url) {
205
- global $wpdb, $permalink_manager_uris;
206
-
207
- $uri = (!empty($uri_parts['uri'])) ? $uri_parts['uri'] : "";
208
- $endpoint = (!empty($uri_parts['endpoint'])) ? $uri_parts['endpoint'] : "";
209
- $endpoint_value = (!empty($uri_parts['endpoint_value'])) ? $uri_parts['endpoint_value'] : "";
210
-
211
- if(empty($item_id) && $uri) {
212
- $slug = basename($uri_parts['uri']);
213
-
214
- // Check if slug is already used by any post or term
215
- $used_by_post = $wpdb->get_row($wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_status = %s AND post_name = %s", "publish", $slug ), ARRAY_A);
216
- $used_by_term = ($used_by_post) ? true : $wpdb->get_row($wpdb->prepare( "SELECT term_id FROM {$wpdb->terms} WHERE slug = %s", $slug ), ARRAY_A);
217
- } else if($endpoint == 'attachment' && !empty($endpoint_value)) {
218
- $slug = $endpoint_value;
219
- }
220
-
221
- if(!empty($slug)) {
222
- $attachment = $wpdb->get_row($wpdb->prepare( "SELECT ID, post_name FROM {$wpdb->posts} WHERE post_type = %s AND post_name = %s", "attachment", $slug ), ARRAY_A);
223
- $item_id = (!empty($attachment['ID'])) ? $attachment['ID'] : $item_id;
224
- }
225
-
226
- return $item_id;
227
- }
228
-
229
- /**
230
- * 4. Custom Permalinks
231
  */
232
  public static function custom_permalinks_uris() {
233
  global $wpdb;
@@ -283,7 +260,7 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
283
  }
284
 
285
  /**
286
- * 5. WP All Import
287
  */
288
  function pmxi_fix_permalinks($import_id) {
289
  global $permalink_manager_uris, $wpdb;
@@ -295,7 +272,10 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
295
 
296
  if(array($post_ids)) {
297
  foreach($post_ids as $id) {
298
- // Get default post URI
 
 
 
299
  $new_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
300
  $permalink_manager_uris[$id] = $new_uri;
301
  }
@@ -304,6 +284,9 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
304
  update_option('permalink-manager-uris', $permalink_manager_uris);
305
  }
306
 
 
 
 
307
  function woocommerce_detect($query) {
308
  global $woocommerce, $pm_item_id;
309
 
@@ -313,6 +296,19 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
313
  unset($query['pagename']);
314
  }
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  return $query;
317
  }
318
 
@@ -338,6 +334,16 @@ class Permalink_Manager_Third_Parties extends Permalink_Manager_Class {
338
  }
339
  }
340
 
 
 
 
 
 
 
 
 
 
 
341
 
342
  }
343
  ?>
10
  }
11
 
12
  function init_hooks() {
13
+ global $sitepress_settings, $permalink_manager_options, $polylang;
14
 
15
+ // 1. WPML & Polylang
16
+ if($sitepress_settings || !empty($polylang->links_model->options)) {
17
  // Detect Post/Term function
18
  add_filter('permalink-manager-detected-post-id', array($this, 'wpml_language_mismatch_fix'), 9, 3);
19
  add_filter('permalink-manager-detected-term-id', array($this, 'wpml_language_mismatch_fix'), 9, 3);
21
  // URI Editor
22
  add_filter('permalink-manager-uri-editor-extra-info', array($this, 'wpml_lang_column_content_uri_editor'), 9, 3);
23
 
24
+ if((isset($sitepress_settings['language_negotiation_type']) && $sitepress_settings['language_negotiation_type'] == 1) || (isset($polylang->links_model->options['force_lang']) && $polylang->links_model->options['force_lang'] == 1)) {
 
25
  add_filter('permalink-manager-detect-uri', array($this, 'wpml_detect_post'), 9, 3);
26
  add_filter('permalink-manager-post-permalink-prefix', array($this, 'wpml_element_lang_prefix'), 9, 3);
27
  add_filter('permalink-manager-term-permalink-prefix', array($this, 'wpml_element_lang_prefix'), 9, 3);
38
  add_filter('request', array($this, 'enable_amp'), 10, 1);
39
  }
40
 
41
+ // 4. WP All Import
 
 
 
 
 
 
 
 
 
 
42
  add_action('pmxi_after_xml_import', array($this, 'pmxi_fix_permalinks'), 10);
43
 
44
+ // 5. WooCommerce
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
51
+ if(class_exists('Theme_My_Login')) {
52
+ add_filter('permalink_manager_filter_final_post_permalink', array($this, 'tml_keep_query_parameters'), 9, 3);
53
+ }
54
  }
55
 
56
  /**
76
  }
77
 
78
  function wpml_detect_post($uri_parts, $request_url, $endpoints) {
79
+ global $sitepress_settings, $polylang;
80
 
81
  if(!empty($sitepress_settings['active_languages'])) {
82
  $languages_list = implode("|", $sitepress_settings['active_languages']);
83
+ } elseif(function_exists('pll_languages_list')) {
84
+ $languages_array = pll_languages_list();
85
+ $languages_list = (is_array($languages_array)) ? implode("|", $languages_array) : "";
86
+ }
87
 
88
+ if(!empty($languages_list)) {
89
  preg_match("/^(?:({$languages_list})\/)?(.+?)(?|\/({$endpoints})\/([^\/]+)|\/()([\d+]))?\/?$/i", $request_url, $regex_parts);
90
 
91
  $uri_parts['lang'] = (!empty($regex_parts[1])) ? $regex_parts[1] : "";
98
  }
99
 
100
  function wpml_element_lang_prefix($prefix, $element, $edit_uri_box = false) {
101
+ global $sitepress_settings, $polylang;
102
 
103
  if(isset($element->post_type)) {
104
  $post = (is_integer($element)) ? get_post($element) : $element;
105
+ $element_id = $post->ID;
106
+ $element_type = $post->post_type;
107
  } else {
108
  $term = (is_numeric($element)) ? get_term(intval($element)) : $element;
109
+ $element_id = $term->term_id;
110
+ $element_type = $term->taxonomy;
111
  }
112
 
113
+ $language_code = apply_filters( 'wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
114
 
115
  if($edit_uri_box) {
116
  // Last instance - use language paramater from &_GET array
117
+ $language_code = (empty($language_code) && !empty($_GET['lang'])) ? $_GET['lang'] : $language_code;
118
  }
119
 
120
  // Append slash to the end of language code if it is not empty
121
+ if(!empty($language_code)) {
122
+ $prefix = "{$language_code}/";
123
 
124
  // Hide language code if "Use directory for default language" option is enabled
125
  $default_language = Permalink_Manager_Helper_Functions::get_language();
126
+ $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;
127
+
128
+ if($hide_prefix_for_default_lang && ($default_language == $language_code)) {
129
  $prefix = "";
130
  }
131
  }
134
  }
135
 
136
  function wpml_lang_column_uri_editor($columns) {
137
+ if(class_exists('SitePress') || class_exists('Polylang')) {
138
  $columns['post_lang'] = __('Language', 'permalink-manager');
139
  }
140
 
141
  return $columns;
142
  }
143
 
144
+ function wpml_lang_column_content_uri_editor($output, $column, $element) {
145
+ if(isset($element->post_type)) {
146
+ $post = (is_integer($element)) ? get_post($element) : $element;
147
+ $element_id = $post->ID;
148
+ $element_type = $post->post_type;
149
  } else {
150
+ $term = (is_numeric($element)) ? get_term(intval($element)) : $element;
151
+ $element_id = $term->term_id;
152
+ $element_type = $term->taxonomy;
153
  }
154
 
155
+ $language_code = apply_filters( 'wpml_element_language_code', null, array('element_id' => $element_id, 'element_type' => $element_type));
156
+ $output .= (!empty($language_code)) ? sprintf(" | <span><strong>%s:</strong> %s</span>", __("Language"), $language_code) : "";
157
 
158
  return $output;
159
  }
204
  }
205
 
206
  /**
207
+ * 3. Custom Permalinks
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  */
209
  public static function custom_permalinks_uris() {
210
  global $wpdb;
260
  }
261
 
262
  /**
263
+ * 4. WP All Import
264
  */
265
  function pmxi_fix_permalinks($import_id) {
266
  global $permalink_manager_uris, $wpdb;
272
 
273
  if(array($post_ids)) {
274
  foreach($post_ids as $id) {
275
+ // Continue only if no custom URI is already assigned
276
+ if(!empty($permalink_manager_uris[$id])) { continue; }
277
+
278
+ // Get default post URI
279
  $new_uri = Permalink_Manager_URI_Functions_Post::get_default_post_uri($id);
280
  $permalink_manager_uris[$id] = $new_uri;
281
  }
284
  update_option('permalink-manager-uris', $permalink_manager_uris);
285
  }
286
 
287
+ /**
288
+ * 5. WooCommerce
289
+ */
290
  function woocommerce_detect($query) {
291
  global $woocommerce, $pm_item_id;
292
 
296
  unset($query['pagename']);
297
  }
298
 
299
+ // Fix WooCommerce pages
300
+ if(!empty($woocommerce->query->query_vars)) {
301
+ $query_vars = $woocommerce->query->query_vars;
302
+
303
+ foreach($query_vars as $key => $val) {
304
+ if(isset($query[$key])) {
305
+ $woocommerce_page = true;
306
+ $query['do_not_redirect'] = 1;
307
+ break;
308
+ }
309
+ }
310
+ }
311
+
312
  return $query;
313
  }
314
 
334
  }
335
  }
336
 
337
+ /**
338
+ * 6. Theme My Login
339
+ */
340
+ function tml_keep_query_parameters($permalink, $post, $old_permalink) {
341
+ // Get the query string from old permalink
342
+ $get_parameters = (($pos = strpos($old_permalink, "?")) !== false) ? substr($old_permalink, $pos) : "";
343
+
344
+ return $permalink . $get_parameters;
345
+ }
346
+
347
 
348
  }
349
  ?>
includes/core/permalink-manager-uri-functions-post.php CHANGED
@@ -23,7 +23,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
23
  add_action( 'save_post', array($this, 'update_post_uri'), 999, 1);
24
  add_action( 'edit_attachment', array($this, 'update_post_uri'), 999, 1 );
25
  add_action( 'wp_insert_post', array($this, 'new_post_uri'), 999, 1 );
26
- //add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 10, 1 );
27
 
28
  add_action( 'quick_edit_custom_box', array($this, 'quick_edit_column_form'), 999, 3);
29
  }
@@ -53,6 +53,9 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
53
 
54
  $post = (is_integer($post)) ? get_post($post) : $post;
55
 
 
 
 
56
  // 1. Check if post type is allowed
57
  if(!empty($post->post_type) && Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $permalink; }
58
 
@@ -65,25 +68,28 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
65
  return trim($permalink, "/");
66
  }
67
 
68
- // 3. Filter only the posts with custom permalink assigned
 
 
 
69
  if(isset($permalink_manager_uris[$post->ID])) {
70
  // Apend the language code as a non-editable prefix (can be used also for another prefixes)
71
  $prefix = apply_filters('permalink-manager-post-permalink-prefix', '', $post);
72
 
73
- $permalink = get_option('home');
74
-
75
  // Encode URI?
76
  if(!empty($permalink_manager_options['general']['decode_uris'])) {
77
- $permalink .= urldecode("/{$prefix}{$permalink_manager_uris[$post->ID]}");
78
  } else {
79
- $permalink .= Permalink_Manager_Helper_Functions::encode_uri("/{$prefix}{$permalink_manager_uris[$post->ID]}");
80
  }
 
 
81
  } else if(!empty($permalink_manager_options['general']['decode_uris'])) {
82
- $permalink = urldecode($permalink);
83
  }
84
 
85
- // 4. Additional filter
86
- $permalink = apply_filters('permalink_manager_filter_final_post_permalink', user_trailingslashit($permalink), $post);
87
 
88
  return $permalink;
89
  }
@@ -130,59 +136,73 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
130
  $post_type = $post->post_type;
131
  $post_name = (empty($post->post_name)) ? sanitize_title($post->post_title) : $post->post_name;
132
 
133
- // Get the permastruct
134
- $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
135
- if($native_uri) {
136
- $permastruct = $default_permastruct;
 
 
 
 
 
 
137
  } else {
138
- $permastruct = (isset($permalink_manager_permastructs['post_types'][$post_type])) ? $permalink_manager_permastructs['post_types'][$post_type] : $default_permastruct;
 
 
 
 
 
139
  }
140
  $default_base = (!empty($permastruct)) ? trim($permastruct, '/') : "";
141
 
142
- // 1A. Get the date
143
  $date = explode(" ", date('Y m d H i s', strtotime($post->post_date)));
144
 
145
- // 1B. Get the author (if needed)
146
  $author = '';
147
  if(strpos($default_base, '%author%') !== false) {
148
  $authordata = get_userdata($post->post_author);
149
  $author = $authordata->user_nicename;
150
  }
151
 
152
- // 2A. Fix for hierarchical CPT (start)
153
- $full_slug = get_page_uri($post);
154
  $full_slug = (empty($full_slug)) ? $post_name : $full_slug;
155
 
156
- // 2B. Allow filter the default slug
157
  if(!$native_uri) {
158
  $full_slug = ($native_uri) ? $full_slug : Permalink_Manager_Helper_Functions::force_custom_slugs($full_slug, $post);
159
  $full_slug = apply_filters('permalink_manager_filter_default_post_slug', $full_slug, $post, $post_name);
160
  }
161
  $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
162
 
163
- // 3A. Get the standard tags and replace them with their values
164
  $tags = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%author%');
165
  $tags_replacements = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->ID, $author);
166
  $default_uri = str_replace($tags, $tags_replacements, $default_base);
167
 
168
  // 3B. Check if any post tag is present in custom permastructure
169
- $slug_tags = array($post_type_tag, '%postname%', '%postname_flat%');
170
- $slug_tags_replacement = array($full_slug, $full_slug, $post_name);
171
- foreach($slug_tags as $tag) {
172
- if(strpos($default_uri, $tag) !== false) {
173
- $do_not_append_slug = true;
174
- break;
 
 
 
175
  }
176
  }
177
 
178
- // 3C. Replace the post tags with slugs or rppend the slug if no post tag is defined
179
  if(!empty($do_not_append_slug)) {
180
  $default_uri = str_replace($slug_tags, $slug_tags_replacement, $default_uri);
181
  } else {
182
  $default_uri .= "/{$full_slug}";
183
  }
184
 
185
- // 3B. Replace taxonomies
186
  $taxonomies = get_taxonomies();
187
 
188
  if($taxonomies) {
@@ -197,6 +217,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
197
  if(empty($replacement_term)) {
198
  $terms = wp_get_object_terms($post->ID, $taxonomy);
199
  $replacement_term = (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) ? $terms[0] : "";
 
200
  }
201
 
202
  // 4A. Get permalink base from the term's custom URI
@@ -238,8 +259,7 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
238
  }
239
  }
240
 
241
- // Clear the URI
242
- // $default_uri = preg_replace("/%(.+?)%/", "", $default_uri);
243
  $default_uri = preg_replace('/\s+/', '', $default_uri);
244
  $default_uri = str_replace('//', '/', $default_uri);
245
  $default_uri = trim($default_uri, "/");
@@ -607,20 +627,13 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
607
  if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
608
 
609
  // Hotfix
610
- if(isset($_POST['custom_uri']) || isset($_POST['permalink-manager-quick-edit'])) { return $post_id; }
611
-
612
- // Fix for revisions
613
- $is_revision = wp_is_post_revision($post_id);
614
- $post_id = ($is_revision) ? $is_revision : $post_id;
615
 
616
  $post = get_post($post_id);
617
 
618
  // Check if post type is allowed
619
  if(Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $post_id; };
620
 
621
- // Continue only if no custom URI is already assigned
622
- if(!empty($permalink_manager_uris[$post_id])) { return $post_id; }
623
-
624
  // Hotfix for menu items & auto-drafts
625
  if($post->post_type == 'nav_menu_item' || $post->post_status == 'auto-draft') { return $post_id; }
626
 
@@ -634,8 +647,8 @@ class Permalink_Manager_URI_Functions_Post extends Permalink_Manager_Class {
634
  }
635
 
636
  /**
637
- * Update URI from "Edit Post" admin page
638
- */
639
  function update_post_uri($post_id) {
640
  global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
641
 
23
  add_action( 'save_post', array($this, 'update_post_uri'), 999, 1);
24
  add_action( 'edit_attachment', array($this, 'update_post_uri'), 999, 1 );
25
  add_action( 'wp_insert_post', array($this, 'new_post_uri'), 999, 1 );
26
+ add_action( 'wp_trash_post', array($this, 'remove_post_uri'), 10, 1 );
27
 
28
  add_action( 'quick_edit_custom_box', array($this, 'quick_edit_column_form'), 999, 3);
29
  }
53
 
54
  $post = (is_integer($post)) ? get_post($post) : $post;
55
 
56
+ // Start with homepage URL
57
+ $home_url = trim(get_option('home'), "/");
58
+
59
  // 1. Check if post type is allowed
60
  if(!empty($post->post_type) && Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $permalink; }
61
 
68
  return trim($permalink, "/");
69
  }
70
 
71
+ // 3. Save the old permalink to separate variable
72
+ $old_permalink = $permalink;
73
+
74
+ // 4. Filter only the posts with custom permalink assigned
75
  if(isset($permalink_manager_uris[$post->ID])) {
76
  // Apend the language code as a non-editable prefix (can be used also for another prefixes)
77
  $prefix = apply_filters('permalink-manager-post-permalink-prefix', '', $post);
78
 
 
 
79
  // Encode URI?
80
  if(!empty($permalink_manager_options['general']['decode_uris'])) {
81
+ $permalink = "{$home_url}/" . urldecode("/{$prefix}{$permalink_manager_uris[$post->ID]}");
82
  } else {
83
+ $permalink = "{$home_url}/" . Permalink_Manager_Helper_Functions::encode_uri("{$prefix}{$permalink_manager_uris[$post->ID]}");
84
  }
85
+ } else if($post->post_type == 'attachment' && $post->post_parent > 0 && $post->post_parent != $post->ID && !empty($permalink_manager_uris[$post->post_parent])) {
86
+ $permalink = "{$home_url}/{$permalink_manager_uris[$post->post_parent]}/attachment/{$post->post_name}";
87
  } else if(!empty($permalink_manager_options['general']['decode_uris'])) {
88
+ $permalink = "{$home_url}/" . urldecode("/{$permalink}");
89
  }
90
 
91
+ // 5. Additional filter
92
+ $permalink = apply_filters('permalink_manager_filter_final_post_permalink', user_trailingslashit($permalink), $post, $old_permalink);
93
 
94
  return $permalink;
95
  }
136
  $post_type = $post->post_type;
137
  $post_name = (empty($post->post_name)) ? sanitize_title($post->post_title) : $post->post_name;
138
 
139
+ // 1. Get the permastruct
140
+ if($post_type == 'attachment') {
141
+ $parent_page = ($post->post_parent > 0 && $post->post_parent != $post->ID) ? get_post($post->post_parent) : false;
142
+ $default_permastruct = ($parent_page) ? trim(get_page_uri($parent_page->ID), "/") . "/attachment" : "";
143
+
144
+ if($native_uri) {
145
+ $permastruct = $default_permastruct;
146
+ } else {
147
+ $permastruct = (!empty($permalink_manager_permastructs['post_types'][$post_type])) ? $permalink_manager_permastructs['post_types'][$post_type] : $default_permastruct;
148
+ }
149
  } else {
150
+ $default_permastruct = Permalink_Manager_Helper_Functions::get_default_permastruct($post_type);
151
+ if($native_uri) {
152
+ $permastruct = $default_permastruct;
153
+ } else {
154
+ $permastruct = (isset($permalink_manager_permastructs['post_types'][$post_type])) ? $permalink_manager_permastructs['post_types'][$post_type] : $default_permastruct;
155
+ }
156
  }
157
  $default_base = (!empty($permastruct)) ? trim($permastruct, '/') : "";
158
 
159
+ // 2A. Get the date
160
  $date = explode(" ", date('Y m d H i s', strtotime($post->post_date)));
161
 
162
+ // 2B. Get the author (if needed)
163
  $author = '';
164
  if(strpos($default_base, '%author%') !== false) {
165
  $authordata = get_userdata($post->post_author);
166
  $author = $authordata->user_nicename;
167
  }
168
 
169
+ // 3A. Fix for hierarchical CPT (start)
170
+ $full_slug = (is_post_type_hierarchical($post_type)) ? get_page_uri($post) : $post_name;
171
  $full_slug = (empty($full_slug)) ? $post_name : $full_slug;
172
 
173
+ // 3B. Allow filter the default slug
174
  if(!$native_uri) {
175
  $full_slug = ($native_uri) ? $full_slug : Permalink_Manager_Helper_Functions::force_custom_slugs($full_slug, $post);
176
  $full_slug = apply_filters('permalink_manager_filter_default_post_slug', $full_slug, $post, $post_name);
177
  }
178
  $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
179
 
180
+ // 3C. Get the standard tags and replace them with their values
181
  $tags = array('%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', '%post_id%', '%author%');
182
  $tags_replacements = array($date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->ID, $author);
183
  $default_uri = str_replace($tags, $tags_replacements, $default_base);
184
 
185
  // 3B. Check if any post tag is present in custom permastructure
186
+ $do_not_append_slug = apply_filters("permalink_manager_do_not_append_slug", false, $post_type, $post);
187
+ if($do_not_append_slug == false) {
188
+ $slug_tags = array($post_type_tag, '%postname%', '%postname_flat%');
189
+ $slug_tags_replacement = array($full_slug, $full_slug, $post_name);
190
+ foreach($slug_tags as $tag) {
191
+ if(strpos($default_uri, $tag) !== false) {
192
+ $do_not_append_slug = true;
193
+ break;
194
+ }
195
  }
196
  }
197
 
198
+ // 3B. Replace the post tags with slugs or rppend the slug if no post tag is defined
199
  if(!empty($do_not_append_slug)) {
200
  $default_uri = str_replace($slug_tags, $slug_tags_replacement, $default_uri);
201
  } else {
202
  $default_uri .= "/{$full_slug}";
203
  }
204
 
205
+ // 3C. Replace taxonomies
206
  $taxonomies = get_taxonomies();
207
 
208
  if($taxonomies) {
217
  if(empty($replacement_term)) {
218
  $terms = wp_get_object_terms($post->ID, $taxonomy);
219
  $replacement_term = (!is_wp_error($terms) && !empty($terms) && is_object($terms[0])) ? $terms[0] : "";
220
+ $replacement_term = apply_filters('permalink_manager_filter_post_terms', $replacement_term, $post, $terms, $taxonomy, $native_uri);
221
  }
222
 
223
  // 4A. Get permalink base from the term's custom URI
259
  }
260
  }
261
 
262
+ // 4. Clear the URI
 
263
  $default_uri = preg_replace('/\s+/', '', $default_uri);
264
  $default_uri = str_replace('//', '/', $default_uri);
265
  $default_uri = trim($default_uri, "/");
627
  if(!empty($_REQUEST['bulk_edit'])) { return $post_id; }
628
 
629
  // Hotfix
630
+ if(isset($_POST['custom_uri']) || isset($_POST['permalink-manager-quick-edit']) || isset($permalink_manager_uris[$post_id])) { return $post_id; }
 
 
 
 
631
 
632
  $post = get_post($post_id);
633
 
634
  // Check if post type is allowed
635
  if(Permalink_Manager_Helper_Functions::is_disabled($post->post_type, 'post_type')) { return $post_id; };
636
 
 
 
 
637
  // Hotfix for menu items & auto-drafts
638
  if($post->post_type == 'nav_menu_item' || $post->post_status == 'auto-draft') { return $post_id; }
639
 
647
  }
648
 
649
  /**
650
+ * Update URI from "Edit Post" admin page
651
+ */
652
  function update_post_uri($post_id) {
653
  global $permalink_manager_uris, $permalink_manager_options, $permalink_manager_before_sections_html;
654
 
includes/views/permalink-manager-settings.php CHANGED
@@ -48,35 +48,38 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
48
  )
49
  )
50
  ),
51
- 'miscellaneous' => array(
52
  'section_name' => __('SEO functions', 'permalink-manager'),
53
  'container' => 'row',
54
  'name' => 'general',
55
  'fields' => array(
56
- 'yoast_primary_term' => array(
57
- 'type' => 'single_checkbox',
58
- 'label' => __('Primary term/category support', 'permalink-manager'),
59
- 'input_class' => '',
60
- 'description' => __('Used to generate default permalinks in pages, posts & custom post types. Works only when "Yoast SEO" plugin is enabled.', 'permalink-manager')
61
- ),
62
- 'yoast_attachment_redirect' => array(
63
- 'type' => 'single_checkbox',
64
- 'label' => __('Attachment redirect support', 'permalink-manager'),
65
- 'input_class' => '',
66
- 'description' => __('Redirect attachment URLs to their parent posts. Works only when "Yoast SEO Premium" plugin is enabled.', 'permalink-manager')
67
- ),
68
  'canonical_redirect' => array(
69
  'type' => 'single_checkbox',
70
  'label' => __('Canonical redirect', 'permalink-manager'),
71
  'input_class' => '',
72
  'description' => __('This function allows Wordpress to correct the URLs used by the visitors.', 'permalink-manager')
73
  ),
 
 
 
 
 
 
 
 
74
  'redirect' => array(
75
  'type' => 'select',
76
  'label' => __('Redirect', 'permalink-manager'),
77
  'input_class' => 'settings-select',
78
  'choices' => array(0 => __('Disable', 'permalink-manager'), "301" => __('Enable "301 redirect"', 'permalink-manager'), "302" => __('Enable "302 redirect"', 'permalink-manager')),
79
  'description' => __('If enabled - the visitors will be redirected from native permalinks to your custom permalinks.<br /><strong>Only native permalinks & extra redirects will be redirected to new custom permalinks</strong>.', 'permalink-manager')
 
 
 
 
 
 
 
80
  )
81
  )
82
  ),
@@ -85,14 +88,6 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
85
  'container' => 'row',
86
  'name' => 'general',
87
  'fields' => array(
88
- 'setup_redirects' => array(
89
- 'type' => 'single_checkbox',
90
- 'label' => __('Auto-create "Extra Redirects" for old permalinks', 'permalink-manager'),
91
- 'input_class' => '',
92
- 'pro' => true,
93
- 'disabled' => true,
94
- 'description' => __('If enabled, the redirects will be automatially created for old custom permalinks, after posts or terms are updated.', 'permalink-manager')
95
- ),
96
  'auto_remove_duplicates' => array(
97
  'type' => 'single_checkbox',
98
  'label' => __('Automatically remove duplicates', 'permalink-manager'),
@@ -105,24 +100,6 @@ class Permalink_Manager_Settings extends Permalink_Manager_Class {
105
  'input_class' => '',
106
  'description' => __('If enabled, the slugs in the default custom permalinks will be recreated from the post titles.<br />This may cause permalinks duplicates when the post or term title is used more than once.', 'permalink-manager')
107
  ),
108
- /*'deep_detect' => array(
109
- 'type' => 'single_checkbox',
110
- 'label' => __('Enable "Deep detect"', 'permalink-manager'),
111
- 'description' => __('Please keep it enabled if your custom URIs end with numerals, e.g. <strong>example.com/projects/20171025</strong> or if $_GET parameters should be detected as endpoints e.g. <strong>?page=1</strong>.', 'permalink-manager')
112
- ),
113
- 'decode_uris' => array(
114
- 'type' => 'single_checkbox',
115
- 'label' => __('Decode URIs', 'permalink-manager'),
116
- 'input_class' => '',
117
- 'description' => __('If enabled, the permalinks with non-ASCII characters may not be recognized in older browsers versions (advanced users only).', 'permalink-manager')
118
- ),*/
119
- 'trailing_slashes' => array(
120
- 'type' => 'select',
121
- 'label' => __('Trailing slashes', 'permalink-manager'),
122
- 'input_class' => 'settings-select',
123
- 'choices' => array(0 => __('Use default settings', 'permalink-manager'), 1 => __('Add trailing slashes', 'permalink-manager'), 10 => __('Add trailing slashes (+ auto-redirect links without them)', 'permalink-manager'), 2 => __('Remove trailing slashes', 'permalink-manager'), 20 => __('Remove trailing slashes (+ auto-redirect links with them)', 'permalink-manager'),),
124
- 'description' => __('This option can be used to alter the native settings and control if trailing slash should be added or removed from the end of posts & terms permalinks.', 'permalink-manager')
125
- ),
126
  'partial_disable' => array(
127
  'type' => 'checkbox',
128
  'label' => __('Disable Permalink Manager functionalities', 'permalink-manager'),
48
  )
49
  )
50
  ),
51
+ 'seo' => array(
52
  'section_name' => __('SEO functions', 'permalink-manager'),
53
  'container' => 'row',
54
  'name' => 'general',
55
  'fields' => array(
 
 
 
 
 
 
 
 
 
 
 
 
56
  'canonical_redirect' => array(
57
  'type' => 'single_checkbox',
58
  'label' => __('Canonical redirect', 'permalink-manager'),
59
  'input_class' => '',
60
  'description' => __('This function allows Wordpress to correct the URLs used by the visitors.', 'permalink-manager')
61
  ),
62
+ 'setup_redirects' => array(
63
+ 'type' => 'single_checkbox',
64
+ 'label' => __('Auto-create "Extra Redirects" for old permalinks', 'permalink-manager'),
65
+ 'input_class' => '',
66
+ 'pro' => true,
67
+ 'disabled' => true,
68
+ 'description' => __('If enabled, the redirects will be automatially created for old custom permalinks, after posts or terms are updated.', 'permalink-manager')
69
+ ),
70
  'redirect' => array(
71
  'type' => 'select',
72
  'label' => __('Redirect', 'permalink-manager'),
73
  'input_class' => 'settings-select',
74
  'choices' => array(0 => __('Disable', 'permalink-manager'), "301" => __('Enable "301 redirect"', 'permalink-manager'), "302" => __('Enable "302 redirect"', 'permalink-manager')),
75
  'description' => __('If enabled - the visitors will be redirected from native permalinks to your custom permalinks.<br /><strong>Only native permalinks & extra redirects will be redirected to new custom permalinks</strong>.', 'permalink-manager')
76
+ ),
77
+ 'trailing_slashes' => array(
78
+ 'type' => 'select',
79
+ 'label' => __('Trailing slashes', 'permalink-manager'),
80
+ 'input_class' => 'settings-select',
81
+ 'choices' => array(0 => __('Use default settings', 'permalink-manager'), 1 => __('Add trailing slashes', 'permalink-manager'), 10 => __('Add trailing slashes (+ auto-redirect links without them)', 'permalink-manager'), 2 => __('Remove trailing slashes', 'permalink-manager'), 20 => __('Remove trailing slashes (+ auto-redirect links with them)', 'permalink-manager'),),
82
+ 'description' => __('This option can be used to alter the native settings and control if trailing slash should be added or removed from the end of posts & terms permalinks.', 'permalink-manager')
83
  )
84
  )
85
  ),
88
  'container' => 'row',
89
  'name' => 'general',
90
  'fields' => array(
 
 
 
 
 
 
 
 
91
  'auto_remove_duplicates' => array(
92
  'type' => 'single_checkbox',
93
  'label' => __('Automatically remove duplicates', 'permalink-manager'),
100
  'input_class' => '',
101
  'description' => __('If enabled, the slugs in the default custom permalinks will be recreated from the post titles.<br />This may cause permalinks duplicates when the post or term title is used more than once.', 'permalink-manager')
102
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  'partial_disable' => array(
104
  'type' => 'checkbox',
105
  'label' => __('Disable Permalink Manager functionalities', 'permalink-manager'),
permalink-manager.php CHANGED
@@ -1,244 +1,242 @@
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.1
8
- * Author: Maciej Bis
9
- * Author URI: http://maciejbis.net/
10
- * License: GPL-2.0+
11
- * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
12
- * Text Domain: permalink-manager
13
- * Domain Path: /languages
14
- */
15
-
16
- // If this file is called directly or plugin is already defined, abort.
17
- if (!defined('WPINC')) {
18
- die;
19
- }
20
-
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.1' );
25
- define( 'PERMALINK_MANAGER_FILE', __FILE__ );
26
- define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
27
- define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
28
- define( 'PERMALINK_MANAGER_URL', untrailingslashit( plugins_url( '', __FILE__ ) ) );
29
- define( 'PERMALINK_MANAGER_WEBSITE', 'http://permalinkmanager.pro?utm_source=plugin' );
30
- define( 'PERMALINK_MANAGER_DONATE', 'https://www.paypal.me/Bismit' );
31
-
32
- class Permalink_Manager_Class {
33
-
34
- public $permalink_manager, $permalink_manager_options_page, $permalink_manager_options;
35
- public $sections, $functions, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
36
-
37
- /**
38
- * Get options from DB, load subclasses & hooks
39
- */
40
  public function __construct() {
41
- $this->include_subclassess();
42
- $this->register_init_hooks();
43
- }
44
-
45
- /**
46
- * Include back-end classess and set their instances
47
- */
48
- function include_subclassess() {
49
- // WP_List_Table needed for post types & taxnomies editors
50
- if( ! class_exists( 'WP_List_Table' ) ) {
51
- require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
52
- }
53
-
54
- $classes = array(
55
- 'core' => array(
56
- 'helper-functions' => 'Permalink_Manager_Helper_Functions',
57
- 'uri-functions-post' => 'Permalink_Manager_URI_Functions_Post',
58
- 'uri-functions-tax' => 'Permalink_Manager_URI_Functions_Tax',
59
- 'admin-functions' => 'Permalink_Manager_Admin_Functions',
60
- 'actions' => 'Permalink_Manager_Actions',
61
- 'third-parties' => 'Permalink_Manager_Third_Parties',
62
- 'core-functions' => 'Permalink_Manager_Core_Functions',
63
- 'pro-functions' => 'Permalink_Manager_Pro_Functions'
64
- ),
65
- 'views' => array(
66
- 'uri-editor' => 'Permalink_Manager_Uri_Editor',
67
- 'tools' => 'Permalink_Manager_Tools',
68
- 'permastructs' => 'Permalink_Manager_Permastructs',
69
- 'settings' => 'Permalink_Manager_Settings',
70
- 'debug' => 'Permalink_Manager_Debug',
71
- 'pro-addons' => 'Permalink_Manager_Pro_Addons',
72
- 'upgrade' => 'Permalink_Manager_Upgrade',
73
- 'uri-editor-tax' => false,
74
- 'uri-editor-post' => false
75
- )
76
- );
77
-
78
- // Load classes and set-up their instances
79
- foreach($classes as $class_type => $classes_array) {
80
- foreach($classes_array as $class => $class_name) {
81
- $filename = PERMALINK_MANAGER_DIR . "/includes/{$class_type}/permalink-manager-{$class}.php";
82
-
83
- if(file_exists($filename)) {
84
- require_once $filename;
85
- if($class_name) { $this->functions[$class] = new $class_name(); }
86
- }
87
- }
88
- }
89
- }
90
-
91
- /**
92
- * Register general hooks
93
- */
94
- public function register_init_hooks() {
95
- // Localize plugin
96
  add_action( 'plugins_loaded', array($this, 'localize_me'), 1 );
97
 
98
  // Load globals & options
99
- add_action( 'plugins_loaded', array($this, 'get_options_and_globals'), 9 );
100
-
101
- // Legacy support
102
- add_action( 'init', array($this, 'legacy_support'), 2 );
103
-
104
- // Default settings & alerts
105
- add_filter( 'permalink-manager-options', array($this, 'default_settings'), 1 );
106
- add_filter( 'permalink-manager-alerts', array($this, 'default_alerts'), 1 );
107
- }
108
-
109
- /**
110
- * Localize this plugin
111
- */
112
- function localize_me() {
113
- load_plugin_textdomain( 'permalink-manager', false, PERMALINK_MANAGER_DIR );
114
- }
115
-
116
- /**
117
- * Get options values & set global
118
- */
119
- public function get_options_and_globals() {
120
- // 1. Globals with data stored in DB
121
- global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $permalink_manager_redirects;
122
-
123
- $this->permalink_manager_options = $permalink_manager_options = apply_filters('permalink-manager-options', get_option('permalink-manager', array()));
124
- $this->permalink_manager_uris = $permalink_manager_uris = apply_filters('permalink-manager-uris', get_option('permalink-manager-uris', array()));
125
- $this->permalink_manager_permastructs = $permalink_manager_permastructs = apply_filters('permalink-manager-permastructs', get_option('permalink-manager-permastructs', array()));
126
- $this->permalink_manager_redirects = $permalink_manager_redirects = apply_filters('permalink-manager-redirects', get_option('permalink-manager-redirects', array()));
127
-
128
- // 2. Globals used to display additional content (eg. alerts)
129
- global $permalink_manager_alerts, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
130
-
131
- $this->permalink_manager_alerts = $permalink_manager_alerts = apply_filters('permalink-manager-alerts', get_option('permalink-manager-alerts', array()));
132
- $this->permalink_manager_before_sections_html = $permalink_manager_before_sections_html = apply_filters('permalink-manager-before-sections', '');
133
  $this->permalink_manager_after_sections_html = $permalink_manager_after_sections_html = apply_filters('permalink-manager-after-sections', '');
134
- }
135
-
136
- /**
137
- * Set the initial/default settings (including "Screen Options")
138
- */
139
- public function default_settings($settings) {
140
- $all_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
141
- $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
142
-
143
- $default_settings = apply_filters('permalink-manager-default-options', array(
144
- 'screen-options' => array(
145
- 'per_page' => 20,
146
- 'post_statuses' => array('publish'),
147
- 'group' => false,
148
- ),
149
- 'general' => array(
150
- 'force_custom_slugs' => 0,
151
- 'auto_update_uris' => 0,
152
- 'case_insensitive_permalinks' => 0,
153
- 'yoast_primary_term' => 1,
154
- 'redirect' => '301',
155
- 'yoast_attachment_redirect' => 1,
156
- 'canonical_redirect' => 1,
157
- 'trailing_slashes' => 0,
158
- 'setup_redirects' => 1,
159
- 'auto_remove_duplicates' => 0,
160
- 'partial_disable' => array(),
161
- 'deep_detect' => 1
162
- ),
163
- 'licence' => array()
164
- ));
165
-
166
- // Apply the default settings (if empty values) in all settings sections
167
- foreach($default_settings as $group_name => $fields) {
168
- foreach($fields as $field_name => $field) {
169
- if(!isset($settings[$group_name][$field_name])) {
170
- $settings[$group_name][$field_name] = $field;
171
- }
172
- }
173
- }
174
-
175
- return $settings;
176
- }
177
-
178
- /**
179
- * Set the initial/default admin notices
180
- */
181
- public function default_alerts($alerts) {
182
- $default_alerts = apply_filters('permalink-manager-default-alerts', array(
183
- 'november' => array(
184
- 'txt' => sprintf(
185
- __("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 \"NOVEMBER\" coupon code!</strong> Valid until 31.11!", "permalink-manager"),
186
- PERMALINK_MANAGER_WEBSITE
187
- ),
188
- 'type' => 'notice-info',
189
- 'show' => 'pro_hide',
190
- 'plugin_only' => true,
191
- 'until' => '2017-11-31'
192
- )
193
- ));
194
-
195
- // Apply the default settings (if empty values) in all settings sections
196
- return $alerts + $default_alerts;
197
- }
198
-
199
- /**
200
- * Temporary hook
201
- */
202
- function legacy_support() {
203
- global $permalink_manager_permastructs, $permalink_manager_options;
204
-
205
- if(isset($permalink_manager_options['base-editor'])) {
206
- $new_options['post_types'] = $permalink_manager_options['base-editor'];
207
- update_option('permalink-manager-permastructs', $new_options);
208
- }
209
- else if(empty($permalink_manager_permastructs['post_types']) && count($permalink_manager_permastructs) > 0) {
210
- $new_options['post_types'] = $permalink_manager_permastructs;
211
- update_option('permalink-manager-permastructs', $new_options);
212
- }
213
-
214
- // Adjust options structure
215
- if(!empty($permalink_manager_options['miscellaneous'])) {
216
- // Get the options direclty from database
217
- $permalink_manager_unfiltered_options = get_option('permalink-manager', array('general' => array(), 'miscellaneous' => array(), 'licence'));
218
-
219
- // Combine general & general
220
- $permalink_manager_unfiltered_options['general'] = array_merge($permalink_manager_unfiltered_options['general'], $permalink_manager_unfiltered_options['miscellaneous']);
221
-
222
- // Move licence key to different section
223
- $permalink_manager_unfiltered_options['licence']['licence_key'] = (!empty($permalink_manager_unfiltered_options['miscellaneous']['license_key'])) ? $permalink_manager_unfiltered_options['miscellaneous']['license_key'] : "";
224
-
225
- // Remove redundant keys
226
- unset($permalink_manager_unfiltered_options['general']['license_key']);
227
- unset($permalink_manager_unfiltered_options['miscellaneous']);
228
- unset($permalink_manager_unfiltered_options['permalink_manager_options']);
229
- unset($permalink_manager_unfiltered_options['_wp_http_referer']);
230
-
231
- // Save the settings in database
232
- update_option('permalink-manager', $permalink_manager_unfiltered_options);
233
- }
234
- }
235
-
236
- }
237
-
238
- /**
239
- * Begins execution of the plugin.
240
- */
241
- function run_permalink_manager() {
242
- $Permalink_Manager_Class = new Permalink_Manager_Class();
243
- }
244
- run_permalink_manager();
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.2
8
+ * Author: Maciej Bis
9
+ * Author URI: http://maciejbis.net/
10
+ * License: GPL-2.0+
11
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
12
+ * Text Domain: permalink-manager
13
+ * Domain Path: /languages
14
+ */
15
+
16
+ // If this file is called directly or plugin is already defined, abort.
17
+ if (!defined('WPINC')) {
18
+ die;
19
+ }
20
+
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.2' );
25
+ define( 'PERMALINK_MANAGER_FILE', __FILE__ );
26
+ define( 'PERMALINK_MANAGER_DIR', untrailingslashit( dirname( __FILE__ ) ) );
27
+ define( 'PERMALINK_MANAGER_BASENAME', plugin_basename(__FILE__) );
28
+ define( 'PERMALINK_MANAGER_URL', untrailingslashit( plugins_url( '', __FILE__ ) ) );
29
+ define( 'PERMALINK_MANAGER_WEBSITE', 'http://permalinkmanager.pro?utm_source=plugin' );
30
+ define( 'PERMALINK_MANAGER_DONATE', 'https://www.paypal.me/Bismit' );
31
+
32
+ class Permalink_Manager_Class {
33
+
34
+ public $permalink_manager, $permalink_manager_options_page, $permalink_manager_options;
35
+ public $sections, $functions, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
36
+
37
+ /**
38
+ * Get options from DB, load subclasses & hooks
39
+ */
40
  public function __construct() {
41
+ $this->include_subclassess();
42
+ $this->register_init_hooks();
43
+ }
44
+
45
+ /**
46
+ * Include back-end classess and set their instances
47
+ */
48
+ function include_subclassess() {
49
+ // WP_List_Table needed for post types & taxnomies editors
50
+ if( ! class_exists( 'WP_List_Table' ) ) {
51
+ require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
52
+ }
53
+
54
+ $classes = array(
55
+ 'core' => array(
56
+ 'helper-functions' => 'Permalink_Manager_Helper_Functions',
57
+ 'uri-functions-post' => 'Permalink_Manager_URI_Functions_Post',
58
+ 'uri-functions-tax' => 'Permalink_Manager_URI_Functions_Tax',
59
+ 'admin-functions' => 'Permalink_Manager_Admin_Functions',
60
+ 'actions' => 'Permalink_Manager_Actions',
61
+ 'third-parties' => 'Permalink_Manager_Third_Parties',
62
+ 'core-functions' => 'Permalink_Manager_Core_Functions',
63
+ 'pro-functions' => 'Permalink_Manager_Pro_Functions'
64
+ ),
65
+ 'views' => array(
66
+ 'uri-editor' => 'Permalink_Manager_Uri_Editor',
67
+ 'tools' => 'Permalink_Manager_Tools',
68
+ 'permastructs' => 'Permalink_Manager_Permastructs',
69
+ 'settings' => 'Permalink_Manager_Settings',
70
+ 'debug' => 'Permalink_Manager_Debug',
71
+ 'pro-addons' => 'Permalink_Manager_Pro_Addons',
72
+ 'upgrade' => 'Permalink_Manager_Upgrade',
73
+ 'uri-editor-tax' => false,
74
+ 'uri-editor-post' => false
75
+ )
76
+ );
77
+
78
+ // Load classes and set-up their instances
79
+ foreach($classes as $class_type => $classes_array) {
80
+ foreach($classes_array as $class => $class_name) {
81
+ $filename = PERMALINK_MANAGER_DIR . "/includes/{$class_type}/permalink-manager-{$class}.php";
82
+
83
+ if(file_exists($filename)) {
84
+ require_once $filename;
85
+ if($class_name) { $this->functions[$class] = new $class_name(); }
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Register general hooks
93
+ */
94
+ public function register_init_hooks() {
95
+ // Localize plugin
96
  add_action( 'plugins_loaded', array($this, 'localize_me'), 1 );
97
 
98
  // Load globals & options
99
+ add_action( 'plugins_loaded', array($this, 'get_options_and_globals'), 9 );
100
+
101
+ // Legacy support
102
+ add_action( 'init', array($this, 'legacy_support'), 2 );
103
+
104
+ // Default settings & alerts
105
+ add_filter( 'permalink-manager-options', array($this, 'default_settings'), 1 );
106
+ add_filter( 'permalink-manager-alerts', array($this, 'default_alerts'), 1 );
107
+ }
108
+
109
+ /**
110
+ * Localize this plugin
111
+ */
112
+ function localize_me() {
113
+ load_plugin_textdomain( 'permalink-manager', false, PERMALINK_MANAGER_DIR );
114
+ }
115
+
116
+ /**
117
+ * Get options values & set global
118
+ */
119
+ public function get_options_and_globals() {
120
+ // 1. Globals with data stored in DB
121
+ global $permalink_manager_options, $permalink_manager_uris, $permalink_manager_permastructs, $permalink_manager_redirects;
122
+
123
+ $this->permalink_manager_options = $permalink_manager_options = apply_filters('permalink-manager-options', get_option('permalink-manager', array()));
124
+ $this->permalink_manager_uris = $permalink_manager_uris = apply_filters('permalink-manager-uris', get_option('permalink-manager-uris', array()));
125
+ $this->permalink_manager_permastructs = $permalink_manager_permastructs = apply_filters('permalink-manager-permastructs', get_option('permalink-manager-permastructs', array()));
126
+ $this->permalink_manager_redirects = $permalink_manager_redirects = apply_filters('permalink-manager-redirects', get_option('permalink-manager-redirects', array()));
127
+
128
+ // 2. Globals used to display additional content (eg. alerts)
129
+ global $permalink_manager_alerts, $permalink_manager_before_sections_html, $permalink_manager_after_sections_html;
130
+
131
+ $this->permalink_manager_alerts = $permalink_manager_alerts = apply_filters('permalink-manager-alerts', get_option('permalink-manager-alerts', array()));
132
+ $this->permalink_manager_before_sections_html = $permalink_manager_before_sections_html = apply_filters('permalink-manager-before-sections', '');
133
  $this->permalink_manager_after_sections_html = $permalink_manager_after_sections_html = apply_filters('permalink-manager-after-sections', '');
134
+ }
135
+
136
+ /**
137
+ * Set the initial/default settings (including "Screen Options")
138
+ */
139
+ public function default_settings($settings) {
140
+ $all_taxonomies = Permalink_Manager_Helper_Functions::get_taxonomies_array();
141
+ $all_post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
142
+
143
+ $default_settings = apply_filters('permalink-manager-default-options', array(
144
+ 'screen-options' => array(
145
+ 'per_page' => 20,
146
+ 'post_statuses' => array('publish'),
147
+ 'group' => false,
148
+ ),
149
+ 'general' => array(
150
+ 'force_custom_slugs' => 0,
151
+ 'auto_update_uris' => 0,
152
+ 'case_insensitive_permalinks' => 0,
153
+ 'redirect' => '301',
154
+ 'canonical_redirect' => 1,
155
+ 'trailing_slashes' => 0,
156
+ 'setup_redirects' => 1,
157
+ 'auto_remove_duplicates' => 0,
158
+ 'partial_disable' => array(),
159
+ 'deep_detect' => 1
160
+ ),
161
+ 'licence' => array()
162
+ ));
163
+
164
+ // Apply the default settings (if empty values) in all settings sections
165
+ foreach($default_settings as $group_name => $fields) {
166
+ foreach($fields as $field_name => $field) {
167
+ if(!isset($settings[$group_name][$field_name])) {
168
+ $settings[$group_name][$field_name] = $field;
169
+ }
170
+ }
171
+ }
172
+
173
+ return $settings;
174
+ }
175
+
176
+ /**
177
+ * Set the initial/default admin notices
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
+
193
+ // Apply the default settings (if empty values) in all settings sections
194
+ return (array) $alerts + (array) $default_alerts;
195
+ }
196
+
197
+ /**
198
+ * Temporary hook
199
+ */
200
+ function legacy_support() {
201
+ global $permalink_manager_permastructs, $permalink_manager_options;
202
+
203
+ if(isset($permalink_manager_options['base-editor'])) {
204
+ $new_options['post_types'] = $permalink_manager_options['base-editor'];
205
+ update_option('permalink-manager-permastructs', $new_options);
206
+ }
207
+ else if(empty($permalink_manager_permastructs['post_types']) && count($permalink_manager_permastructs) > 0) {
208
+ $new_options['post_types'] = $permalink_manager_permastructs;
209
+ update_option('permalink-manager-permastructs', $new_options);
210
+ }
211
+
212
+ // Adjust options structure
213
+ if(!empty($permalink_manager_options['miscellaneous'])) {
214
+ // Get the options direclty from database
215
+ $permalink_manager_unfiltered_options = get_option('permalink-manager', array('general' => array(), 'miscellaneous' => array(), 'licence'));
216
+
217
+ // Combine general & general
218
+ $permalink_manager_unfiltered_options['general'] = array_merge($permalink_manager_unfiltered_options['general'], $permalink_manager_unfiltered_options['miscellaneous']);
219
+
220
+ // Move licence key to different section
221
+ $permalink_manager_unfiltered_options['licence']['licence_key'] = (!empty($permalink_manager_unfiltered_options['miscellaneous']['license_key'])) ? $permalink_manager_unfiltered_options['miscellaneous']['license_key'] : "";
222
+
223
+ // Remove redundant keys
224
+ unset($permalink_manager_unfiltered_options['general']['license_key']);
225
+ unset($permalink_manager_unfiltered_options['miscellaneous']);
226
+ unset($permalink_manager_unfiltered_options['permalink_manager_options']);
227
+ unset($permalink_manager_unfiltered_options['_wp_http_referer']);
228
+
229
+ // Save the settings in database
230
+ update_option('permalink-manager', $permalink_manager_unfiltered_options);
231
+ }
232
+ }
233
+
234
+ }
235
+
236
+ /**
237
+ * Begins execution of the plugin.
238
+ */
239
+ function run_permalink_manager() {
240
+ $Permalink_Manager_Class = new Permalink_Manager_Class();
241
+ }
242
+ run_permalink_manager();