PluginProbe ʕ •ᴥ•ʔ
Permalink Manager Lite / 2.2.12
Permalink Manager Lite v2.2.12
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 4 years ago permalink-manager-admin-functions.php 4 years ago permalink-manager-core-functions.php 4 years ago permalink-manager-debug.php 4 years ago permalink-manager-gutenberg.php 4 years ago permalink-manager-helper-functions.php 4 years ago permalink-manager-language-plugins.php 4 years ago permalink-manager-third-parties.php 4 years ago permalink-manager-uri-functions-post.php 4 years ago permalink-manager-uri-functions.php 4 years ago
permalink-manager-helper-functions.php
780 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', 'nav_menu_item', '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 /**
229 * Check if post type should be ignored by Permalink Manager
230 */
231 static public function is_post_type_disabled($post_type, $check_if_exists = true) {
232 $disabled_post_types = self::get_disabled_post_types();
233 $post_type_exists = ($check_if_exists) ? post_type_exists($post_type) : true;
234 $out = ((is_array($disabled_post_types) && in_array($post_type, $disabled_post_types)) || empty($post_type_exists)) ? true : false;
235
236 return $out;
237 }
238
239 /**
240 * Check if taxonomy should be ignored by Permalink Manager
241 */
242 static public function is_taxonomy_disabled($taxonomy, $check_if_exists = true) {
243 $disabled_taxonomies = self::get_disabled_taxonomies();
244 $taxonomy_exists = ($check_if_exists) ? taxonomy_exists($taxonomy) : true;
245 $out = ((is_array($disabled_taxonomies) && in_array($taxonomy, $disabled_taxonomies)) || empty($taxonomy_exists)) ? true : false;
246
247 return $out;
248 }
249
250 /**
251 * Check if single post should be ignored by Permalink Manager
252 */
253 public static function is_post_excluded($post = null) {
254 $post = (is_integer($post)) ? get_post($post) : $post;
255
256 // A. Check if post type is disabled
257 if(!empty($post->post_type) && self::is_post_type_disabled($post->post_type)) {
258 return true;
259 }
260
261 $excluded_post_ids = apply_filters('permalink_manager_excluded_post_ids', array());
262
263 // B. Check if post ID is excluded
264 if(is_array($excluded_post_ids) && !empty($post->ID) && in_array($post->ID, $excluded_post_ids)) {
265 return true;
266 }
267
268 return false;
269 }
270
271 /**
272 * Check if single term should be ignored by Permalink Manager
273 */
274 public static function is_term_excluded($term = null) {
275 $term = (is_numeric($term)) ? get_term($term) : $term;
276
277 // A. Check if post type is disabled
278 if(!empty($term->taxonomy) && self::is_taxonomy_disabled($term->taxonomy)) {
279 return true;
280 }
281
282 $excluded_term_ids = apply_filters('permalink_manager_excluded_term_ids', array());
283
284 // B. Check if post ID is excluded
285 if(is_array($excluded_term_ids) && !empty($term->term_id) && in_array($term->term_id, $excluded_term_ids)) {
286 return true;
287 }
288
289 return false;
290 }
291
292 /**
293 * Get all post types supported by Permalink Manager
294 */
295 static function get_post_types_array($format = null, $cpt = null, $include_user_excluded = false) {
296 global $wp_post_types;
297
298 $post_types_array = array();
299 $disabled_post_types = self::get_disabled_post_types(!$include_user_excluded);
300
301 foreach($wp_post_types as $post_type) {
302 if($format == 'full') {
303 $post_types_array[$post_type->name] = array('label' => $post_type->labels->name, 'name' => $post_type->name);
304 } else if($format == 'archive_slug') {
305 // Ignore non-public post types
306 if(!is_post_type_viewable($post_type) || empty($post_type->has_archive)) {
307 continue;
308 }
309
310 if($post_type->has_archive != true) {
311 $archive_slug = $post_type->has_archive;
312 } else if(is_array($post_type->rewrite) && !empty($post_type->rewrite['slug'])) {
313 $archive_slug = $post_type->rewrite['slug'];
314 } else {
315 $archive_slug = $post_type->name;
316 }
317
318 $post_types_array[$post_type->name] = $archive_slug;
319 } else {
320 $post_types_array[$post_type->name] = $post_type->labels->name;
321 }
322 }
323
324 if(is_array($disabled_post_types)) {
325 foreach($disabled_post_types as $post_type) {
326 if(!empty($post_types_array[$post_type])) {
327 unset($post_types_array[$post_type]);
328 }
329 }
330 }
331
332 return (empty($cpt)) ? $post_types_array : $post_types_array[$cpt];
333 }
334
335 /**
336 * Get all taxonomies supported by Permalink Manager
337 */
338 static function get_taxonomies_array($format = null, $tax = null, $prefix = false, $include_user_excluded = false, $settings = false) {
339 global $wp_taxonomies;
340
341 $taxonomies_array = array();
342 $disabled_taxonomies = self::get_disabled_taxonomies(!$include_user_excluded);
343
344 foreach($wp_taxonomies as $taxonomy) {
345 $key = ($prefix) ? "tax-{$taxonomy->name}" : $taxonomy->name;
346 $taxonomy_name = (!empty($taxonomy->labels->name)) ? $taxonomy->labels->name : '-';
347
348 $taxonomies_array[$taxonomy->name] = ($format == 'full') ? array('label' => $taxonomy->labels->name, 'name' => $taxonomy->name) : $taxonomy_name;
349 }
350
351 if(is_array($disabled_taxonomies)) {
352 foreach($disabled_taxonomies as $taxonomy) {
353 if(!empty($taxonomies_array[$taxonomy])) {
354 unset($taxonomies_array[$taxonomy]);
355 }
356 }
357 }
358
359 ksort($taxonomies_array);
360
361 return (empty($tax)) ? $taxonomies_array : $taxonomies_array[$tax];
362 }
363
364 /**
365 * Get all post statuses supported by Permalink Manager
366 */
367 static function get_post_statuses() {
368 $post_statuses = get_post_statuses();
369
370 return apply_filters('permalink_manager_post_statuses', $post_statuses);
371 }
372
373 /**
374 * Get permastruct
375 */
376 static function get_default_permastruct($post_type = 'page', $remove_post_tag = false) {
377 global $wp_rewrite;
378
379 // Get default permastruct
380 if($post_type == 'page') {
381 $permastruct = $wp_rewrite->get_page_permastruct();
382 } else if($post_type == 'post') {
383 $permastruct = get_option('permalink_structure');
384 } else {
385 $permastruct = $wp_rewrite->get_extra_permastruct($post_type);
386 }
387
388 return ($remove_post_tag) ? trim(str_replace(array("%postname%", "%pagename%", "%{$post_type}%"), "", $permastruct), "/") : $permastruct;
389 }
390
391 /**
392 * Get all endpoints
393 */
394 static function get_endpoints() {
395 global $wp_rewrite;
396
397 $pagination_endpoint = (!empty($wp_rewrite->pagination_base)) ? $wp_rewrite->pagination_base : 'page';
398
399 // Start with default endpoints
400 $endpoints = "{$pagination_endpoint}|feed|embed|attachment|trackback|filter";
401
402 if(!empty($wp_rewrite->endpoints)) {
403 foreach($wp_rewrite->endpoints as $endpoint) {
404 $endpoints .= "|{$endpoint[1]}";
405 }
406 }
407
408 return apply_filters("permalink_manager_endpoints", str_replace("/", "\/", $endpoints));
409 }
410
411 /**
412 * Structure Tags & Rewrite functions
413 */
414 static function get_all_structure_tags($code = true, $seperator = ', ', $hide_slug_tags = true) {
415 global $wp_rewrite;
416
417 $tags = $wp_rewrite->rewritecode;
418
419 // Hide slug tags
420 if($hide_slug_tags) {
421 $post_types = Permalink_Manager_Helper_Functions::get_post_types_array();
422 foreach($post_types as $post_type => $post_type_name) {
423 $post_type_tag = Permalink_Manager_Helper_Functions::get_post_tag($post_type);
424 // Find key with post type tag from rewritecode
425 $key = array_search($post_type_tag, $tags);
426 if($key) { unset($tags[$key]); }
427 }
428 }
429
430 // Extra tags
431 $tags[] = '%taxonomy%';
432 $tags[] = '%post_type%';
433 $tags[] = '%term_id%';
434 $tags[] = '%monthname%';
435
436 foreach($tags as &$tag) {
437 $tag = ($code) ? "<code>{$tag}</code>" : "{$tag}";
438 }
439 $output = implode($seperator, $tags);
440
441 return "<span class=\"structure-tags-list\">{$output}</span>";
442 }
443
444 /**
445 * Get endpoint used to mark the postname or its equivalent for custom post types and pages in permastructures
446 */
447 static function get_post_tag($post_type) {
448 // Get the post type (with fix for posts & pages)
449 if($post_type == 'page') {
450 $post_type_tag = '%pagename%';
451 } else if ($post_type == 'post') {
452 $post_type_tag = '%postname%';
453 } else {
454 $post_type_tag = "%{$post_type}%";
455 }
456 return $post_type_tag;
457 }
458
459 /**
460 * Find taxonomy name using "term_id"
461 */
462 static function get_tax_name($term, $term_by = 'id') {
463 $term_object = get_term_by($term_by, $term);
464 return (isset($term_object->taxonomy)) ? $term_object->taxonomy : '';
465 }
466
467 /**
468 * Get permalink base (home URL)
469 */
470 public static function get_permalink_base($element = null) {
471 return apply_filters('permalink_manager_filter_permalink_base', trim(get_option('home'), "/"), $element);
472 }
473
474 /**
475 * Remove post tag from permastructure
476 */
477 static function remove_post_tag($permastruct) {
478 $post_types = self::get_post_types_array('full');
479
480 // Get all post tags
481 $post_tags = array("%postname%", "%pagename%");
482 foreach($post_types as $post_type) {
483 $post_tags[] = "%{$post_type['name']}%";
484 }
485
486 $permastruct = str_replace($post_tags, "", $permastruct);
487 return trim($permastruct, "/");
488 }
489
490 /**
491 * Get front-page ID
492 */
493 static function is_front_page($page_id) {
494 $front_page_id = get_option('page_on_front');
495 $bool = (!empty($front_page_id) && $page_id == $front_page_id) ? true : false;
496
497 return apply_filters('permalink_manager_is_front_page', $bool, $page_id, $front_page_id);
498 }
499
500 /**
501 * Sanitize multidimensional array
502 */
503 static function sanitize_array($data = array()) {
504 if (!is_array($data) || !count($data)) {
505 return array();
506 }
507
508 foreach ($data as $k => $v) {
509 if (!is_array($v) && !is_object($v)) {
510 $data[$k] = htmlspecialchars(trim($v));
511 }
512 if (is_array($v)) {
513 $data[$k] = self::sanitize_array($v);
514 }
515 }
516 return $data;
517 }
518
519 /**
520 * Encode URI and keep special characters
521 */
522 static function encode_uri($uri) {
523 return str_replace(array('%2F', '%2C', '%7C', '%2B'), array('/', ',', '|', '+'), urlencode($uri));
524 }
525
526 /**
527 * Slugify function
528 */
529 public static function sanitize_title($str, $keep_percent_sign = false, $force_lowercase = null, $sanitize_slugs = null) {
530 global $permalink_manager_options;
531
532 // Foree lowercase & hyphens
533 $force_lowercase = (!is_null($force_lowercase)) ? $force_lowercase : apply_filters('permalink_manager_force_lowercase_uris', true);
534
535 if(is_null($sanitize_slugs)) {
536 $sanitize_slugs = (!empty($permalink_manager_options['general']['disable_slug_sanitization'])) ? false : true;
537 }
538
539 // Remove accents & entities
540 $clean = (empty($permalink_manager_options['general']['keep_accents'])) ? remove_accents($str) : $str;
541 $clean = str_replace(array('&lt', '&gt', '&amp'), '', $clean);
542
543 $percent_sign = ($keep_percent_sign) ? "\%" : "";
544 $sanitize_regex = apply_filters("permalink_manager_sanitize_regex", "/[^\p{Xan}a-zA-Z0-9{$percent_sign}\/_\.|+, -]/ui", $percent_sign);
545 $clean = preg_replace($sanitize_regex, '', $clean);
546 $clean = ($force_lowercase) ? strtolower($clean) : $clean;
547
548 // Remove amperand
549 $clean = str_replace(array('%26', '&'), '', $clean);
550
551 // Remove special characters
552 if($sanitize_slugs !== false) {
553 $clean = preg_replace("/[\s|+-]+/", "-", $clean);
554 $clean = preg_replace("/[,]+/", "", $clean);
555 $clean = preg_replace('/([\.]+)(?![a-z]{3,4}$)/i', '', $clean);
556 $clean = preg_replace('/([-\s+]\/[-\s+])/', '-', $clean);
557 } else {
558 $clean = preg_replace("/[\s]+/", "-", $clean);
559 }
560
561 // Remove widow & duplicated slashes
562 $clean = preg_replace('/([-]*[\/]+[-]*)/', '/', $clean);
563 $clean = preg_replace('/([\/]+)/', '/', $clean);
564
565 // Trim slashes, dashes and whitespaces
566 $clean = trim($clean, " /-");
567
568 return $clean;
569 }
570
571 /**
572 * Replace empty placeholder tags & remove BOM
573 */
574 public static function replace_empty_placeholder_tags($default_uri, $native_slug = "", $element = "", $slug = "", $native_uri = "") {
575 // Do not affect native URIs
576 if($native_uri == true) { return $default_uri; }
577
578 // Remove the BOM
579 $default_uri = str_replace(array("\xEF\xBB\xBF", "%ef%bb%bf"), '', $default_uri);
580
581 // Encode the URI before placeholders are removed
582 $chunks = explode('/', $default_uri);
583 foreach ($chunks as &$chunk) {
584 if(preg_match("/^(%.+?%)$/", $chunk) == false) {
585 $chunk = rawurldecode($chunk);
586 }
587 }
588 $default_uri = implode("/", $chunks);
589
590 $empty_tag_replacement = apply_filters('permalink_manager_empty_tag_replacement', null, $element);
591 $default_uri = ($empty_tag_replacement || is_null($empty_tag_replacement)) ? str_replace("//", "/", preg_replace("/%(.+?)%/", $empty_tag_replacement, $default_uri)) : $default_uri;
592
593 return trim($default_uri, "/");
594 }
595
596 /**
597 * Clear/Sanitize the URI
598 */
599 public static function clear_single_uri($uri) {
600 return self::sanitize_title($uri, true);
601 }
602
603 /**
604 * Remove all slashes
605 */
606 public static function remove_slashes($uri) {
607 return preg_replace("/[\/]+/", "", $uri);
608 }
609
610 /**
611 * Force custom slugs
612 */
613 public static function force_custom_slugs($slug, $object, $flat = false) {
614 global $permalink_manager_options, $permalink_manager_uris;
615
616 $force_custom_slugs = (!empty($permalink_manager_options['general']['force_custom_slugs'])) ? $permalink_manager_options['general']['force_custom_slugs'] : false;
617 $force_custom_slugs = apply_filters('permalink_manager_force_custom_slugs', $force_custom_slugs, $slug, $object);
618
619 if($force_custom_slugs) {
620 // A. Custom slug (title)
621 if($force_custom_slugs == 1) {
622 $title = (!empty($object->name)) ? $object->name : $object->post_title;
623 $title = self::remove_slashes($title);
624
625 $new_slug = self::sanitize_title($title, false, null, null);
626 }
627 // B. Custom slug (custom permalink)
628 else {
629 $object_id = (!empty($object->term_id)) ? "tax-{$object->term_id}" : $object->ID;
630 $new_slug = (!empty($permalink_manager_uris[$object_id])) ? basename($permalink_manager_uris[$object_id]) : '';
631 }
632
633 $slug = (!empty($new_slug)) ? preg_replace('/([^\/]+)$/', $new_slug, $slug) : $slug;
634 }
635
636 if($flat) {
637 $slug = preg_replace("/([^\/]+)(.*)/", "$1", $slug);
638 }
639
640 return $slug;
641 }
642
643 public static function element_exists($element_id) {
644 global $wpdb;
645
646 if(strpos($element_id, 'tax-') !== false) {
647 $term_id = intval(preg_replace("/[^0-9]/", "", $element_id));
648 $element_exists = $wpdb->get_var( "SELECT * FROM {$wpdb->prefix}terms WHERE term_id = {$term_id}" );
649 } else {
650 $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'" );
651 }
652
653 return (!empty($element_exists)) ? $element_exists : false;
654 }
655
656 /**
657 * Detect duplicates
658 */
659 public static function get_all_duplicates($include_custom_uris = true) {
660 global $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_options, $wpdb;
661
662 // Make sure that both variables are arrays
663 $all_uris = ($include_custom_uris && is_array($permalink_manager_uris)) ? $permalink_manager_uris : array();
664 $permalink_manager_redirects = (is_array($permalink_manager_redirects)) ? $permalink_manager_redirects : array();
665
666 // Convert redirects list, so it can be merged with $permalink_manager_uris
667 foreach($permalink_manager_redirects as $element_id => $redirects) {
668 if(is_array($redirects)) {
669 foreach($redirects as $index => $uri) {
670 $all_uris["redirect-{$index}_{$element_id}"] = $uri;
671 }
672 }
673 }
674
675 // Count duplicates
676 $duplicates_removed = 0;
677 $duplicates_groups = array();
678 $duplicates_list = array_count_values($all_uris);
679 $duplicates_list = array_filter($duplicates_list, function ($x) { return $x >= 2; });
680
681 // Assign keys to duplicates (group them)
682 if(count($duplicates_list) > 0) {
683 foreach($duplicates_list as $duplicated_uri => $count) {
684 $duplicated_ids = array_keys($all_uris, $duplicated_uri);
685
686 // Ignore duplicates in different langauges
687 if(self::is_uri_duplicated($duplicated_uri, $duplicated_ids[0], $duplicated_ids)) {
688 $duplicates_groups[$duplicated_uri] = $duplicated_ids;
689 }
690 }
691 }
692
693 return $duplicates_groups;
694 }
695
696 /**
697 * Check if a single URI is duplicated
698 */
699 public static function is_uri_duplicated($uri, $element_id, $duplicated_ids = array()) {
700 global $permalink_manager_uris;
701
702 if(empty($uri) || empty($element_id) || empty($permalink_manager_uris)) { return false; }
703
704 $uri = trim(trim(sanitize_text_field($uri)), "/");
705 $element_id = sanitize_text_field($element_id);
706
707 // Keep the URIs in a separate array just here
708 if(!empty($duplicated_ids)) {
709 $all_duplicates = $duplicated_ids;
710 } else if(in_array($uri, $permalink_manager_uris)) {
711 $all_duplicates = (array) array_keys($permalink_manager_uris, $uri);
712 }
713
714 if(!empty($all_duplicates)) {
715 // Get the language code of current element
716 $this_uri_lang = Permalink_Manager_Language_Plugins::get_language_code($element_id);
717
718 foreach($all_duplicates as $key => $duplicated_id) {
719 // Ignore custom redirects
720 if(strpos($key, 'redirect-') !== false) {
721 unset($all_duplicates[$key]);
722 continue;
723 }
724
725 if($this_uri_lang) {
726 $duplicated_uri_lang = Permalink_Manager_Language_Plugins::get_language_code($duplicated_id);
727 }
728
729 // Ignore the URI for requested element and other elements in other languages to prevent the false alert
730 if((!empty($duplicated_uri_lang) && $duplicated_uri_lang !== $this_uri_lang) || $element_id == $duplicated_id) {
731 unset($all_duplicates[$key]);
732 }
733 }
734
735 return (count($all_duplicates) > 0) ? true : false;
736 } else {
737 return false;
738 }
739 }
740
741 /**
742 * URI Search
743 */
744 public static function search_uri($search_query, $content_type = null) {
745 global $permalink_manager_uris;
746
747 $found = array();
748 $search_query = preg_quote($search_query, '/');
749
750 foreach($permalink_manager_uris as $id => $uri) {
751 if(preg_match("/\b$search_query\b/i", $uri)) {
752 if($content_type && $content_type == 'taxonomies' && (strpos($id, 'tax-') !== false)) {
753 $found[] = (int) abs(filter_var($id, FILTER_SANITIZE_NUMBER_INT));
754 } else if($content_type && $content_type == 'posts' && is_numeric($id)) {
755 $found[] = (int) filter_var($id, FILTER_SANITIZE_NUMBER_INT);
756 } else {
757 $found[] = $id;
758 }
759 }
760 }
761
762 return $found;
763 }
764
765 /**
766 * Reload the globals when the blog is switched (multisite)
767 */
768 public function reload_globals_in_network($new_blog_id) {
769 global $permalink_manager_uris, $permalink_manager_redirects, $permalink_manager_external_redirects;
770
771 if(function_exists('get_blog_option')) {
772 $permalink_manager_uris = get_blog_option($new_blog_id, 'permalink-manager-uris');
773 $permalink_manager_redirects = get_blog_option($new_blog_id, 'permalink-manager-redirects');
774 $permalink_manager_external_redirects = get_blog_option($new_blog_id, 'permalink-manager-external-redirects');
775 }
776 }
777
778
779 }
780