| 1 |
<?php |
| 2 |
|
| 3 |
if (!defined('ABSPATH')) { |
| 4 |
exit; |
| 5 |
} |
| 6 |
|
| 7 |
use \FilterEverything\Filter\Container; |
| 8 |
use \FilterEverything\Filter\FilterSet; |
| 9 |
use \FilterEverything\Filter\FilterFields; |
| 10 |
use \FilterEverything\Filter\PostMetaNumEntity; |
| 11 |
use \FilterEverything\Filter\PostDateEntity; |
| 12 |
use \FilterEverything\Filter\PostMetaDateEntity; |
| 13 |
/** |
| 14 |
* Returns user's caps level that allows to use the plugin. |
| 15 |
* Developers can modify this level via hook 'wpc_plugin_user_caps' ot their own risk. |
| 16 |
* @return string |
| 17 |
*/ |
| 18 |
function flrt_plugin_user_caps() |
| 19 |
{ |
| 20 |
return apply_filters('wpc_plugin_user_caps', 'manage_options'); |
| 21 |
} |
| 22 |
|
| 23 |
function flrt_the_set($set_id = 0) |
| 24 |
{ |
| 25 |
if (function_exists('brizy_load')) { |
| 26 |
if (!did_action('wp_print_scripts')) { |
| 27 |
return false; |
| 28 |
} |
| 29 |
} |
| 30 |
|
| 31 |
return Container::instance()->getFilterContext()->takeSet($set_id); |
| 32 |
} |
| 33 |
|
| 34 |
function flrt_print_filters_for($hook = '') |
| 35 |
{ |
| 36 |
global $wp_filter; |
| 37 |
if (empty($hook) || !isset($wp_filter[$hook])) |
| 38 |
return; |
| 39 |
return $wp_filter[$hook]; |
| 40 |
} |
| 41 |
|
| 42 |
function flrt_is_filter_request() |
| 43 |
{ |
| 44 |
$wpManager = Container::instance()->getWpManager(); |
| 45 |
return $wpManager->getQueryVar('wpc_is_filter_request'); |
| 46 |
} |
| 47 |
|
| 48 |
/** |
| 49 |
* Whether filters travel as pretty URL path segments. |
| 50 |
* |
| 51 |
* FLRT_PERMALINKS_ENABLED is the switch; it can be overridden in wp-config.php |
| 52 |
* or a theme's functions.php (Permalink Manager compatibility mode). When it is |
| 53 |
* not defined yet, compute the default it would get: PRO with non-empty rewrite |
| 54 |
* rules. WpManager::init() defines the constant from this on `init`, but code |
| 55 |
* running in a request where the plugin was loaded after `init` — plugin |
| 56 |
* activation — must not fall back to the query-string mode. |
| 57 |
* |
| 58 |
* @return bool |
| 59 |
*/ |
| 60 |
function flrt_permalinks_enabled() |
| 61 |
{ |
| 62 |
if ( defined( 'FLRT_PERMALINKS_ENABLED' ) ) { |
| 63 |
return (bool) FLRT_PERMALINKS_ENABLED; |
| 64 |
} |
| 65 |
|
| 66 |
global $wp_rewrite; |
| 67 |
$rewrite = ( $wp_rewrite instanceof \WP_Rewrite ) ? $wp_rewrite->wp_rewrite_rules() : []; |
| 68 |
|
| 69 |
return defined( 'FLRT_FILTERS_PRO' ) && ! empty( $rewrite ); |
| 70 |
} |
| 71 |
|
| 72 |
function flrt_include($filename) |
| 73 |
{ |
| 74 |
$path = flrt_get_path($filename); |
| 75 |
|
| 76 |
if (file_exists($path)) { |
| 77 |
include_once($path); |
| 78 |
} |
| 79 |
} |
| 80 |
|
| 81 |
function flrt_get_path($path = '') |
| 82 |
{ |
| 83 |
return FLRT_PLUGIN_DIR_PATH . ltrim($path, '/'); |
| 84 |
} |
| 85 |
|
| 86 |
function flrt_ucfirst($text) |
| 87 |
{ |
| 88 |
if (!is_string($text)) { |
| 89 |
return $text; |
| 90 |
} |
| 91 |
return mb_strtoupper(mb_substr($text, 0, 1)) . mb_substr($text, 1); |
| 92 |
} |
| 93 |
|
| 94 |
function flrt_lcfirst( $text ) |
| 95 |
{ |
| 96 |
if( ! is_string( $text ) ){ |
| 97 |
return $text; |
| 98 |
} |
| 99 |
return mb_strtolower( mb_substr( $text, 0, 1 ) ) . mb_substr( $text, 1 ); |
| 100 |
} |
| 101 |
|
| 102 |
function flrt_add_query_arg(...$args) |
| 103 |
{ |
| 104 |
if (is_array($args[0])) { |
| 105 |
if (count($args) < 2 || false === $args[1]) { |
| 106 |
$uri = $_SERVER['REQUEST_URI']; |
| 107 |
} else { |
| 108 |
$uri = $args[1]; |
| 109 |
} |
| 110 |
} else { |
| 111 |
if (count($args) < 3 || false === $args[2]) { |
| 112 |
$uri = $_SERVER['REQUEST_URI']; |
| 113 |
} else { |
| 114 |
$uri = $args[2]; |
| 115 |
} |
| 116 |
} |
| 117 |
|
| 118 |
$frag = strstr($uri, '#'); |
| 119 |
if ($frag) { |
| 120 |
$uri = substr($uri, 0, -strlen($frag)); |
| 121 |
} else { |
| 122 |
$frag = ''; |
| 123 |
} |
| 124 |
|
| 125 |
if (0 === stripos($uri, 'http://')) { |
| 126 |
$protocol = 'http://'; |
| 127 |
$uri = substr($uri, 7); |
| 128 |
} elseif (0 === stripos($uri, 'https://')) { |
| 129 |
$protocol = 'https://'; |
| 130 |
$uri = substr($uri, 8); |
| 131 |
} else { |
| 132 |
$protocol = ''; |
| 133 |
} |
| 134 |
|
| 135 |
if (strpos($uri, '?') !== false) { |
| 136 |
list($base, $query) = explode('?', $uri, 2); |
| 137 |
$base .= '?'; |
| 138 |
} elseif ($protocol || strpos($uri, '=') === false) { |
| 139 |
$base = $uri . '?'; |
| 140 |
$query = ''; |
| 141 |
} else { |
| 142 |
$base = ''; |
| 143 |
$query = $uri; |
| 144 |
} |
| 145 |
|
| 146 |
wp_parse_str($query, $qs); |
| 147 |
|
| 148 |
if (is_array($args[0])) { |
| 149 |
foreach ($args[0] as $k => $v) { |
| 150 |
$qs[$k] = $v; |
| 151 |
} |
| 152 |
} else { |
| 153 |
$qs[$args[0]] = $args[1]; |
| 154 |
} |
| 155 |
|
| 156 |
foreach ($qs as $k => $v) { |
| 157 |
if (false === $v) { |
| 158 |
unset($qs[$k]); |
| 159 |
} |
| 160 |
} |
| 161 |
|
| 162 |
$ret = build_query($qs); |
| 163 |
$ret = trim($ret, '?'); |
| 164 |
$ret = preg_replace('#=(&|$)#', '$1', $ret); |
| 165 |
$ret = $protocol . $base . $ret . $frag; |
| 166 |
$ret = rtrim($ret, '?'); |
| 167 |
return $ret; |
| 168 |
} |
| 169 |
|
| 170 |
/** |
| 171 |
* @param $terms array |
| 172 |
* @param $keys array |
| 173 |
* |
| 174 |
* @return array Array of objects with required keys |
| 175 |
*/ |
| 176 |
function flrt_extract_objects_vars($terms, $keys = []) |
| 177 |
{ |
| 178 |
$required = []; |
| 179 |
|
| 180 |
foreach ($terms as $i => $term) { |
| 181 |
$new_object = new \stdClass(); |
| 182 |
|
| 183 |
foreach ($keys as $key) { |
| 184 |
if (isset($term->$key)) { |
| 185 |
$new_object->$key = $term->$key; |
| 186 |
$required[$term->term_id] = $new_object; |
| 187 |
} |
| 188 |
} |
| 189 |
} |
| 190 |
|
| 191 |
return $required; |
| 192 |
} |
| 193 |
|
| 194 |
add_filter('wpc_check_broken_query_vars', function ($query_vars, $query) { |
| 195 |
if (is_admin()) { |
| 196 |
return $query_vars; |
| 197 |
} |
| 198 |
|
| 199 |
$detector_class = 'FilterEverything\\Filter\\WP_Query_Source_Detector'; |
| 200 |
$is_allowed_method = 'is_allowed'; |
| 201 |
$source_var = 'flrt_detected_source'; |
| 202 |
|
| 203 |
if (defined('FLRT_FILTERS_PRO')) { |
| 204 |
if (defined('FLRT_PRO_BUILDER_KEY')) { |
| 205 |
$builder_key = apply_filters('wpc_builder_key_pro', $query->get($source_var), constant('FLRT_PRO_BUILDER_KEY')); |
| 206 |
|
| 207 |
if ($detector_class::$is_allowed_method($builder_key)) { |
| 208 |
return $query_vars; |
| 209 |
} |
| 210 |
} |
| 211 |
} |
| 212 |
|
| 213 |
if (!defined('FLRT_FILTERS_PRO')) { |
| 214 |
$builder_key = apply_filters('wpc_builder_key', $query->get($source_var), $detector_class::$builder_key); |
| 215 |
|
| 216 |
if ($detector_class::$is_allowed_method($builder_key)) { |
| 217 |
return $query_vars; |
| 218 |
} |
| 219 |
} |
| 220 |
|
| 221 |
return []; |
| 222 |
}, 10, 2); |
| 223 |
|
| 224 |
add_filter('wpc_builder_key', function ($source, $builder_id) { |
| 225 |
return (int) sprintf("%u", crc32($source . $builder_id)); |
| 226 |
}, 10, 2); |
| 227 |
|
| 228 |
/** |
| 229 |
* Compatibility with membership / access-control plugins. |
| 230 |
* |
| 231 |
* Such plugins (e.g. Ultimate Membership Pro — indeed-membership-pro) inject |
| 232 |
* post__in / post__not_in into front-end queries to hide protected content from |
| 233 |
* non-authorised or logged-out visitors. That flips is_post__in / is_post__not_in |
| 234 |
* in the query-identity hash FE uses to match a Filter Set to a page query — so a |
| 235 |
* page that filters correctly for the (unrestricted) admin who saved the set stops |
| 236 |
* matching for restricted visitors, and filtering silently does nothing for them. |
| 237 |
* |
| 238 |
* We normalise those two flags back to their save-time value (false), but ONLY when |
| 239 |
* such a plugin is actually active. This keeps every saved query hash untouched on |
| 240 |
* sites that don't have this conflict. The per-page order counter still distinguishes |
| 241 |
* genuinely different same-shape queries, so filtering stays correct. |
| 242 |
*/ |
| 243 |
add_filter('wpc_check_broken_query_vars', function ($query_vars, $query) { |
| 244 |
// Add markers of other post-hiding plugins here if needed; overridable via the filter. |
| 245 |
$context_hides_posts = defined('IHC_PATH') // Ultimate Membership Pro |
| 246 |
|| defined('WCB2B_PLUGIN_FILE'); // WooCommerce B2B — hides "unallowed" products from guests/other groups via post__not_in |
| 247 |
|
| 248 |
if ( ! apply_filters('wpc_context_hides_posts', $context_hides_posts, $query) ) { |
| 249 |
return $query_vars; |
| 250 |
} |
| 251 |
|
| 252 |
// Only touch queries FE still considers filterable (its own callback empties the |
| 253 |
// rest at priority 10); never re-populate an emptied set. |
| 254 |
if ( is_array($query_vars) && array_key_exists('is_post__not_in', $query_vars) ) { |
| 255 |
$query_vars['is_post__in'] = false; |
| 256 |
$query_vars['is_post__not_in'] = false; |
| 257 |
} |
| 258 |
|
| 259 |
return $query_vars; |
| 260 |
}, 20, 2); |
| 261 |
|
| 262 |
function flrt_remove_level_array($array) |
| 263 |
{ |
| 264 |
/** |
| 265 |
* @feature maybe rewrite this full of shame code |
| 266 |
*/ |
| 267 |
if (!is_array($array)) { |
| 268 |
return []; |
| 269 |
} |
| 270 |
|
| 271 |
$flatten = []; |
| 272 |
|
| 273 |
array_map(function ($a) use (&$flatten) { |
| 274 |
if (is_array($a)) { |
| 275 |
$flatten = array_merge($flatten, $a); |
| 276 |
} |
| 277 |
}, |
| 278 |
$array); |
| 279 |
|
| 280 |
return $flatten; |
| 281 |
} |
| 282 |
|
| 283 |
add_filter('wpc_check_errors_ids', function ($error_ids, $query) { |
| 284 |
$source_key = 'flrt_detected_source'; |
| 285 |
if (empty($query->query_vars[$source_key])) { |
| 286 |
return $error_ids; |
| 287 |
} |
| 288 |
|
| 289 |
$source = $query->query_vars[$source_key]; |
| 290 |
$detector_class = 'FilterEverything\\Filter\\WP_Query_Source_Detector'; |
| 291 |
$is_allowed_method = 'is_allowed'; |
| 292 |
|
| 293 |
if (defined('FLRT_FILTERS_PRO')) { |
| 294 |
if (defined('FLRT_PRO_BUILDER_KEY')) { |
| 295 |
$builder_key = apply_filters('wpc_builder_key_pro', $source, constant('FLRT_PRO_BUILDER_KEY')); |
| 296 |
if ($detector_class::$is_allowed_method($builder_key)) { |
| 297 |
return $error_ids; |
| 298 |
} |
| 299 |
} |
| 300 |
} |
| 301 |
|
| 302 |
if (!defined('FLRT_FILTERS_PRO')) { |
| 303 |
$builder_key = apply_filters('wpc_builder_key', $source, $detector_class::$builder_key); |
| 304 |
|
| 305 |
if ($detector_class::$is_allowed_method($builder_key)) { |
| 306 |
return $error_ids; |
| 307 |
} |
| 308 |
} |
| 309 |
|
| 310 |
return []; |
| 311 |
}, 10, 2); |
| 312 |
|
| 313 |
function flrt_get_forbidden_prefixes() |
| 314 |
{ |
| 315 |
//@todo it seems all existing tax prefixes should be there |
| 316 |
// All them actual only when permalinks off |
| 317 |
$forbidden_prefixes = ['srch']; |
| 318 |
$permalinksEnabled = defined('FLRT_PERMALINKS_ENABLED') ? FLRT_PERMALINKS_ENABLED : false; |
| 319 |
if (!$permalinksEnabled) { |
| 320 |
$forbidden_prefixes = array_merge($forbidden_prefixes, array('cat', 'tag', 'page', 'author')); |
| 321 |
} |
| 322 |
|
| 323 |
if (flrt_wpml_active()) { |
| 324 |
$wpml_url_format = apply_filters('wpml_setting', 0, 'language_negotiation_type'); |
| 325 |
if ($wpml_url_format === '3') { |
| 326 |
$forbidden_prefixes[] = 'lang'; |
| 327 |
} |
| 328 |
} |
| 329 |
|
| 330 |
return apply_filters('wpc_forbidden_prefixes', $forbidden_prefixes); |
| 331 |
} |
| 332 |
|
| 333 |
function flrt_get_forbidden_meta_keys() |
| 334 |
{ |
| 335 |
$forbidden_meta_keys = array('wpc_filter_set_post_type', 'wpc_seo_rule_post_type'); |
| 336 |
return apply_filters('wpc_forbidden_meta_keys', $forbidden_meta_keys); |
| 337 |
} |
| 338 |
|
| 339 |
function flrt_array_contains_duplicate($array) |
| 340 |
{ |
| 341 |
return count($array) != count(array_unique($array)); |
| 342 |
} |
| 343 |
|
| 344 |
function flrt_create_filters_nonce() |
| 345 |
{ |
| 346 |
return FilterSet::createNonce(); |
| 347 |
} |
| 348 |
|
| 349 |
function flrt_get_filter_fields_mapping() |
| 350 |
{ |
| 351 |
return Container::instance()->getFilterFieldsService()->getFieldsMapping(); |
| 352 |
} |
| 353 |
|
| 354 |
function flrt_get_configured_filters($post_id) |
| 355 |
{ |
| 356 |
$filterFields = Container::instance()->getFilterFieldsService(); |
| 357 |
return $filterFields->getFiltersInputs($post_id); |
| 358 |
} |
| 359 |
|
| 360 |
function flrt_get_filter_view_name($view_key) |
| 361 |
{ |
| 362 |
$view_options = FilterFields::getViewOptions(); |
| 363 |
if (isset($view_options[$view_key])) { |
| 364 |
return esc_html($view_options[$view_key]); |
| 365 |
} |
| 366 |
|
| 367 |
return esc_html($view_key); |
| 368 |
} |
| 369 |
|
| 370 |
function flrt_get_filter_entity_name($entity_key) |
| 371 |
{ |
| 372 |
$em = Container::instance()->getEntityManager(); |
| 373 |
$entities = $em->getPossibleEntities(); |
| 374 |
|
| 375 |
foreach ($entities as $key => $entity_array) { |
| 376 |
if (isset($entity_array['entities'][$entity_key])) { |
| 377 |
return esc_html($entity_array['entities'][$entity_key]); |
| 378 |
} |
| 379 |
} |
| 380 |
|
| 381 |
if ($entity_key === 'post_meta_exists' && !defined('FLRT_FILTERS_PRO')) { |
| 382 |
return esc_html__('Available in PRO', 'filter-everything'); |
| 383 |
} |
| 384 |
|
| 385 |
return esc_html($entity_key); |
| 386 |
} |
| 387 |
|
| 388 |
function flrt_get_set_settings_fields($post_id) |
| 389 |
{ |
| 390 |
$filterSet = Container::instance()->getFilterSetService(); |
| 391 |
return $filterSet->getSettingsTypeFields($post_id); |
| 392 |
} |
| 393 |
|
| 394 |
function flrt_get_set_settings_location_fields($post_id) |
| 395 |
{ |
| 396 |
$filterSet = Container::instance()->getFilterSetService(); |
| 397 |
return $filterSet->getSettingsLocationTypeFields($post_id); |
| 398 |
} |
| 399 |
|
| 400 |
function flrt_extract_vars(&$array, $keys) |
| 401 |
{ |
| 402 |
$r = []; |
| 403 |
foreach ($keys as $key) { |
| 404 |
$var = flrt_extract_var($array, $key); |
| 405 |
if ($var) { |
| 406 |
$r[$key] = $var; |
| 407 |
} |
| 408 |
} |
| 409 |
return $r; |
| 410 |
} |
| 411 |
|
| 412 |
function flrt_extract_var(&$array, $key, $default = null) |
| 413 |
{ |
| 414 |
// check if exists |
| 415 |
// - uses array_key_exists to extract NULL values (isset will fail) |
| 416 |
if (is_array($array) && array_key_exists($key, $array)) { |
| 417 |
$v = $array[$key]; |
| 418 |
unset($array[$key]); |
| 419 |
return $v; |
| 420 |
} |
| 421 |
return $default; |
| 422 |
} |
| 423 |
|
| 424 |
function flrt_get_empty_filter($set_id) |
| 425 |
{ |
| 426 |
$filterFields = Container::instance()->getFilterFieldsService(); |
| 427 |
return $filterFields->getEmptyFilterObject($set_id); |
| 428 |
} |
| 429 |
|
| 430 |
function flrt_excluded_taxonomies() |
| 431 |
{ |
| 432 |
$excluded_taxonomies = array( |
| 433 |
'nav_menu', |
| 434 |
'link_category', |
| 435 |
'post_format', |
| 436 |
'template_category', |
| 437 |
'element_category', |
| 438 |
'fusion_tb_category', |
| 439 |
'slide-page', |
| 440 |
'elementor_font_type', |
| 441 |
'post_translations', |
| 442 |
'term_language', |
| 443 |
'term_translations', |
| 444 |
'wp_theme', |
| 445 |
'wp_template_part_area', |
| 446 |
'wp_pattern_category', |
| 447 |
'elementor_library_type', |
| 448 |
'elementor_library_category', |
| 449 |
); |
| 450 |
|
| 451 |
return apply_filters('wpc_excluded_taxonomies', $excluded_taxonomies); |
| 452 |
} |
| 453 |
|
| 454 |
function flrt_force_non_unique_slug($notNull, $originalSlug) |
| 455 |
{ |
| 456 |
return $originalSlug; |
| 457 |
} |
| 458 |
|
| 459 |
function flrt_redirect_to_error($post_id, $errors) |
| 460 |
{ |
| 461 |
$redirect = get_edit_post_link($post_id, 'url'); |
| 462 |
$error_code = 20; // Default error code |
| 463 |
|
| 464 |
if (!empty($errors) && is_array($errors)) { |
| 465 |
$error_code = reset($errors); |
| 466 |
} |
| 467 |
|
| 468 |
$redirect = add_query_arg('message', $error_code, $redirect); |
| 469 |
wp_redirect($redirect); |
| 470 |
exit; |
| 471 |
} |
| 472 |
|
| 473 |
function flrt_sanitize_int($var) |
| 474 |
{ |
| 475 |
return preg_replace('/[^\d]+/', '', $var); |
| 476 |
} |
| 477 |
|
| 478 |
function flrt_get_query_string_parameters() |
| 479 |
{ |
| 480 |
$container = Container::instance(); |
| 481 |
$get = $container->getTheGet(); |
| 482 |
$post = $container->getThePost(); |
| 483 |
|
| 484 |
// For compatibility with some Nginx configurations |
| 485 |
unset($get['q']); |
| 486 |
|
| 487 |
if (isset($post['flrt_ajax_link'])) { |
| 488 |
$parts = parse_url($post['flrt_ajax_link']); |
| 489 |
if (isset($parts['query'])) { |
| 490 |
parse_str($parts['query'], $output); |
| 491 |
return $output; |
| 492 |
} |
| 493 |
} |
| 494 |
|
| 495 |
return $get; |
| 496 |
} |
| 497 |
|
| 498 |
function flrt_get_option($key, $default = false) |
| 499 |
{ |
| 500 |
$settings = get_option('wpc_filter_settings'); |
| 501 |
|
| 502 |
if (isset($settings[$key])) { |
| 503 |
return apply_filters('wpc_get_option', $settings[$key], $key); |
| 504 |
} |
| 505 |
|
| 506 |
if ($default) { |
| 507 |
return $default; |
| 508 |
} |
| 509 |
|
| 510 |
return false; |
| 511 |
|
| 512 |
} |
| 513 |
|
| 514 |
function flrt_remove_option($key) |
| 515 |
{ |
| 516 |
$settings = get_option('wpc_filter_settings'); |
| 517 |
|
| 518 |
if (isset($settings[$key]) && $settings[$key]) { |
| 519 |
unset($settings[$key]); |
| 520 |
return update_option('wpc_filter_settings', $settings); |
| 521 |
} |
| 522 |
|
| 523 |
return false; |
| 524 |
} |
| 525 |
|
| 526 |
function flrt_change_option($option_key, $key, $value, $autoload = false) |
| 527 |
{ |
| 528 |
$settings = get_option($option_key); |
| 529 |
|
| 530 |
if ($settings[$key] === $value) { |
| 531 |
return true; |
| 532 |
} |
| 533 |
|
| 534 |
$settings = is_array($settings) ? $settings : []; |
| 535 |
$settings[$key] = $value; |
| 536 |
|
| 537 |
return update_option($option_key, $settings, $autoload); |
| 538 |
} |
| 539 |
|
| 540 |
function flrt_get_experimental_option($key, $default = false) |
| 541 |
{ |
| 542 |
/** |
| 543 |
* @todo This should be rewritten |
| 544 |
*/ |
| 545 |
$settings = get_option('wpc_filter_experimental'); |
| 546 |
|
| 547 |
if (isset($settings[$key])) { |
| 548 |
return apply_filters('wpc_get_option', $settings[$key], $key); |
| 549 |
} |
| 550 |
|
| 551 |
if ($default !== false) { |
| 552 |
return apply_filters('wpc_get_option', $default, $key); |
| 553 |
} |
| 554 |
|
| 555 |
return apply_filters('wpc_get_option', false, $key); |
| 556 |
|
| 557 |
} |
| 558 |
|
| 559 |
function flrt_term_id($name, $filter, $id, $echo = true) |
| 560 |
{ |
| 561 |
$attr = esc_attr("wpc-" . $name . "-" . $filter['entity'] . "-" . esc_attr($filter['e_name']) . "-" . $id); |
| 562 |
if ($echo) { |
| 563 |
echo $attr; |
| 564 |
} else { |
| 565 |
return $attr; |
| 566 |
} |
| 567 |
} |
| 568 |
|
| 569 |
function flrt_get_plugin_name() |
| 570 |
{ |
| 571 |
if (defined('FLRT_FILTERS_PRO')) { |
| 572 |
return esc_html__('Filter Everything Pro', 'filter-everything'); |
| 573 |
} else { |
| 574 |
return esc_html__('Filter Everything', 'filter-everything'); |
| 575 |
} |
| 576 |
} |
| 577 |
|
| 578 |
function flrt_get_plugin_url($type = 'about', $full = false) |
| 579 |
{ |
| 580 |
if ($full) { |
| 581 |
return esc_url($full); |
| 582 |
} |
| 583 |
|
| 584 |
return esc_url(FLRT_PLUGIN_URL . '/' . $type); |
| 585 |
} |
| 586 |
|
| 587 |
function flrt_get_term_by_slug($prefix) |
| 588 |
{ |
| 589 |
global $wpdb; |
| 590 |
|
| 591 |
$sql = "SELECT {$wpdb->terms}.slug FROM {$wpdb->terms} WHERE {$wpdb->terms}.slug = '%s'"; |
| 592 |
$sql = $wpdb->prepare($sql, $prefix); |
| 593 |
$result = $wpdb->get_row($sql); |
| 594 |
|
| 595 |
if (isset($result->slug) && $result->slug) { |
| 596 |
return $result->slug; |
| 597 |
} |
| 598 |
|
| 599 |
return false; |
| 600 |
} |
| 601 |
|
| 602 |
function flrt_walk_terms_tree($terms, $args) |
| 603 |
{ |
| 604 |
_deprecated_function('flrt_walk_terms_tree', '1.7.6', 'flrt_filter_walk_terms_tree()'); |
| 605 |
flrt_filter_walk_terms_tree($terms, $args); |
| 606 |
} |
| 607 |
|
| 608 |
function flrt_filter_walk_terms_tree($terms, $args) |
| 609 |
{ |
| 610 |
$walker = new \FilterEverything\Filter\WalkerCheckbox(); |
| 611 |
|
| 612 |
$depth = -1; |
| 613 |
if (isset($args['filter']['hierarchy']) && $args['filter']['hierarchy'] === 'yes') { |
| 614 |
$depth = 10; |
| 615 |
} |
| 616 |
|
| 617 |
return $walker->walk($terms, $depth, $args); |
| 618 |
} |
| 619 |
|
| 620 |
function flrt_get_all_parents($elements, $parent_id, &$ids) |
| 621 |
{ |
| 622 |
if (isset($elements[$parent_id]->parent) && $elements[$parent_id]->parent > 0) { |
| 623 |
$id = $elements[$parent_id]->parent; |
| 624 |
$ids_flipped = array_flip($ids); |
| 625 |
|
| 626 |
if (!isset($ids_flipped[$id])) { |
| 627 |
$ids[] = $id; |
| 628 |
} |
| 629 |
|
| 630 |
flrt_get_all_parents($elements, $id, $ids); |
| 631 |
} else { |
| 632 |
return $ids; |
| 633 |
} |
| 634 |
} |
| 635 |
|
| 636 |
function flrt_get_parents_with_not_empty_children($elements, $key = 'cross_count') |
| 637 |
{ |
| 638 |
$has_posts_in_children = []; |
| 639 |
|
| 640 |
if (empty($elements) || !is_array($elements)) { |
| 641 |
return $has_posts_in_children; |
| 642 |
} |
| 643 |
|
| 644 |
$new_elements = []; |
| 645 |
|
| 646 |
foreach ($elements as $k => $e) { |
| 647 |
$new_elements[$e->term_id] = $e; |
| 648 |
} |
| 649 |
|
| 650 |
$has_posts_in_children_flipped = array_flip($has_posts_in_children); |
| 651 |
|
| 652 |
foreach ($new_elements as $e) { |
| 653 |
if (isset($e->parent) && !empty($e->parent) && $e->$key > 0) { |
| 654 |
// Find all parents for term that contains posts |
| 655 |
if (!isset($has_posts_in_children_flipped[$e->parent])) { |
| 656 |
$has_posts_in_children[] = $e->parent; |
| 657 |
} |
| 658 |
|
| 659 |
flrt_get_all_parents($new_elements, $e->parent, $has_posts_in_children); |
| 660 |
} |
| 661 |
} |
| 662 |
|
| 663 |
return $has_posts_in_children; |
| 664 |
} |
| 665 |
|
| 666 |
function flrt_find_all_descendants($arr) |
| 667 |
{ |
| 668 |
$all_results = []; |
| 669 |
|
| 670 |
if (empty($arr) || !is_array($arr)) { |
| 671 |
return $all_results; |
| 672 |
} |
| 673 |
|
| 674 |
foreach ($arr as $k => $v) { |
| 675 |
$curr_result = []; |
| 676 |
|
| 677 |
for ($stack = [$k]; count($stack);) { |
| 678 |
$el = array_pop($stack); |
| 679 |
|
| 680 |
if (array_key_exists($el, $arr) && is_array($arr[$el])) { |
| 681 |
foreach ($arr[$el] as $child) { |
| 682 |
$curr_result [] = $child; |
| 683 |
$stack [] = $child; |
| 684 |
} |
| 685 |
} |
| 686 |
} |
| 687 |
|
| 688 |
if (count($curr_result)) { |
| 689 |
$all_results[$k] = $curr_result; |
| 690 |
} |
| 691 |
} |
| 692 |
|
| 693 |
return $all_results; |
| 694 |
} |
| 695 |
|
| 696 |
function flrt_debug_title() |
| 697 |
{ |
| 698 |
|
| 699 |
echo '<div class="wpc-debug-title">' . esc_html__('Filter Everything debug', 'filter-everything'); |
| 700 |
echo ' ' . flrt_help_tip( |
| 701 |
sprintf( |
| 702 |
__('Debug messages are visible for logged in administrators only. You can disable them in Filters -> <a href="%s">Settings</a> -> Debug mode.', 'filter-everything'), |
| 703 |
admin_url('edit.php?post_type=filter-set&page=filters-settings') |
| 704 |
), true) . '</div>'; |
| 705 |
} |
| 706 |
|
| 707 |
function flrt_is_debug_mode() |
| 708 |
{ |
| 709 |
$debug_mode = false; |
| 710 |
if (flrt_get_option('widget_debug_messages') === 'on') { |
| 711 |
if (current_user_can(flrt_plugin_user_caps())) { |
| 712 |
$debug_mode = true; |
| 713 |
} |
| 714 |
} |
| 715 |
|
| 716 |
return $debug_mode; |
| 717 |
} |
| 718 |
|
| 719 |
function flrt_clean($var) |
| 720 |
{ |
| 721 |
if (is_array($var)) { |
| 722 |
return array_map('flrt_clean', $var); |
| 723 |
} else { |
| 724 |
return is_scalar($var) ? sanitize_text_field($var) : $var; |
| 725 |
} |
| 726 |
} |
| 727 |
|
| 728 |
function flrt_sorting_option_value($order_by_value, $meta_keys, $orders, $i) |
| 729 |
{ |
| 730 |
$meta_key = isset($meta_keys[$i]) ? $meta_keys[$i] : ''; |
| 731 |
$order = isset($orders[$i]) ? $orders[$i] : ''; |
| 732 |
|
| 733 |
$option_value = $order_by_value; |
| 734 |
|
| 735 |
if (in_array($order_by_value, ['m', 'n'], true)) { |
| 736 |
$option_value .= $meta_key; |
| 737 |
} |
| 738 |
|
| 739 |
$option_value .= ($order === 'desc') ? '-' . $order : ''; |
| 740 |
|
| 741 |
return $option_value; |
| 742 |
} |
| 743 |
|
| 744 |
function flrt_get_active_plugins() |
| 745 |
{ |
| 746 |
|
| 747 |
if (is_multisite()) { |
| 748 |
$active_plugins = get_site_option('active_sitewide_plugins'); |
| 749 |
if (is_array($active_plugins)) { |
| 750 |
$active_plugins = array_keys($active_plugins); |
| 751 |
} |
| 752 |
|
| 753 |
$site_active_plugins = apply_filters('active_plugins', get_option('active_plugins')); |
| 754 |
$active_plugins = array_merge($active_plugins, $site_active_plugins); |
| 755 |
} else { |
| 756 |
$active_plugins = apply_filters('active_plugins', get_option('active_plugins')); |
| 757 |
} |
| 758 |
|
| 759 |
return $active_plugins; |
| 760 |
} |
| 761 |
|
| 762 |
/** |
| 763 |
* Version tag for FE transient cache NAMES. Bump it whenever the cached data |
| 764 |
* SHAPE changes (v2 = compact aggregated maps instead of raw SQL rows). |
| 765 |
* Versioned key names keep branches/versions with different cache formats |
| 766 |
* from ever reading each other's transients (e.g. when switching git branches |
| 767 |
* on a dev site) - each format lives under its own keys and stale ones simply |
| 768 |
* expire. |
| 769 |
*/ |
| 770 |
if ( ! defined( 'FLRT_CACHE_FORMAT_SUFFIX' ) ) { |
| 771 |
define( 'FLRT_CACHE_FORMAT_SUFFIX', '_v2' ); |
| 772 |
} |
| 773 |
|
| 774 |
function flrt_remove_empty_terms($checkTerms, $filter, $has_not_empty_children_flipped = [], $use_apply_button = false) |
| 775 |
{ |
| 776 |
|
| 777 |
if (!$use_apply_button) { |
| 778 |
foreach ($checkTerms as $index => $term) { |
| 779 |
if ($filter['hierarchy'] === 'yes') { |
| 780 |
|
| 781 |
if ($term->cross_count === 0 |
| 782 |
&& !isset($has_not_empty_children_flipped[$term->term_id])) { |
| 783 |
unset($checkTerms[$index]); |
| 784 |
} |
| 785 |
|
| 786 |
} else { |
| 787 |
if ($term->cross_count === 0) { |
| 788 |
unset($checkTerms[$index]); |
| 789 |
} |
| 790 |
} |
| 791 |
} |
| 792 |
} |
| 793 |
|
| 794 |
return $checkTerms; |
| 795 |
} |
| 796 |
|
| 797 |
function flrt_get_wp_queried_term($terms) |
| 798 |
{ |
| 799 |
$wp_queried_terms = false; |
| 800 |
|
| 801 |
foreach ($terms as $term) { |
| 802 |
if ($term->wp_queried === true) { |
| 803 |
$wp_queried_terms = $term; |
| 804 |
break; |
| 805 |
} |
| 806 |
} |
| 807 |
|
| 808 |
return $wp_queried_terms; |
| 809 |
} |
| 810 |
|
| 811 |
function flrt_get_filter_terms($filter, $posType, $em = false) |
| 812 |
{ |
| 813 |
if (!$em) { |
| 814 |
$em = Container::instance()->getEntityManager(); |
| 815 |
} |
| 816 |
|
| 817 |
$entityObj = $em->getEntityByFilter($filter, $posType); |
| 818 |
|
| 819 |
// The filter may lack entity/e_name (e.g. a parent_filter reference |
| 820 |
// to a filter that is absent from the rendered set) |
| 821 |
if (!$entityObj) { |
| 822 |
return []; |
| 823 |
} |
| 824 |
|
| 825 |
// Exclude or include terms |
| 826 |
$isInclude = (isset($filter['include']) && $filter['include'] === 'yes'); |
| 827 |
$entityObj->setExcludedTerms($filter['exclude'], $isInclude); |
| 828 |
|
| 829 |
$terms = $entityObj->getTerms(); |
| 830 |
|
| 831 |
return apply_filters('wpc_items_after_calc_term_count', $terms); |
| 832 |
} |
| 833 |
|
| 834 |
function flrt_str_replace($string = '', $search_replace = array()) |
| 835 |
{ |
| 836 |
$ignore = array(); |
| 837 |
unset($search_replace['']); |
| 838 |
|
| 839 |
foreach ($search_replace as $search => $replace) { |
| 840 |
if (in_array($search, $ignore)) { |
| 841 |
continue; |
| 842 |
} |
| 843 |
if (strpos($string, $search) === false) { |
| 844 |
continue; |
| 845 |
} |
| 846 |
$string = str_replace($search, $replace, $string); |
| 847 |
$ignore[] = $replace; |
| 848 |
} |
| 849 |
|
| 850 |
return $string; |
| 851 |
} |
| 852 |
|
| 853 |
function flrt_string_polyfill($data) { |
| 854 |
return map_deep( $data,'flrt_string_polyfill_body'); |
| 855 |
} |
| 856 |
|
| 857 |
function flrt_string_polyfill_body( $string ){ |
| 858 |
|
| 859 |
if ( ! is_string( $string ) ) { |
| 860 |
return $string; |
| 861 |
} |
| 862 |
|
| 863 |
$str = preg_replace('/\x00|<[^>]*>?/', '', $string ); |
| 864 |
return str_replace( ["'", '"'], [''', '"'], $str ); |
| 865 |
} |
| 866 |
|
| 867 |
if (!function_exists('flrt_set_transient')) { |
| 868 |
function flrt_set_transient($transient, $value, $expiration = 0) |
| 869 |
{ |
| 870 |
if (defined('FLRT_SET_TRANSIENT_ENABLED') && FLRT_SET_TRANSIENT_ENABLED) { |
| 871 |
set_transient($transient, $value, $expiration); |
| 872 |
} |
| 873 |
} |
| 874 |
} |
| 875 |
|
| 876 |
if (!function_exists('flrt_get_transient')) { |
| 877 |
function flrt_get_transient($transient) |
| 878 |
{ |
| 879 |
if (defined('FLRT_SET_TRANSIENT_ENABLED') && FLRT_SET_TRANSIENT_ENABLED) { |
| 880 |
return get_transient($transient); |
| 881 |
} |
| 882 |
return false; |
| 883 |
} |
| 884 |
} |
| 885 |
|
| 886 |
if (!class_exists('FlrtWooDiscountRules')) { |
| 887 |
class FlrtWooDiscountRules |
| 888 |
{ |
| 889 |
|
| 890 |
protected $rules; |
| 891 |
|
| 892 |
protected $base; |
| 893 |
protected $rule_helper; |
| 894 |
protected $discount_calculator; |
| 895 |
protected $manage_discount; |
| 896 |
|
| 897 |
//public $filter; |
| 898 |
public function __construct() |
| 899 |
{ |
| 900 |
$this->base = new Wdr\App\Controllers\Base(); |
| 901 |
$this->rule_helper = new Wdr\App\Helpers\Rule(); |
| 902 |
$this->manage_discount = new Wdr\App\Controllers\ManageDiscount(); |
| 903 |
$this->rules = $this->manage_discount->getDiscountRules(); |
| 904 |
$this->discount_calculator = new Wdr\App\Controllers\DiscountCalculator($this->rule_helper->getAvailableRules($this->base->getAvailableConditions())); |
| 905 |
} |
| 906 |
|
| 907 |
public function getProductPriceToDisplay($product) |
| 908 |
{ |
| 909 |
return $this->discount_calculator->getProductPriceToDisplay($product, 1); |
| 910 |
} |
| 911 |
} |
| 912 |
|
| 913 |
function flrt_woo_discount_rules_class() |
| 914 |
{ |
| 915 |
return new FlrtWooDiscountRules(); |
| 916 |
} |
| 917 |
} |
| 918 |
|
| 919 |
|
| 920 |
if (!function_exists('flrt_is_sitemap_exists')) { |
| 921 |
function flrt_is_sitemap_exists() |
| 922 |
{ |
| 923 |
$filepath = rtrim(FLRT_XML_PATH, '/\\') . '/filter-sitemap-index.xml'; |
| 924 |
return file_exists($filepath); |
| 925 |
} |
| 926 |
} |
| 927 |
if (!function_exists('flrt_get_index_sitemap')) { |
| 928 |
function flrt_get_index_sitemap() |
| 929 |
{ |
| 930 |
return fltr_get_url_from_absolute_path(FLRT_XML_PATH . '/filter-sitemap-index.xml'); |
| 931 |
} |
| 932 |
} |
| 933 |
|
| 934 |
if (!function_exists('fltr_get_url_from_absolute_path')) { |
| 935 |
function fltr_get_url_from_absolute_path($absolute_path) |
| 936 |
{ |
| 937 |
$wp_root_path = realpath(ABSPATH); |
| 938 |
$wp_url = site_url(); |
| 939 |
|
| 940 |
$file_path = realpath($absolute_path); |
| 941 |
|
| 942 |
if (!$file_path || strpos($file_path, $wp_root_path) !== 0) { |
| 943 |
return false; |
| 944 |
} |
| 945 |
|
| 946 |
|
| 947 |
$relative_path = str_replace($wp_root_path, '', $file_path); |
| 948 |
$relative_path = str_replace('\\', '/', $relative_path); |
| 949 |
|
| 950 |
return rtrim($wp_url, '/') . $relative_path; |
| 951 |
} |
| 952 |
} |
| 953 |
|
| 954 |
if (!function_exists('flrt_has_filter_seo_rules')) { |
| 955 |
function flrt_has_filter_seo_rules() |
| 956 |
{ |
| 957 |
$args = [ |
| 958 |
'post_type' => 'filter-seo-rule', |
| 959 |
'post_status' => 'publish', |
| 960 |
'posts_per_page' => 1, |
| 961 |
'fields' => 'ids', |
| 962 |
'no_found_rows' => true, |
| 963 |
]; |
| 964 |
|
| 965 |
$query = new WP_Query($args); |
| 966 |
return $query->have_posts(); |
| 967 |
} |
| 968 |
} |
| 969 |
|
| 970 |
if (!function_exists('flrt_get_last_modified_filter_seo_rule')) { |
| 971 |
function flrt_get_last_modified_filter_post_type($post_type) |
| 972 |
{ |
| 973 |
global $wpdb; |
| 974 |
$sql = " |
| 975 |
SELECT post_modified |
| 976 |
FROM {$wpdb->posts} |
| 977 |
WHERE post_type = '%s' |
| 978 |
AND post_status IN ('publish', 'trash') |
| 979 |
ORDER BY post_modified DESC |
| 980 |
LIMIT 1"; |
| 981 |
$query = $wpdb->prepare($sql, $post_type); |
| 982 |
$last_modified = $wpdb->get_var($query); |
| 983 |
|
| 984 |
if (!$last_modified) { |
| 985 |
return false; |
| 986 |
} |
| 987 |
return $last_modified; |
| 988 |
} |
| 989 |
} |
| 990 |
|
| 991 |
if (!function_exists('flrt_check_to_update_xml')) { |
| 992 |
function flrt_check_to_update_xml() |
| 993 |
{ |
| 994 |
$wpc_xml_write_date = get_option('wpc_xml_write_date'); |
| 995 |
if (!$wpc_xml_write_date) return false; |
| 996 |
|
| 997 |
$last_modified_filter_seo_rule = flrt_get_last_modified_filter_post_type(FLRT_SEO_RULES_POST_TYPE); |
| 998 |
$last_modified_filter_set = flrt_get_last_modified_filter_post_type(FLRT_FILTERS_SET_POST_TYPE); |
| 999 |
|
| 1000 |
if (!$last_modified_filter_seo_rule && !$last_modified_filter_set) return false; |
| 1001 |
|
| 1002 |
$wpc_xml_write_date = strtotime($wpc_xml_write_date); |
| 1003 |
$last_modified_filter_seo_rule = strtotime($last_modified_filter_seo_rule); |
| 1004 |
$last_modified_filter_set = strtotime($last_modified_filter_set); |
| 1005 |
|
| 1006 |
if ($last_modified_filter_seo_rule > $wpc_xml_write_date || $last_modified_filter_set > $wpc_xml_write_date) { |
| 1007 |
return true; |
| 1008 |
} |
| 1009 |
if ($wpc_xml_write_date !== false && !flrt_has_filter_seo_rules()) { |
| 1010 |
return true; |
| 1011 |
} |
| 1012 |
return false; |
| 1013 |
} |
| 1014 |
} |
| 1015 |
|
| 1016 |
|
| 1017 |
if (!function_exists('flrt_post_type_underline_transform')) { |
| 1018 |
function flrt_post_type_underline_transform($post_type) |
| 1019 |
{ |
| 1020 |
if (mb_strpos($post_type, '-') !== false) { |
| 1021 |
return str_replace('-', '_', $post_type); |
| 1022 |
} |
| 1023 |
return $post_type; |
| 1024 |
} |
| 1025 |
} |
| 1026 |
|
| 1027 |
|
| 1028 |
if (!function_exists('flrt_generate_unique_copy_title')) { |
| 1029 |
|
| 1030 |
/** |
| 1031 |
* Generates a unique copy title in the format: |
| 1032 |
* "Base Title – {copy_text} {N}". |
| 1033 |
* |
| 1034 |
* @param string $original_title The original post title to derive the base title from. |
| 1035 |
* If it already ends with "– {copy_text} N", that suffix is stripped. |
| 1036 |
* @param string $post_type The WordPress post type within which to check for duplicate titles. |
| 1037 |
* By default expects the FLRT_FILTERS_SET_POST_TYPE constant. |
| 1038 |
* @param string $copy_text The suffix text for copies (e.g., 'copy', 'duplicate'). |
| 1039 |
* @param int $start_number Numbering threshold: |
| 1040 |
* - if 0 (default), the first copy gets number "1"; |
| 1041 |
* - if 1, the first copy has no number; numbering appears only when |
| 1042 |
* a "… – {copy_text} 1" already exists. |
| 1043 |
* |
| 1044 |
* @return string The generated unique copy title. |
| 1045 |
*/ |
| 1046 |
|
| 1047 |
function flrt_generate_unique_copy_title($original_title, $post_type = FLRT_FILTERS_SET_POST_TYPE, $copy_text = 'copy', $number_position = true) |
| 1048 |
{ |
| 1049 |
global $wpdb; |
| 1050 |
if ($number_position) { |
| 1051 |
$preg_match_pattern = '/^(.*) – ' . preg_quote($copy_text, '/') . ' \d+$/'; |
| 1052 |
} |
| 1053 |
|
| 1054 |
if (!$number_position) { |
| 1055 |
$preg_match_pattern = '/^(.*) \d+ – ' . preg_quote($copy_text, '/') . '$/'; |
| 1056 |
} |
| 1057 |
|
| 1058 |
if (preg_match($preg_match_pattern, $original_title, $matches)) { |
| 1059 |
$base_title = $matches[1]; |
| 1060 |
} else { |
| 1061 |
$base_title = $original_title; |
| 1062 |
} |
| 1063 |
|
| 1064 |
if ($number_position) { |
| 1065 |
$copy_pattern = $wpdb->esc_like($base_title) . ' – ' . $wpdb->esc_like($copy_text) . '%'; |
| 1066 |
$titles = $wpdb->get_col( |
| 1067 |
$wpdb->prepare( |
| 1068 |
"SELECT post_title FROM $wpdb->posts |
| 1069 |
WHERE (post_title = %s OR post_title LIKE %s) |
| 1070 |
AND post_type = %s", |
| 1071 |
$base_title, |
| 1072 |
$copy_pattern, |
| 1073 |
$post_type |
| 1074 |
) |
| 1075 |
); |
| 1076 |
} |
| 1077 |
if (!$number_position) { |
| 1078 |
$copy_pattern = $wpdb->esc_like($base_title) . ' % – ' . $wpdb->esc_like($copy_text); |
| 1079 |
$titles = $wpdb->get_col( |
| 1080 |
$wpdb->prepare( |
| 1081 |
"SELECT post_title FROM $wpdb->posts |
| 1082 |
WHERE post_title LIKE %s |
| 1083 |
AND post_type = %s", |
| 1084 |
$copy_pattern, |
| 1085 |
$post_type |
| 1086 |
) |
| 1087 |
); |
| 1088 |
} |
| 1089 |
|
| 1090 |
$max_copy_number = 0; |
| 1091 |
|
| 1092 |
if ($number_position) { |
| 1093 |
$preg_match_pattern_title = '/^' . preg_quote($base_title, '/') . ' – ' . preg_quote($copy_text, '/') . ' (\d+)$/'; |
| 1094 |
|
| 1095 |
} |
| 1096 |
if (!$number_position) { |
| 1097 |
$preg_match_pattern_title = '/^' . preg_quote($base_title, '/') . ' (\d+) – ' . preg_quote($copy_text, '/') . '$/'; |
| 1098 |
} |
| 1099 |
|
| 1100 |
foreach ($titles as $title) { |
| 1101 |
if (preg_match($preg_match_pattern_title, $title, $m)) { |
| 1102 |
if (isset($m[1]) && is_numeric($m[1])) { |
| 1103 |
$num = intval($m[1]); |
| 1104 |
if ($num > $max_copy_number) { |
| 1105 |
$max_copy_number = $num; |
| 1106 |
} |
| 1107 |
} |
| 1108 |
} |
| 1109 |
} |
| 1110 |
|
| 1111 |
$new_number = $max_copy_number + 1; |
| 1112 |
|
| 1113 |
if ($number_position) { |
| 1114 |
$text = $base_title . ' – ' . $copy_text . ' ' . $new_number; |
| 1115 |
} |
| 1116 |
if (!$number_position) { |
| 1117 |
$text = $base_title . ' ' . $new_number . ' – ' . $copy_text; |
| 1118 |
} |
| 1119 |
return $text; |
| 1120 |
} |
| 1121 |
} |
| 1122 |
|
| 1123 |
if (!function_exists('flrt_get_delete_set_transient')) { |
| 1124 |
function flrt_refresh_temp_transient($set_name, $data) |
| 1125 |
{ |
| 1126 |
if (get_transient($set_name) !== false) { |
| 1127 |
delete_transient($set_name); |
| 1128 |
} |
| 1129 |
set_transient($set_name, $data, 300); |
| 1130 |
} |
| 1131 |
} |
| 1132 |
|
| 1133 |
if (!function_exists('flrt_view_admin_error')) { |
| 1134 |
function flrt_view_admin_error($text) |
| 1135 |
{ |
| 1136 |
$error_str = '<div class="notice notice-error is-dismissible"><p>%s</p></div>'; |
| 1137 |
printf( |
| 1138 |
$error_str, |
| 1139 |
$text |
| 1140 |
); |
| 1141 |
} |
| 1142 |
} |
| 1143 |
if (!function_exists('flrt_export_setting_icon')) { |
| 1144 |
function flrt_export_setting_icon() |
| 1145 |
{ |
| 1146 |
return '<svg xmlns="http://www.w3.org/2000/svg" fill="#99a2b2" width="19px" height="19px" viewBox="0 0 24 20"><polyline id="primary" points="15 3 21 3 21 9" style="fill: none; stroke: rgb(153,162,178); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"/><line id="primary-2" data-name="primary" x1="11" y1="13" x2="21" y2="3" style="fill: none; stroke: rgb(153,162,178); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"/><path id="primary-3" data-name="primary" d="M21,13v7a1,1,0,0,1-1,1H4a1,1,0,0,1-1-1V4A1,1,0,0,1,4,3h7" style="fill: none; stroke: rgb(153,162,178); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"/></svg>'; |
| 1147 |
} |
| 1148 |
} |
| 1149 |
|
| 1150 |
if (!function_exists('flrt_import_setting_icon')) { |
| 1151 |
function flrt_import_setting_icon() |
| 1152 |
{ |
| 1153 |
return '<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" width="19px" height="19px" viewBox="0 0 24 23" id="wpc-import-icon"><polyline id="primary" points="17 13 11 13 11 7" style="fill: none; stroke: rgb(153,162,178); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"/><line id="primary-2" data-name="primary" x1="21" y1="3" x2="11" y2="13" style="fill: none; stroke: rgb(153,162,178); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"/><path id="primary-3" data-name="primary" d="M21,13v7a1,1,0,0,1-1,1H4a1,1,0,0,1-1-1V4A1,1,0,0,1,4,3h7" style="fill: none; stroke: rgb(153,162,178); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"/></svg>'; |
| 1154 |
} |
| 1155 |
} |
| 1156 |
|
| 1157 |
if (!function_exists('flrt_open_in_new_tab_icon')) { |
| 1158 |
function flrt_open_in_new_tab_icon() |
| 1159 |
{ |
| 1160 |
$icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 21" width="18" height="18" aria-hidden="true" focusable="false"> |
| 1161 |
<path d="M19.5 4.5h-7V6h4.44l-5.97 5.97 1.06 1.06L18 7.06v4.44h1.5v-7Zm-13 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2v-3H17v3a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h3V5.5h-3Z"></path></svg>'; |
| 1162 |
return wp_kses( |
| 1163 |
$icon, |
| 1164 |
array( |
| 1165 |
'svg' => array( |
| 1166 |
'xmlns' => true, |
| 1167 |
'viewbox' => true, |
| 1168 |
'width' => true, |
| 1169 |
'height' => true, |
| 1170 |
'aria-hidden' => true, |
| 1171 |
'focusable' => true, |
| 1172 |
), |
| 1173 |
'path' => array( |
| 1174 |
'd' => true |
| 1175 |
), |
| 1176 |
) |
| 1177 |
); |
| 1178 |
} |
| 1179 |
} |
| 1180 |
|
| 1181 |
if (!function_exists('flrt_vailable_in_pro_attr_link')) { |
| 1182 |
function flrt_vailable_in_pro_attr_link($target_blank = false): string |
| 1183 |
{ |
| 1184 |
$link = 'edit.php?post_type=' . FLRT_FILTERS_SET_POST_TYPE . '&page=flrt-pro'; |
| 1185 |
if ($target_blank) { |
| 1186 |
$link .= '_target=blank'; |
| 1187 |
} |
| 1188 |
return $link; |
| 1189 |
} |
| 1190 |
} |
| 1191 |
if (!function_exists('flrt_pro_promo_label')) { |
| 1192 |
function flrt_pro_promo_label($replace_class = false): string |
| 1193 |
{ |
| 1194 |
$class = $replace_class ? 'wpc-pro-badge' : 'wpc-pro-badge-transparent'; |
| 1195 |
$label = ' <span class="' . $class . '">' . esc_html__('PRO', 'filter-everything') . '</span>'; |
| 1196 |
|
| 1197 |
return wp_kses($label, [ |
| 1198 |
'span' => [ |
| 1199 |
'class' => [] |
| 1200 |
] |
| 1201 |
]); |
| 1202 |
} |
| 1203 |
} |
| 1204 |
|
| 1205 |
if(!function_exists( 'flrt_unlock_icon')){ |
| 1206 |
function flrt_unlock_icon($width = '20px', $height = '20px', $color = '#3858E9') |
| 1207 |
{ |
| 1208 |
return '<svg xmlns="http://www.w3.org/2000/svg" height="' . $height . '" viewBox="0 -960 960 960" width="' . $width . '" fill="' . $color . '"><path d="M264-624h336v-96q0-50-35-85t-85-35q-50 0-85 35t-35 85h-72q0-80 56.23-136 56.22-56 136-56Q560-912 616-855.84q56 56.16 56 135.84v96h24q29.7 0 50.85 21.15Q768-581.7 768-552v384q0 29.7-21.16 50.85Q725.68-96 695.96-96H263.72Q234-96 213-117.15T192-168v-384q0-29.7 21.15-50.85Q234.3-624 264-624Zm0 456h432v-384H264v384Zm216.21-120Q510-288 531-309.21t21-51Q552-390 530.79-411t-51-21Q450-432 429-410.79t-21 51Q408-330 429.21-309t51 21ZM264-168v-384 384Z"/></svg>'; |
| 1209 |
} |
| 1210 |
} |
| 1211 |
|
| 1212 |
if(!function_exists( 'flrt_crown_icon')){ |
| 1213 |
function flrt_crown_icon($width = '16px', $height = '16px', $color = '#FFFFFF') |
| 1214 |
{ |
| 1215 |
return '<svg xmlns="http://www.w3.org/2000/svg" fill="' . $color . '" viewBox="0 0 16 16" width="' . $width . '" height="' . $height . '" class="wpc-crown-icon"><path fill="' . $color . '" d="M8.687 1.932c-.238-.634-1.136-.634-1.374 0l-1.642 4.38-3.167-2.11a.733.733 0 0 0-1.126.753L3.333 12h9.334l1.955-7.045a.733.733 0 0 0-1.126-.754L10.33 6.313zM6.654 7.49 8 3.899l1.346 3.59c.166.442.7.614 1.094.352l2.59-1.727-1.363 4.553H4.333L2.97 6.114 5.56 7.841a.733.733 0 0 0 1.094-.352m6.013 5.844H3.333v1.334h9.334z"></path></svg>'; |
| 1216 |
} |
| 1217 |
} |
| 1218 |
|
| 1219 |
if(!function_exists( 'flrt_unlock_in_pro')){ |
| 1220 |
function flrt_unlock_in_pro($button_text = '') |
| 1221 |
{ |
| 1222 |
$string = '<a class="wpc-available-in-pro-button" href="' . admin_url(flrt_vailable_in_pro_attr_link()) . '">'; |
| 1223 |
$string .= !empty($button_text) ? $button_text . ' - ': ''; |
| 1224 |
$string .= flrt_unlock_icon(); |
| 1225 |
$string .= '<span>' . esc_html__('Unlock with PRO', 'filter-everything') . '</span></a>'; |
| 1226 |
return $string; |
| 1227 |
} |
| 1228 |
} |
| 1229 |
|
| 1230 |
|
| 1231 |
add_filter('wpc_filter_default_fields', 'flrt_add_pro_promo_fields', 10, 2); |
| 1232 |
|
| 1233 |
|
| 1234 |
add_action('wp_footer', function () { |
| 1235 |
if (current_user_can(flrt_plugin_user_caps())) |
| 1236 |
if (!wp_script_is('wpc-filter-everything')) { |
| 1237 |
{ |
| 1238 |
?> |
| 1239 |
<script> |
| 1240 |
jQuery(function ($) { |
| 1241 |
$(document).on('click', '.wpc-open-close-filters-button', function (e) { |
| 1242 |
e.preventDefault(); |
| 1243 |
let openCloseButton = $(this); |
| 1244 |
let wpcButtonFilterSetError = openCloseButton.data('wpcButtonFilterSetError'); |
| 1245 |
let wpcButtonWidgetError = openCloseButton.data('wpcButtonWidgetError'); |
| 1246 |
|
| 1247 |
if (typeof wpcButtonFilterSetError !== 'undefined') { |
| 1248 |
alert(wpcButtonFilterSetError); |
| 1249 |
} |
| 1250 |
if (typeof wpcButtonWidgetError !== 'undefined') { |
| 1251 |
if (typeof window.wpcFilterWidgetActive === 'undefined') { |
| 1252 |
alert(wpcButtonWidgetError); |
| 1253 |
} |
| 1254 |
} |
| 1255 |
}); |
| 1256 |
}); |
| 1257 |
</script> |
| 1258 |
<?php |
| 1259 |
} |
| 1260 |
} |
| 1261 |
}); |
| 1262 |
|
| 1263 |
function flrt_log( $message, $data = null ) { |
| 1264 |
if ( ! defined('WP_DEBUG_LOG') || ! WP_DEBUG_LOG ) { |
| 1265 |
return; |
| 1266 |
} |
| 1267 |
|
| 1268 |
$log = '[Filter Everything] ' . $message; |
| 1269 |
|
| 1270 |
if ( $data !== null ) { |
| 1271 |
$log .= ' | ' . wp_json_encode( $data ); |
| 1272 |
} |
| 1273 |
|
| 1274 |
error_log( $log ); |
| 1275 |
} |
| 1276 |
|
| 1277 |
function prepare_wpc_filter_set_json_data($postData) |
| 1278 |
{ |
| 1279 |
if(!empty($postData['wpc_filter_set_json_data'])){ |
| 1280 |
$postData = json_decode(stripslashes($postData['wpc_filter_set_json_data']), true); |
| 1281 |
$postData['wpc_set_fields']['wp_filter_query_vars'] = wp_slash($postData['wpc_set_fields']['wp_filter_query_vars']); |
| 1282 |
} |
| 1283 |
return $postData; |
| 1284 |
} |
| 1285 |
|