PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 2.2.9.7
Permalink Manager Lite v2.2.9.7
2.5.4 2.5.3.4 2.2.18 2.2.19.2 2.2.19.3 2.2.19.3.1 2.2.2 2.2.20 2.2.20.1 2.2.20.3 2.2.4 2.2.5 2.2.6 2.2.7.2 2.2.7.3 2.2.7.5 2.2.7.6 2.2.8.4 2.2.8.5 2.2.8.6 2.2.8.7 2.2.8.9 2.2.9.1 2.2.9.2 2.2.9.2.1 2.2.9.3 2.2.9.4 2.2.9.6 2.2.9.7 2.2.9.9 2.3.0 2.3.1.1 2.4.0 2.4.1 2.4.1.2 2.4.1.3 2.4.1.4 2.4.1.5 2.4.1.6 2.4.2 2.4.2.1 2.4.3 2.4.3.1 2.4.3.2 2.4.3.3 2.4.3.4 2.4.4 2.4.4.1 2.4.4.2 2.4.4.3 2.5.0 2.5.1 2.5.1.1 2.5.1.2 2.5.1.3 2.5.1.4 2.5.2 2.5.2.1 2.5.2.2 2.5.2.3 2.5.2.4 2.5.3 2.5.3.1 2.5.3.2 2.5.3.3 trunk 0.2 0.3 0.3.1 0.3.2 0.3.3 0.3.4 0.4 0.4.1 0.4.2 0.4.3 0.4.4 0.4.6 0.4.7 0.4.8 0.4.9 0.5.3 0.5.4 1.0.0 1.0.1 1.0.4 1.1.0 1.1.1 1.1.2 1.11.6.3 2.0.0 2.0.3 2.0.4 2.0.4.3 2.0.5.1 2.0.5.2 2.0.5.3 2.0.5.3.1 2.0.5.4 2.0.5.4a 2.0.5.5 2.0.5.6 2.0.5.6.1 2.0.5.7 2.0.5.9a 2.0.6.2.1 2.0.6.2a 2.0.6.3 2.1.0 2.1.1 2.1.2.4 2.2.0 2.2.1.1 2.2.1.2 2.2.11 2.2.12 2.2.13.1 2.2.14 2.2.15.1 2.2.16 2.2.17
permalink-manager / includes / core / permalink-manager-helper-functions.php
permalink-manager / includes / core Last commit date
permalink-manager-actions.php 5 years ago permalink-manager-admin-functions.php 5 years ago permalink-manager-core-functions.php 5 years ago permalink-manager-debug.php 5 years ago permalink-manager-gutenberg.php 5 years ago permalink-manager-helper-functions.php 5 years ago permalink-manager-language-plugins.php 5 years ago permalink-manager-third-parties.php 5 years ago permalink-manager-uri-functions-post.php 5 years ago permalink-manager-uri-functions.php 5 years ago
permalink-manager-helper-functions.php
713 lines
1 <?php
2
3 /**
4 * Additional functions used in classes and another subclasses
5 */
6 class Permalink_Manager_Helper_Functions extends Permalink_Manager_Class {
7
8 public function __construct() {
9 add_action('plugins_loaded', array($this, 'init'), 5);
10 }
11
12 public function init() {
13 // Replace empty placeholder tags & remove BOM
14 add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5);
15 add_filter( 'permalink_manager_filter_default_term_uri', array($this, 'replace_empty_placeholder_tags'), 10, 5);
16
17 // Clear the final default URIs
18 add_filter( 'permalink_manager_filter_default_term_uri', array($this, 'clear_single_uri'), 20);
19 add_filter( 'permalink_manager_filter_default_post_uri', array($this, 'clear_single_uri'), 20);
20
21 // Reload the globals when the blog is switched (multisite)
22 add_action('switch_blog', array($this, 'reload_globals_in_network'), 9);
23 }
24
25 /**
26 * Support for multidimensional arrays - array_map()
27 */
28 static function multidimensional_array_map($function, $input) {
29 $output = array();
30
31 if(is_array($input)) {
32 foreach ($input as $key => $val) {
33 $output[$key] = (is_array($val) ? self::multidimensional_array_map($function, $val) : $function($val));
34 }
35 } else {
36 $output = $function($input);
37 }
38
39 return $output;
40 }
41
42 /**
43 * Get primary term
44 */
45 static function get_primary_term($post_id, $taxonomy, $slug_only = true) {
46 global $permalink_manager_options;
47
48 $primary_term_enabled = apply_filters('permalink_manager_primary_term', true);
49
50 if(!$primary_term_enabled) { return; }
51
52 // A. Yoast SEO
53 if(class_exists('WPSEO_Primary_Term')) {
54 $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
55 $primary_term = get_term($primary_term->get_primary_term());
56 }
57 // B. The SEO Framework
58 else if(function_exists('the_seo_framework')) {
59 $primary_term = the_seo_framework()->get_primary_term($post_id, $taxonomy);
60 }
61 // C. RankMath
62 else if(class_exists('RankMath')) {
63 $primary_cat_id = get_post_meta($post_id, "rank_math_primary_{$taxonomy}", true);
64 $primary_term = (!empty($primary_cat_id)) ? get_term($primary_cat_id, $taxonomy) : '';
65 }
66 // D. SEOPress
67 else if(function_exists('seopress_init') && $taxonomy == 'category') {
68 $primary_cat_id = get_post_meta($post_id, '_seopress_robots_primary_cat', true);
69 $primary_term = (!empty($primary_cat_id)) ? get_term($primary_cat_id, 'category') : '';
70 }
71
72 if(!empty($primary_term) && !is_wp_error($primary_term)) {
73 return ($slug_only) ? $primary_term->slug : $primary_term;
74 } else {
75 return;
76 }
77 }
78
79 /**
80 * Get lowest level term/post
81 */
82 static function get_lowest_element($first_element, $elements) {
83 if(!empty($elements) && !empty($first_element)) {
84 // Get the ID of first element
85 if(!empty($first_element->term_id)) {
86 $first_element_id = $first_element->term_id;
87 $parent_key = 'parent';
88 } else if(!empty($first_element->ID)) {
89 $first_element_id = $first_element->ID;
90 $parent_key = 'post_parent';
91 } else if(is_numeric($first_element)) {
92 $first_element_id = $first_element;
93 $parent_key = 'post_parent';
94 } else {
95 return false;
96 }
97
98 $children = wp_filter_object_list($elements, array($parent_key => $first_element_id));
99 if(!empty($children)) {
100 // Get the first term
101 $child_term = reset($children);
102 $first_element = self::get_lowest_element($child_term, $elements);
103 }
104 }
105 return $first_element;
106 }
107
108 /**
109 * Get term full slug
110 */
111 static function get_term_full_slug($term, $terms, $mode = false, $native_uri = false) {
112 global $permalink_manager_uris;
113
114 // Check if term is not empty
115 if(empty($term->taxonomy)) { return ''; }
116
117 // Get taxonomy
118 $taxonomy = $term->taxonomy;
119
120 // Check if mode is set
121 if(empty($mode)) {
122 $mode = (is_taxonomy_hierarchical($taxonomy)) ? 2 : 4;
123 }
124
125 // A. Inherit the custom permalink from the term
126 if($mode == 1) {
127 $term_slug = $permalink_manager_uris["tax-{$term->term_id}"];
128 }
129 // B. Hierarhcical taxonomy base
130 else if($mode == 2) {
131 $ancestors = get_ancestors($term->term_id, $taxonomy, 'taxonomy');
132 $hierarchical_slugs = array();
133
134 foreach((array) $ancestors as $ancestor) {
135 $ancestor_term = get_term($ancestor, $taxonomy);
136 $hierarchical_slugs[] = ($native_uri) ? $ancestor_term->slug : self::force_custom_slugs($ancestor_term->slug, $ancestor_term);
137 }
138 $hierarchical_slugs = array_reverse($hierarchical_slugs);
139 $term_slug = implode('/', $hierarchical_slugs);
140
141 // Append the term slug now
142 $last_term_slug = ($native_uri) ? $term->slug : self::force_custom_slugs($term->slug, $term);
143 $term_slug = "{$term_slug}/{$last_term_slug}";
144 }
145 // C. Force flat taxonomy base - get highest level term (if %taxonomy_top% tag is used)
146 else if($mode == 3) {
147 if(!empty($term->parent)) {
148 $ancestors = get_ancestors($term->term_id, $taxonomy, 'taxonomy');
149
150 if(is_array($ancestors)) {
151 $top_ancestor = end($ancestors);
152 $top_ancestor_term = get_term($top_ancestor, $taxonomy);
153 $single_term = (!empty($top_ancestor_term->slug)) ? $top_ancestor_term : $term;
154 }
155 }
156
157 $term_slug = (!empty($single_term->slug)) ? self::force_custom_slugs($single_term->slug, $single_term) : $term->slug;
158 }
159 // D. Force flat taxonomy base - get primary or lowest level term (if term is non-hierarchical or %taxonomy_flat% tag is used)
160 else {
161 if(!empty($term->slug)) {
162 $term_slug = ($native_uri) ? $term->slug : Permalink_Manager_Helper_Functions::force_custom_slugs($term->slug, $term);
163 } else {
164 foreach($terms as $single_term) {
165 if($single_term->parent == 0) {
166 $term_slug = self::force_custom_slugs($single_term->slug, $single_term);
167 break;
168 }
169 }
170 }
171 }
172
173 return (!empty($term_slug)) ? $term_slug : "";
174 }
175
176 /**
177 * Allow to disable post types and taxonomies
178 */
179 static function get_disabled_post_types($include_user_excluded = true) {
180 global $wp_post_types, $permalink_manager_options;
181
182 $disabled_post_types = array(
183 'revision', 'algolia_task', 'fl_builder', 'fl-builder', 'fl-builder-template', 'fl-theme-layout', 'fusion_tb_layout', 'fusion_tb_section', 'fusion_template', 'fusion_element', 'wc_product_tab', 'wc_voucher', 'wc_voucher_template',
184 'sliders', 'thirstylink', 'elementor_library', 'elementor_menu_item', 'cms_block', 'nooz_coverage'
185 );
186
187 // 1. Disable post types that are not publicly_queryable
188 foreach($wp_post_types as $post_type) {
189 $is_publicly_queryable = (!empty($post_type->publicly_queryable) || (!empty($post_type->public) && !empty($post_type->rewrite))) ? true : false;
190
191 if(!$is_publicly_queryable && !in_array($post_type->name, array('post', 'page', 'attachment'))) {
192 $disabled_post_types[] = $post_type->name;
193 }
194 }
195
196 // 2. Add post types disabled by user
197 if($include_user_excluded) {
198 $disabled_post_types = (!empty($permalink_manager_options['general']['partial_disable']['post_types'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['post_types'], $disabled_post_types) : $disabled_post_types;
199 }
200
201 return apply_filters('permalink_manager_disabled_post_types', $disabled_post_types);
202 }
203
204 static function get_disabled_taxonomies($include_user_excluded = true) {
205 global $wp_taxonomies, $permalink_manager_options;
206
207 $disabled_taxonomies = array(
208 'product_shipping_class', 'post_status', 'fl-builder-template-category', 'post_format', 'nav_menu', 'language'
209 );
210
211 // 1. Disable taxonomies that are not publicly_queryable
212 foreach($wp_taxonomies as $taxonomy) {
213 $is_publicly_queryable = (!empty($taxonomy->publicly_queryable) || (!empty($taxonomy->public) && !empty($taxonomy->rewrite))) ? true : false;
214
215 if(!$is_publicly_queryable && !in_array($taxonomy->name, array('category', 'post_tag'))) {
216 $disabled_taxonomies[] = $taxonomy->name;
217 }
218 }
219
220 // 2. Add taxonomies disabled by user
221 if($include_user_excluded) {
222 $disabled_taxonomies = (!empty($permalink_manager_options['general']['partial_disable']['taxonomies'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['taxonomies'], $disabled_taxonomies) : $disabled_taxonomies;
223 }
224
225 return apply_filters('permalink_manager_disabled_taxonomies', $disabled_taxonomies);
226 }
227
228 static public function is_disabled($content_name, $content_type = 'post_type', $check_if_exists = true) {
229 $out = false;
230
231 if($content_type == 'post_type') {
232 $disabled_post_types = self::get_disabled_post_types();
233 $post_type_exists = ($check_if_exists) ? post_type_exists($content_name) : true;
234 $out = ((is_array($disabled_post_types) && in_array($content_name, $disabled_post_types)) || empty($post_type_exists)) ? true : false;
235 } else {
236 $disabled_taxonomies = self::get_disabled_taxonomies();
237 $taxonomy_exists = ($check_if_exists) ? taxonomy_exists($content_name) : true;
238 $out = ((is_array($disabled_taxonomies) && in_array($content_name, $disabled_taxonomies)) || empty($taxonomy_exists)) ? true : false;
239 }
240
241 return $out;
242 }
243
244 /**
245 * Get all post types supported by Permalink Manager
246 */
247 static function get_post_types_array($format = null, $cpt = null, $include_user_excluded = false) {
248 global $wp_post_types;
249
250 $post_types_array = array();
251 $disabled_post_types = self::get_disabled_post_types(!$include_user_excluded);
252
253 foreach($wp_post_types as $post_type) {
254 $post_types_array[$post_type->name] = ($format == 'full') ? array('label' => $post_type->labels->name, 'name' => $post_type->name) : $post_type->labels->name;
255 }
256
257 if(is_array($disabled_post_types)) {
258 foreach($disabled_post_types as $post_type) {
259 if(!empty($post_types_array[$post_type])) {
260 unset($post_types_array[$post_type]);
261 }
262 }
263 }
264
265 return (empty($cpt)) ? $post_types_array : $post_types_array[$cpt];
266 }
267
268 /**
269 * Get all taxonomies supported by Permalink Manager
270 */
271 static function get_taxonomies_array($format = null, $tax = null, $prefix = false, $include_user_excluded = false, $settings = false) {
272 global $wp_taxonomies;
273
274 $taxonomies_array = array();
275 $disabled_taxonomies = self::get_disabled_taxonomies(!$include_user_excluded);
276
277 foreach($wp_taxonomies as $taxonomy) {
278 $key = ($prefix) ? "tax-{$taxonomy->name}" : $taxonomy->name;
279 $taxonomy_name = (!empty($taxonomy->labels->name)) ? $taxonomy->labels->name : '-';
280
281 $taxonomies_array[$taxonomy->name] = ($format == 'full') ? array('label' => $taxonomy->labels->name, 'name' => $taxonomy->name) : $taxonomy_name;
282 }
283
284 if(is_array($disabled_taxonomies)) {
285 foreach($disabled_taxonomies as $taxonomy) {
286 if(!empty($taxonomies_array[$taxonomy])) {
287 unset($taxonomies_array[$taxonomy]);
288 }
289 }
290 }
291
292 ksort($taxonomies_array);
293
294 return (empty($tax)) ? $taxonomies_array : $taxonomies_array[$tax];
295 }
296
297 /**
298 * Get all post statuses supported by Permalink Manager
299 */
300 static function get_post_statuses() {
301 $post_statuses = get_post_statuses();
302
303 return apply_filters('permalink_manager_post_statuses', $post_statuses);
304 }
305
306 /**
307 * Get permastruct
308 */
309 static function get_default_permastruct($post_type = 'page', $remove_post_tag = false) {
310 global $wp_rewrite;
311
312 // Get default permastruct
313 if($post_type == 'page') {
314 $permastruct = $wp_rewrite->get_page_permastruct();
315 } else if($post_type == 'post') {
316 $permastruct = get_option('permalink_structure');
317 } else {
318 $permastruct = $wp_rewrite->get_extra_permastruct($post_type);
319 }
320
321 return ($remove_post_tag) ? trim(str_replace(array("%postname%", "%pagename%", "%{$post_type}%"), "", $permastruct), "/") : $permastruct;
322 }
323
324 /**
325 * Get all endpoints
326 */
327 static function get_endpoints() {
328 global $wp_rewrite;
329
330 $pagination_endpoint = (!empty($wp_rewrite->pagination_base)) ? $wp_rewrite->pagination_base : 'page';
331
332 // Start with default endpoints
333 $endpoints = "{$pagination_endpoint}|feed|embed|attachment|trackback|filter";
334
335 if(!empty($wp_rewrite->endpoints)) {
336 foreach($wp_rewrite->endpoints as $endpoint) {
337 $endpoints .= "|{$endpoint[1]}";
338 }
339 }
340
341 return apply_filters("permalink_manager_endpoints", str_replace("/", "\/", $endpoints));
342 }
343
344 /**
345 * Structure Tags & Rewrite functions
346 */
347 static function get_all_structure_tags($code = true, $seperator = ', ', $hide_slug_tags = true) {
348 global $wp_rewrite;
349
350 $tags = $wp_rewrite->rewritecode;
351
352 // Hide slug tags
353 if($hide_slug_tags) {
354 $post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
355 foreach($post_types as $post_type => $post_type_name) {
356 $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
357 // Find key with post type tag from rewritecode
358 $key = array_search($post_type_tag, $tags);
359 if($key) { unset($tags[$key]); }
360 }
361 }
362
363 // Extra tags
364 $tags[] = '%taxonomy%';
365 $tags[] = '%post_type%';
366 $tags[] = '%term_id%';
367 $tags[] = '%monthname%';
368
369 foreach($tags as &$tag) {
370 $tag = ($code) ? "<code>{$tag}</code>" : "{$tag}";
371 }
372 $output = implode($seperator, $tags);
373
374 return "<span class=\"structure-tags-list\">{$output}</span>";
375 }
376
377 /**
378 * Get endpoint used to mark the postname or its equivalent for custom post types and pages in permastructures
379 */
380 static function get_post_tag($post_type) {
381 // Get the post type (with fix for posts & pages)
382 if($post_type == 'page') {
383 $post_type_tag = '%pagename%';
384 } else if ($post_type == 'post') {
385 $post_type_tag = '%postname%';
386 } else {
387 $post_type_tag = "%{$post_type}%";
388 }
389 return $post_type_tag;
390 }
391
392 /**
393 * Find taxonomy name using "term_id"
394 */
395 static function get_tax_name($term, $term_by = 'id') {
396 $term_object = get_term_by($term_by, $term);
397 return (isset($term_object->taxonomy)) ? $term_object->taxonomy : '';
398 }
399
400 /**
401 * Get permalink base (home URL)
402 */
403 public static function get_permalink_base($element = null) {
404 return apply_filters('permalink_manager_filter_permalink_base', trim(get_option('home'), "/"), $element);
405 }
406
407 /**
408 * Remove post tag from permastructure
409 */
410 static function remove_post_tag($permastruct) {
411 $post_types = self::get_post_types_array('full');
412
413 // Get all post tags
414 $post_tags = array("%postname%", "%pagename%");
415 foreach($post_types as $post_type) {
416 $post_tags[] = "%{$post_type['name']}%";
417 }
418
419 $permastruct = str_replace($post_tags, "", $permastruct);
420 return trim($permastruct, "/");
421 }
422
423 /**
424 * Get front-page ID
425 */
426 static function is_front_page($page_id) {
427 $front_page_id = get_option('page_on_front');
428 $bool = (!empty($front_page_id) && $page_id == $front_page_id) ? true : false;
429
430 return apply_filters('permalink_manager_is_front_page', $bool, $page_id, $front_page_id);
431 }
432
433 /**
434 * Sanitize multidimensional array
435 */
436 static function sanitize_array($data = array()) {
437 if (!is_array($data) || !count($data)) {
438 return array();
439 }
440
441 foreach ($data as $k => $v) {
442 if (!is_array($v) && !is_object($v)) {
443 $data[$k] = htmlspecialchars(trim($v));
444 }
445 if (is_array($v)) {
446 $data[$k] = self::sanitize_array($v);
447 }
448 }
449 return $data;
450 }
451
452 /**
453 * Encode URI and keep special characters
454 */
455 static function encode_uri($uri) {
456 return str_replace(array('%2F', '%2C', '%7C', '%2B'), array('/', ',', '|', '+'), urlencode($uri));
457 }
458
459 /**
460 * Slugify function
461 */
462 public static function sanitize_title($str, $keep_percent_sign = false, $force_lowercase = null, $sanitize_slugs = null) {
463 global $permalink_manager_options;
464
465 // Foree lowercase & hyphens
466 $force_lowercase = (!is_null($force_lowercase)) ? $force_lowercase : apply_filters('permalink_manager_force_lowercase_uris', true);
467
468 if(is_null($sanitize_slugs)) {
469 $sanitize_slugs = (!empty($permalink_manager_options['general']['disable_slug_sanitization'])) ? false : true;
470 }
471
472 // Remove accents & entities
473 $clean = (empty($permalink_manager_options['general']['keep_accents'])) ? remove_accents($str) : $str;
474 $clean = str_replace(array('&lt', '&gt', '&amp'), '', $clean);
475
476 $percent_sign = ($keep_percent_sign) ? "\%" : "";
477 $sanitize_regex = apply_filters("permalink_manager_sanitize_regex", "/[^\p{Xan}a-zA-Z0-9{$percent_sign}\/_\.|+, -]/ui", $percent_sign);
478 $clean = preg_replace($sanitize_regex, '', $clean);
479 $clean = ($force_lowercase) ? strtolower($clean) : $clean;
480
481 // Remove amperand
482 $clean = str_replace(array('%26', '&'), '', $clean);
483
484 // Remove special characters
485 if($sanitize_slugs !== false) {
486 $clean = preg_replace("/[\s|+-]+/", "-", $clean);
487 $clean = preg_replace("/[,]+/", "", $clean);
488 $clean = preg_replace('/([\.]+)(?![a-z]{3,4}$)/i', '', $clean);
489 $clean = preg_replace('/([-\s+]\/[-\s+])/', '-', $clean);
490 } else {
491 $clean = preg_replace("/[\s]+/", "-", $clean);
492 }
493
494 // Remove widow & duplicated slashes
495 $clean = preg_replace('/([-]*[\/]+[-]*)/', '/', $clean);
496 $clean = preg_replace('/([\/]+)/', '/', $clean);
497
498 // Trim slashes, dashes and whitespaces
499 $clean = trim($clean, " /-");
500
501 return $clean;
502 }
503
504 /**
505 * Replace empty placeholder tags & remove BOM
506 */
507 public static function replace_empty_placeholder_tags($default_uri, $native_slug = "", $element = "", $slug = "", $native_uri = "") {
508 // Do not affect native URIs
509 if($native_uri == true) { return $default_uri; }
510
511 // Remove the BOM
512 $default_uri = str_replace(array("\xEF\xBB\xBF", "%ef%bb%bf"), '', $default_uri);
513
514 // Encode the URI before placeholders are removed
515 $chunks = explode('/', $default_uri);
516 foreach ($chunks as &$chunk) {
517 if(preg_match("/^(%.+?%)$/", $chunk) == false) {
518 $chunk = rawurldecode($chunk);
519 }
520 }
521 $default_uri = implode("/", $chunks);
522
523 $empty_tag_replacement = apply_filters('permalink_manager_empty_tag_replacement', null, $element);
524 $default_uri = ($empty_tag_replacement || is_null($empty_tag_replacement)) ? str_replace("//", "/", preg_replace("/%(.+?)%/", $empty_tag_replacement, $default_uri)) : $default_uri;
525
526 return trim($default_uri, "/");
527 }
528
529 /**
530 * Clear/Sanitize the URI
531 */
532 public static function clear_single_uri($uri) {
533 return self::sanitize_title($uri, true);
534 }
535
536 /**
537 * Remove all slashes
538 */
539 public static function remove_slashes($uri) {
540 return preg_replace("/[\/]+/", "", $uri);
541 }
542
543 /**
544 * Force custom slugs
545 */
546 public static function force_custom_slugs($slug, $object, $flat = false) {
547 global $permalink_manager_options, $permalink_manager_uris;
548
549 $force_custom_slugs = (!empty($permalink_manager_options['general']['force_custom_slugs'])) ? $permalink_manager_options['general']['force_custom_slugs'] : false;
550 $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
551
552 if($force_custom_slugs) {
553 // A. Custom slug (title)
554 if($force_custom_slugs == 1) {
555 $title = (!empty($object->name)) ? $object->name : $object->post_title;
556 $title = self::remove_slashes($title);
557
558 $new_slug = self::sanitize_title($title, false, null, null);
559 }
560 // B. Custom slug (custom permalink)
561 else {
562 $object_id = (!empty($object->term_id)) ? "tax-{$object->term_id}" : $object->ID;
563 $new_slug = (!empty($permalink_manager_uris[$object_id])) ? basename($permalink_manager_uris[$object_id]) : '';
564 }
565
566 $slug = (!empty($new_slug)) ? preg_replace('/([^\/]+)$/', $new_slug, $slug) : $slug;
567 }
568
569 if($flat) {
570 $slug = preg_replace("/([^\/]+)(.*)/", "$1", $slug);
571 }
572
573 return $slug;
574 }
575
576 public static function element_exists($element_id) {
577 global $wpdb;
578
579 if(strpos($element_id, 'tax-') !== false) {
580 $term_id = intval(preg_replace("/[^0-9]/", "", $element_id));
581 $element_exists = $wpdb->get_var( "SELECT * FROM {$wpdb->prefix}terms WHERE term_id = {$term_id}" );
582 } else {
583 $element_exists = $wpdb->get_var( "SELECT * FROM {$wpdb->prefix}posts WHERE ID = {$element_id} AND post_status NOT IN ('auto-draft', 'trash') AND post_type != 'nav_menu_item'" );
584 }
585
586 return (!empty($element_exists)) ? $element_exists : false;
587 }
588
589 /**
590 * Detect duplicates
591 */
592 public static function get_all_duplicates($include_custom_uris = true) {
593 global $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wpdb;
594
595 // Make sure that both variables are arrays
596 $all_uris = ($include_custom_uris && is_array($permalink_manager_uris)) ? $permalink_manager_uris : array();
597 $permalink_manager_redirects = (is_array($permalink_manager_redirects)) ? $permalink_manager_redirects : array();
598
599 // Convert redirects list, so it can be merged with $permalink_manager_uris
600 foreach($permalink_manager_redirects as $element_id => $redirects) {
601 if(is_array($redirects)) {
602 foreach($redirects as $index => $uri) {
603 $all_uris["redirect-{$index}_{$element_id}"] = $uri;
604 }
605 }
606 }
607
608 // Count duplicates
609 $duplicates_removed = 0;
610 $duplicates_groups = array();
611 $duplicates_list = array_count_values($all_uris);
612 $duplicates_list = array_filter($duplicates_list, function ($x) { return $x >= 2; });
613
614 // Assign keys to duplicates (group them)
615 if(count($duplicates_list) > 0) {
616 foreach($duplicates_list as $duplicated_uri => $count) {
617 $duplicated_ids = array_keys($all_uris, $duplicated_uri);
618
619 // Ignore duplicates in different langauges
620 if(self::is_uri_duplicated($duplicated_uri, $duplicated_ids[0], $duplicated_ids)) {
621 $duplicates_groups[$duplicated_uri] = $duplicated_ids;
622 }
623 }
624 }
625
626 return $duplicates_groups;
627 }
628
629 /**
630 * Check if a single URI is duplicated
631 */
632 public static function is_uri_duplicated($uri, $element_id, $duplicated_ids = array()) {
633 global $permalink_manager_uris;
634
635 if(empty($uri) || empty($element_id) || empty($permalink_manager_uris)) { return false; }
636
637 $uri = trim(trim(sanitize_text_field($uri)), "/");
638 $element_id = sanitize_text_field($element_id);
639
640 // Keep the URIs in a separate array just here
641 if(!empty($duplicated_ids)) {
642 $all_duplicates = $duplicated_ids;
643 } else if(in_array($uri, $permalink_manager_uris)) {
644 $all_duplicates = (array) array_keys($permalink_manager_uris, $uri);
645 }
646
647 if(!empty($all_duplicates)) {
648 // Get the language code of current element
649 $this_uri_lang = Permalink_Manager_Language_Plugins::get_language_code($element_id);
650
651 foreach($all_duplicates as $key => $duplicated_id) {
652 // Ignore custom redirects
653 if(strpos($key, 'redirect-') !== false) {
654 unset($all_duplicates[$key]);
655 continue;
656 }
657
658 if($this_uri_lang) {
659 $duplicated_uri_lang = Permalink_Manager_Language_Plugins::get_language_code($duplicated_id);
660 }
661
662 // Ignore the URI for requested element and other elements in other languages to prevent the false alert
663 if((!empty($duplicated_uri_lang) && $duplicated_uri_lang !== $this_uri_lang) || $element_id == $duplicated_id) {
664 unset($all_duplicates[$key]);
665 }
666 }
667
668 return (count($all_duplicates) > 0) ? true : false;
669 } else {
670 return false;
671 }
672 }
673
674 /**
675 * URI Search
676 */
677 public static function search_uri($search_query, $content_type = null) {
678 global $permalink_manager_uris;
679
680 $found = array();
681 $search_query = preg_quote($search_query, '/');
682
683 foreach($permalink_manager_uris as $id => $uri) {
684 if(preg_match("/\b$search_query\b/i", $uri)) {
685 if($content_type && $content_type == 'taxonomies' && (strpos($id, 'tax-') !== false)) {
686 $found[] = (int) abs(filter_var($id, FILTER_SANITIZE_NUMBER_INT));
687 } else if($content_type && $content_type == 'posts' && is_numeric($id)) {
688 $found[] = (int) filter_var($id, FILTER_SANITIZE_NUMBER_INT);
689 } else {
690 $found[] = $id;
691 }
692 }
693 }
694
695 return $found;
696 }
697
698 /**
699 * Reload the globals when the blog is switched (multisite)
700 */
701 public function reload_globals_in_network($new_blog_id) {
702 global $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_external_redirects;
703
704 if(function_exists('get_blog_option')) {
705 $permalink_manager_uris = get_blog_option($new_blog_id, 'permalink-manager-uris');
706 $permalink_manager_redirects = get_blog_option($new_blog_id, 'permalink-manager-redirects');
707 $permalink_manager_external_redirects = get_blog_option($new_blog_id, 'permalink-manager-external-redirects');
708 }
709 }
710
711
712 }
713