PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 2.2.7.3
Permalink Manager Lite v2.2.7.3
2.6.0 2.5.5 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 6 years ago permalink-manager-admin-functions.php 6 years ago permalink-manager-core-functions.php 6 years ago permalink-manager-debug.php 6 years ago permalink-manager-gutenberg.php 6 years ago permalink-manager-helper-functions.php 6 years ago permalink-manager-third-parties.php 6 years ago permalink-manager-uri-functions-post.php 6 years ago
permalink-manager-helper-functions.php
648 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
22 /**
23 * Support for multidimensional arrays - array_map()
24 */
25 static function multidimensional_array_map($function, $input) {
26 $output = array();
27
28 if(is_array($input)) {
29 foreach ($input as $key => $val) {
30 $output[$key] = (is_array($val) ? self::multidimensional_array_map($function, $val) : $function($val));
31 }
32 } else {
33 $output = $function($input);
34 }
35
36 return $output;
37 }
38
39 /**
40 * Get primary term (by Yoast SEO)
41 */
42 static function get_primary_term($post_id, $taxonomy, $slug_only = true) {
43 global $permalink_manager_options;
44
45 $primary_term_enabled = apply_filters('permalink_manager_primary_term', true);
46
47 if(!$primary_term_enabled) { return; }
48
49 if(class_exists('WPSEO_Primary_Term')) {
50 $primary_term = new WPSEO_Primary_Term($taxonomy, $post_id);
51 $primary_term = get_term($primary_term->get_primary_term());
52 } else if(function_exists('the_seo_framework')) {
53 $primary_term = the_seo_framework()->get_primary_term($post_id, $taxonomy);
54 }
55
56 if(!empty($primary_term) && !is_wp_error($primary_term)) {
57 return ($slug_only) ? $primary_term->slug : $primary_term;
58 } else {
59 return;
60 }
61 }
62
63 /**
64 * Get lowest level term/post
65 */
66 static function get_lowest_element($first_element, $elements) {
67 if(!empty($elements) && !empty($first_element)) {
68 // Get the ID of first element
69 if(!empty($first_element->term_id)) {
70 $first_element_id = $first_element->term_id;
71 $parent_key = 'parent';
72 } else if(!empty($first_element->ID)) {
73 $first_element_id = $first_element->ID;
74 $parent_key = 'post_parent';
75 } else if(is_numeric($first_element)) {
76 $first_element_id = $first_element;
77 $parent_key = 'post_parent';
78 } else {
79 return false;
80 }
81
82 $children = wp_filter_object_list($elements, array($parent_key => $first_element_id));
83 if(!empty($children)) {
84 // Get the first term
85 $child_term = reset($children);
86 $first_element = self::get_lowest_element($child_term, $elements);
87 }
88 }
89 return $first_element;
90 }
91
92 /**
93 * Get term full slug
94 */
95 static function get_term_full_slug($term, $terms, $mode = false, $native_uri = false) {
96 global $permalink_manager_uris;
97
98 // Check if term is not empty
99 if(empty($term->taxonomy)) { return ''; }
100
101 // Get taxonomy
102 $taxonomy = $term->taxonomy;
103
104 // Check if mode is set
105 if(empty($mode)) {
106 $mode = (is_taxonomy_hierarchical($taxonomy)) ? 2 : 4;
107 }
108
109 // A. Get permalink base from the term's custom URI
110 if($mode == 1) {
111 $term_slug = $permalink_manager_uris["tax-{$term->term_id}"];
112 }
113 // B. Hierarhcical taxonomy base
114 else if($mode == 2) {
115 $ancestors = get_ancestors($term->term_id, $taxonomy, 'taxonomy');
116 $hierarchical_slugs = array();
117
118 foreach((array) $ancestors as $ancestor) {
119 $ancestor_term = get_term($ancestor, $taxonomy);
120 $hierarchical_slugs[] = ($native_uri) ? $ancestor_term->slug : self::force_custom_slugs($ancestor_term->slug, $ancestor_term);
121 }
122 $hierarchical_slugs = array_reverse($hierarchical_slugs);
123 $term_slug = implode('/', $hierarchical_slugs);
124
125 // Append the term slug now
126 $last_term_slug = ($native_uri) ? $term->slug : self::force_custom_slugs($term->slug, $term);
127 $term_slug = "{$term_slug}/{$last_term_slug}";
128 }
129 // C. Force flat taxonomy base - get highgest level term (if %taxonomy_flat% tag is used)
130 else if($mode == 4) {
131 foreach($terms as $single_term) {
132 if($single_term->parent == 0) {
133 $term_slug = self::force_custom_slugs($single_term->slug, $single_term);
134 break;
135 }
136 }
137 }
138 // D. Flat/non-hierarchical taxonomy base - get primary term (if set) or first term
139 else if(!empty($term->slug)) {
140 $term_slug = ($native_uri) ? $term->slug : Permalink_Manager_Helper_Functions::force_custom_slugs($term->slug, $term);
141 }
142
143 return (!empty($term_slug)) ? $term_slug : "";
144 }
145
146 static function content_types_disabled_by_default($is_taxonomy = false) {
147 if($is_taxonomy) {
148 return array('product_shipping_class', 'post_status');
149 } else {
150 return array('revision', 'algolia_task', 'fl_builder', 'fl-builder', 'fl-theme-layout', 'wc_product_tab', 'wc_voucher', 'wc_voucher_template', 'sliders', 'thirstylink', 'elementor_library', 'cms_block');
151 }
152 }
153
154 /**
155 * Allow to disable post types and taxonomies
156 */
157 static function get_disabled_post_types() {
158 global $permalink_manager_options, $wp_post_types, $wp_rewrite;
159
160 $initial_disabled_post_types = self::content_types_disabled_by_default();
161
162 // Disable post types that are not publicly_queryable
163 if(!empty($wp_rewrite)){
164 foreach($wp_post_types as $post_type) {
165 $is_publicly_queryable = (empty($post_type->publicly_queryable) && empty($post_type->public)) ? false : true;
166
167 if(!$is_publicly_queryable && !in_array($post_type->name, array('post', 'page', 'attachment'))) {
168 $initial_disabled_post_types[] = $post_type->name;
169 }
170 }
171 }
172
173 $disabled_post_types = (!empty($permalink_manager_options['general']['partial_disable']['post_types'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['post_types'], $initial_disabled_post_types) : $initial_disabled_post_types;
174
175 return apply_filters('permalink_manager_disabled_post_types', $disabled_post_types);
176 }
177
178 static function get_disabled_taxonomies() {
179 global $permalink_manager_options;
180
181 $initial_disabled_taxonomies = self::content_types_disabled_by_default(true);
182
183 $disabled_taxonomies = (!empty($permalink_manager_options['general']['partial_disable']['taxonomies'])) ? array_merge((array) $permalink_manager_options['general']['partial_disable']['taxonomies'], $initial_disabled_taxonomies) : array();
184
185 return apply_filters('permalink_manager_disabled_taxonomies', $disabled_taxonomies);
186 }
187
188 static public function is_disabled($content_name, $content_type = 'post_type', $check_if_exists = true) {
189 $out = false;
190
191 if($content_type == 'post_type') {
192 $disabled_post_types = self::get_disabled_post_types();
193 $post_type_exists = ($check_if_exists) ? post_type_exists($content_name) : true;
194 $out = ((is_array($disabled_post_types) && in_array($content_name, $disabled_post_types)) || empty($post_type_exists)) ? true : false;
195 } else {
196 $disabled_taxonomies = self::get_disabled_taxonomies();
197 $taxonomy_exists = ($check_if_exists) ? taxonomy_exists($content_name) : true;
198 $out = ((is_array($disabled_taxonomies) && in_array($content_name, $disabled_taxonomies)) || empty($taxonomy_exists)) ? true : false;
199 }
200
201 return $out;
202 }
203
204 /**
205 * Get post_types array
206 */
207 static function get_post_types_array($format = null, $cpt = null, $all = false) {
208 global $wp_post_types;
209
210 $post_types = get_post_types(array('publicly_queryable' => true, '_builtin' => false), 'objects', 'AND');
211 $disabled_post_types = self::get_disabled_post_types();
212
213 // Include native post types
214 foreach(array('post', 'page', 'attachment') as $post_type_name) {
215 $post_types[$post_type_name] = $wp_post_types[$post_type_name];
216 }
217
218 $post_types_array = array();
219 foreach($post_types as $post_type) {
220 $value = ($format == 'full') ? array('label' => $post_type->labels->name, 'name' => $post_type->name) : $post_type->labels->name;
221 $post_types_array[$post_type->name] = $value;
222 }
223
224 // Soft exclude disabled post types
225 if(!$all && is_array($disabled_post_types)) {
226 foreach($disabled_post_types as $post_type) {
227 if(!empty($post_types_array[$post_type])) { unset($post_types_array[$post_type]); }
228 }
229 }
230
231 // Hard exclude disabled post types
232 $hard_disabled_post_types = self::content_types_disabled_by_default();
233 if(is_array($hard_disabled_post_types)) {
234 foreach($hard_disabled_post_types as $post_type) {
235 if(!empty($post_types_array[$post_type])) { unset($post_types_array[$post_type]); }
236 }
237 }
238
239 return (empty($cpt)) ? $post_types_array : $post_types_array[$cpt];
240 }
241
242 /**
243 * Get array with all taxonomies
244 */
245 static function get_taxonomies_array($format = null, $tax = null, $prefix = false, $all = false, $settings = false) {
246 $taxonomies = get_taxonomies(array('public' => true, 'publicly_queryable' => true), 'objects', 'AND');
247 $disabled_taxonomies = self::get_disabled_taxonomies();
248
249 $taxonomies_array = array();
250
251 foreach($taxonomies as $taxonomy) {
252 $key = ($prefix) ? "tax-{$taxonomy->name}" : $taxonomy->name;
253 if($format == 'full') {
254 $taxonomies_array[$taxonomy->name] = array('label' => $taxonomy->labels->name, 'name' => $taxonomy->name);
255 } else {
256 $taxonomies_array[$key] = $taxonomy->labels->name;
257 }
258 }
259
260 // Soft exclude taxonomies
261 if(!$all && is_array($disabled_taxonomies)) {
262 foreach($disabled_taxonomies as $taxonomy) {
263 if(!empty($taxonomies_array[$taxonomy])) { unset($taxonomies_array[$taxonomy]); }
264 }
265 }
266
267 // Hard exclude disabled taxonomies
268 $hard_disabled_taxonomies = self::content_types_disabled_by_default(true);
269 if(is_array($hard_disabled_taxonomies)) {
270 foreach($hard_disabled_taxonomies as $taxonomy) {
271 if(!empty($taxonomies_array[$taxonomy])) { unset($taxonomies_array[$taxonomy]); }
272 }
273 }
274
275 ksort($taxonomies_array);
276
277 return (empty($tax)) ? $taxonomies_array : $taxonomies_array[$tax];
278 }
279
280 /**
281 * Get permastruct
282 */
283 static function get_default_permastruct($post_type = 'page', $remove_post_tag = false) {
284 global $wp_rewrite;
285
286 // Get default permastruct
287 if($post_type == 'page') {
288 $permastruct = $wp_rewrite->get_page_permastruct();
289 } else if($post_type == 'post') {
290 $permastruct = get_option('permalink_structure');
291 } else {
292 $permastruct = $wp_rewrite->get_extra_permastruct($post_type);
293 }
294
295 return ($remove_post_tag) ? trim(str_replace(array("%postname%", "%pagename%", "%{$post_type}%"), "", $permastruct), "/") : $permastruct;
296 }
297
298 /**
299 * Get all endpoints
300 */
301 static function get_endpoints() {
302 global $wp_rewrite;
303
304 $pagination_endpoint = (!empty($wp_rewrite->pagination_base)) ? $wp_rewrite->pagination_base : 'page';
305
306 // Start with default endpoints
307 $endpoints = "{$pagination_endpoint}|feed|embed|attachment|trackback|filter";
308
309 if(!empty($wp_rewrite->endpoints)) {
310 foreach($wp_rewrite->endpoints as $endpoint) {
311 $endpoints .= "|{$endpoint[1]}";
312 }
313 }
314
315 return apply_filters("permalink_manager_endpoints", str_replace("/", "\/", $endpoints));
316 }
317
318 /**
319 * Structure Tags & Rewrite functions
320 */
321 static function get_all_structure_tags($code = true, $seperator = ', ', $hide_slug_tags = true) {
322 global $wp_rewrite;
323
324 $tags = $wp_rewrite->rewritecode;
325
326 // Hide slug tags
327 if($hide_slug_tags) {
328 $post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
329 foreach($post_types as $post_type => $post_type_name) {
330 $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
331 // Find key with post type tag from rewritecode
332 $key = array_search($post_type_tag, $tags);
333 if($key) { unset($tags[$key]); }
334 }
335 }
336
337 // Extra tags
338 $tags[] = '%taxonomy%';
339 $tags[] = '%post_type%';
340 $tags[] = '%term_id%';
341 $tags[] = '%monthname%';
342
343 foreach($tags as &$tag) {
344 $tag = ($code) ? "<code>{$tag}</code>" : "{$tag}";
345 }
346 $output = implode($seperator, $tags);
347
348 return "<span class=\"structure-tags-list\">{$output}</span>";
349 }
350
351 /**
352 * Get endpoint used to mark the postname or its equivalent for custom post types and pages in permastructures
353 */
354 static function get_post_tag($post_type) {
355 // Get the post type (with fix for posts & pages)
356 if($post_type == 'page') {
357 $post_type_tag = '%pagename%';
358 } else if ($post_type == 'post') {
359 $post_type_tag = '%postname%';
360 } else {
361 $post_type_tag = "%{$post_type}%";
362 }
363 return $post_type_tag;
364 }
365
366 /**
367 * Find taxonomy name using "term_id"
368 */
369 static function get_tax_name($term, $term_by = 'id') {
370 $term_object = get_term_by($term_by, $term);
371 return (isset($term_object->taxonomy)) ? $term_object->taxonomy : '';
372 }
373
374 /**
375 * Get permalink base (home URL)
376 */
377 public static function get_permalink_base($element = null) {
378 return apply_filters('permalink_manager_filter_permalink_base', trim(get_option('home'), "/"), $element);
379 }
380
381 /**
382 * Remove post tag from permastructure
383 */
384 static function remove_post_tag($permastruct) {
385 $post_types = self::get_post_types_array('full');
386
387 // Get all post tags
388 $post_tags = array("%postname%", "%pagename%");
389 foreach($post_types as $post_type) {
390 $post_tags[] = "%{$post_type['name']}%";
391 }
392
393 $permastruct = str_replace($post_tags, "", $permastruct);
394 return trim($permastruct, "/");
395 }
396
397 /**
398 * Get front-page ID
399 */
400 static function is_front_page($page_id) {
401 $front_page_id = get_option('page_on_front');
402 $bool = (!empty($front_page_id) && $page_id == $front_page_id) ? true : false;
403
404 return apply_filters('permalink_manager_is_front_page', $bool, $page_id, $front_page_id);
405 }
406
407 /**
408 * Sanitize multidimensional array
409 */
410 static function sanitize_array($data = array()) {
411 if (!is_array($data) || !count($data)) {
412 return array();
413 }
414
415 foreach ($data as $k => $v) {
416 if (!is_array($v) && !is_object($v)) {
417 $data[$k] = htmlspecialchars(trim($v));
418 }
419 if (is_array($v)) {
420 $data[$k] = self::sanitize_array($v);
421 }
422 }
423 return $data;
424 }
425
426 /**
427 * Encode URI and keep slashes
428 */
429 static function encode_uri($uri) {
430 return str_replace("%2F", "/", urlencode($uri));
431 }
432
433 /**
434 * Slugify function
435 */
436 public static function sanitize_title($str, $keep_percent_sign = false, $force_lowercase = null, $sanitize_slugs = null) {
437 global $permalink_manager_options;
438
439 // Foree lowercase & hyphens
440 $force_lowercase = (!is_null($force_lowercase)) ? $force_lowercase : apply_filters('permalink_manager_force_lowercase_uris', true);
441
442 if(is_null($sanitize_slugs)) {
443 $sanitize_slugs = (!empty($permalink_manager_options['general']['disable_slug_sanitization'])) ? false : true;
444 }
445
446 // Trim slashes & whitespaces
447 $clean = trim($str, " /");
448
449 // Remove accents
450 $clean = remove_accents($clean);
451
452 // $clean = iconv('UTF-8', 'ASCII//TRANSLIT', $clean);
453 $percent_sign = ($keep_percent_sign) ? "\%" : "";
454 $clean = preg_replace("/[^\p{Thai}\p{Xwd}\p{Hebrew}a-zA-Z0-9{$percent_sign}\/_\.|+, -]/u", '', $clean);
455 $clean = ($force_lowercase) ? strtolower(trim($clean, '-')) : trim($clean, '-');
456
457 // Remove special characters
458 if($sanitize_slugs !== false) {
459 $clean = preg_replace("/[\s_|+-]+/", "-", $clean);
460 $clean = preg_replace("/[,]+/", "", $clean);
461 $clean = preg_replace('/([\.]+)(?![a-z]{3,4}$)/i', '', $clean);
462 $clean = preg_replace('/([-\s+]\/[-\s+])/', '-', $clean);
463 } else {
464 $clean = preg_replace("/[\s]+/", "-", $clean);
465 }
466
467 // Remove trailing slashes
468 $clean = str_replace(array('-/', '/-', '//'), '/', $clean);
469
470 return $clean;
471 }
472
473 /**
474 * Replace empty placeholder tags & remove BOM
475 */
476 public static function replace_empty_placeholder_tags($default_uri, $native_slug = "", $element = "", $slug = "", $native_uri = "") {
477 // Do not affect native URIs
478 if($native_uri == true) { return $default_uri; }
479
480 // Remove the BOM
481 $default_uri = str_replace(array("\xEF\xBB\xBF", "%ef%bb%bf"), '', $default_uri);
482
483 // Encode the URI before placeholders are removed
484 $chunks = explode('/', $default_uri);
485 foreach ($chunks as &$chunk) {
486 if(preg_match("/^(%.+?%)$/", $chunk) == false) {
487 $chunk = rawurldecode($chunk);
488 }
489 }
490 $default_uri = implode("/", $chunks);
491
492 $empty_tag_replacement = apply_filters('permalink_manager_empty_tag_replacement', null, $element);
493 $default_uri = ($empty_tag_replacement || is_null($empty_tag_replacement)) ? str_replace("//", "/", preg_replace("/%(.+?)%/", $empty_tag_replacement, $default_uri)) : $default_uri;
494
495 return trim($default_uri, "/");
496 }
497
498 /**
499 * Clear/Sanitize the URI
500 */
501 public static function clear_single_uri($uri) {
502 return self::sanitize_title($uri, true);
503 }
504
505 /**
506 * Remove all slashes
507 */
508 public static function remove_slashes($uri) {
509 return preg_replace("/[\/]+/", "", $uri);
510 }
511
512 /**
513 * Force custom slugs
514 */
515 public static function force_custom_slugs($slug, $object, $flat = false) {
516 global $permalink_manager_options;
517
518 $force_custom_slugs = (!empty($permalink_manager_options['general']['force_custom_slugs'])) ? true : false;
519 $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
520
521 if($force_custom_slugs) {
522 $title = (!empty($object->name)) ? $object->name : $object->post_title;
523 $title = self::remove_slashes($title);
524
525 $old_slug = basename($slug);
526 $new_slug = self::sanitize_title($title, false, null, null);
527
528 $slug = ($old_slug != $new_slug) ? str_replace($old_slug, $new_slug, $slug) : $slug;
529 }
530
531 if($flat) {
532 $slug = preg_replace("/([^\/]+)(.*)/", "$1", $slug);
533 }
534
535 return $slug;
536 }
537
538 public static function element_exists($element_id) {
539 global $wpdb;
540
541 if(strpos($element_id, 'tax-') !== false) {
542 $term_id = intval(preg_replace("/[^0-9]/", "", $element_id));
543 $element_exists = $wpdb->get_var( "SELECT * FROM {$wpdb->prefix}terms WHERE term_id = {$term_id}" );
544 } else {
545 $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'" );
546 }
547
548 return (!empty($element_exists)) ? $element_exists : false;
549 }
550
551 /**
552 * Detect duplicates
553 */
554 public static function get_all_duplicates($include_custom_uris = true) {
555 global $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wpdb;
556
557 // Make sure that both variables are arrays
558 $all_uris = ($include_custom_uris && is_array($permalink_manager_uris)) ? $permalink_manager_uris : array();
559 $permalink_manager_redirects = (is_array($permalink_manager_redirects)) ? $permalink_manager_redirects : array();
560
561 // Convert redirects list, so it can be merged with $permalink_manager_uris
562 foreach($permalink_manager_redirects as $element_id => $redirects) {
563 if(is_array($redirects)) {
564 foreach($redirects as $index => $uri) {
565 $all_uris["redirect-{$index}_{$element_id}"] = $uri;
566 }
567 }
568 }
569
570 // Count duplicates
571 $duplicates_removed = 0;
572 $duplicates_groups = array();
573 $duplicates_list = array_count_values($all_uris);
574 $duplicates_list = array_filter($duplicates_list, function ($x) { return $x >= 2; });
575
576 // Assign keys to duplicates (group them)
577 if(count($duplicates_list) > 0) {
578 foreach($duplicates_list as $duplicated_uri => $count) {
579 $duplicates_groups[$duplicated_uri] = array_keys($all_uris, $duplicated_uri);
580 }
581 }
582
583 return $duplicates_groups;
584 }
585
586 /**
587 * Check if a single URI is duplicated
588 */
589 public static function is_uri_duplicated($uri, $element_id) {
590 global $permalink_manager_uris;
591
592 if(empty($uri) || empty($element_id)) { return false; }
593
594 $uri = trim(trim(sanitize_text_field($uri)), "/");
595 $element_id = sanitize_text_field($element_id);
596
597 // Keep the URIs in a separate array just here & unset the URI for requested element to prevent false alert
598 $all_uris = $permalink_manager_uris;
599 unset($permalink_manager_uris[$element_id]);
600
601 if(in_array($uri, $permalink_manager_uris)) {
602 $all_duplicates = (array) array_keys($permalink_manager_uris, $uri);
603 $this_uri_lang = Permalink_Manager_Third_Parties::get_language_code($element_id);
604
605 if($this_uri_lang) {
606 foreach($all_duplicates as $key => $duplicated_id) {
607 $duplicated_uri_lang = Permalink_Manager_Third_Parties::get_language_code($duplicated_id);
608
609 if($duplicated_uri_lang !== $this_uri_lang) {
610 unset($all_duplicates[$key]);
611 }
612 }
613
614 return (count($all_duplicates) > 0) ? true : false;
615 } else {
616 return true;
617 }
618 } else {
619 return false;
620 }
621 }
622
623 /**
624 * URI Search
625 */
626 public static function search_uri($search_query, $content_type = null) {
627 global $permalink_manager_uris;
628
629 $found = array();
630 $search_query = preg_quote($search_query, '/');
631
632 foreach($permalink_manager_uris as $id => $uri) {
633 if(preg_match("/\b$search_query\b/i", $uri)) {
634 if($content_type && $content_type == 'taxonomies' && (strpos($id, 'tax-') !== false)) {
635 $found[] = (int) abs(filter_var($id, FILTER_SANITIZE_NUMBER_INT));
636 } else if($content_type && $content_type == 'posts' && is_numeric($id)) {
637 $found[] = (int) filter_var($id, FILTER_SANITIZE_NUMBER_INT);
638 } else {
639 $found[] = $id;
640 }
641 }
642 }
643
644 return $found;
645 }
646
647 }
648