a835ba3662
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
198 lines
6.2 KiB
PHP
198 lines
6.2 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace WPMultiCity;
|
|
|
|
final class Helpers
|
|
{
|
|
private static ?string $current_town_memo = null;
|
|
private static bool $current_town_resolved = false;
|
|
private static array $term_cache = [];
|
|
private static array $page_unic_cache = [];
|
|
private static int $bypass_depth = 0;
|
|
|
|
public static function reset_cache(): void
|
|
{
|
|
self::$current_town_memo = null;
|
|
self::$current_town_resolved = false;
|
|
self::$term_cache = [];
|
|
self::$page_unic_cache = [];
|
|
self::$bypass_depth = 0;
|
|
}
|
|
|
|
public static function get_term_by_slug(string $slug, string $taxonomy = 'town'): ?\WP_Term
|
|
{
|
|
$key = $taxonomy . '|' . $slug;
|
|
if (array_key_exists($key, self::$term_cache)) {
|
|
return self::$term_cache[$key];
|
|
}
|
|
$term = \get_term_by('slug', $slug, $taxonomy);
|
|
return self::$term_cache[$key] = ($term instanceof \WP_Term) ? $term : null;
|
|
}
|
|
|
|
public static function current_town(): ?string
|
|
{
|
|
if (self::$current_town_resolved) {
|
|
return self::$current_town_memo;
|
|
}
|
|
|
|
$uri = $_SERVER['REQUEST_URI'] ?? '/';
|
|
$first_segment = self::first_path_segment($uri);
|
|
|
|
$resolved = null;
|
|
if ($first_segment !== null) {
|
|
$terms = \get_terms([
|
|
'taxonomy' => 'town',
|
|
'hide_empty' => false,
|
|
'fields' => 'id=>slug',
|
|
]);
|
|
if (is_array($terms) && in_array($first_segment, $terms, true)) {
|
|
$resolved = $first_segment;
|
|
}
|
|
}
|
|
|
|
if ($resolved === null) {
|
|
$resolved = \apply_filters('wpmc_main_town_slug', null);
|
|
if (!is_string($resolved) || $resolved === '') {
|
|
$resolved = null;
|
|
}
|
|
}
|
|
|
|
$resolved = \apply_filters('wpmc_current_town_slug', $resolved);
|
|
if (!is_string($resolved) || $resolved === '') {
|
|
$resolved = null;
|
|
}
|
|
|
|
self::$current_town_memo = $resolved;
|
|
self::$current_town_resolved = true;
|
|
return $resolved;
|
|
}
|
|
|
|
private static function first_path_segment(string $uri): ?string
|
|
{
|
|
$path = strtok($uri, '?');
|
|
if ($path === false) {
|
|
return null;
|
|
}
|
|
$parts = array_values(array_filter(explode('/', $path), static fn(string $p) => $p !== ''));
|
|
return $parts[0] ?? null;
|
|
}
|
|
|
|
public static function alt_get_field(string $selector, $post_id = false, bool $format_value = true)
|
|
{
|
|
$post_id = \apply_filters('wpmc_alt_get_field_post_id', $post_id, $selector);
|
|
if (!\function_exists('get_field')) {
|
|
return null;
|
|
}
|
|
$value = \get_field($selector, $post_id, $format_value);
|
|
return is_string($value) ? \do_shortcode($value) : $value;
|
|
}
|
|
|
|
public static function remove_domain_link(string $url): string
|
|
{
|
|
$parsed = parse_url($url);
|
|
if ($parsed === false || empty($parsed['scheme'])) {
|
|
return $url;
|
|
}
|
|
$scheme = strtolower((string) $parsed['scheme']);
|
|
if ($scheme !== 'http' && $scheme !== 'https') {
|
|
return $url;
|
|
}
|
|
$path = $parsed['path'] ?? '';
|
|
$query = isset($parsed['query']) ? '?' . $parsed['query'] : '';
|
|
$fragment = isset($parsed['fragment']) ? '#' . $parsed['fragment'] : '';
|
|
return $path . $query . $fragment;
|
|
}
|
|
|
|
public static function index_town_alt_page_id(): ?int
|
|
{
|
|
if (!\function_exists('get_field')) {
|
|
return null;
|
|
}
|
|
$value = \get_field('index_town_alt', 'option');
|
|
$id = (int) $value;
|
|
return $id > 0 ? $id : null;
|
|
}
|
|
|
|
public static function main_town_slug(): ?string
|
|
{
|
|
if (!\function_exists('get_field')) {
|
|
return null;
|
|
}
|
|
$value = \get_field('main_town_slug', 'option');
|
|
if ($value instanceof \WP_Term) {
|
|
return $value->slug !== '' ? $value->slug : null;
|
|
}
|
|
return is_string($value) && $value !== '' ? $value : null;
|
|
}
|
|
|
|
public static function page_unic_swap(int $page_id_old, string $town_slug): ?int
|
|
{
|
|
$key = $page_id_old . '|' . $town_slug;
|
|
if (array_key_exists($key, self::$page_unic_cache)) {
|
|
return self::$page_unic_cache[$key];
|
|
}
|
|
$term = self::get_term_by_slug($town_slug);
|
|
if ($term === null) {
|
|
return self::$page_unic_cache[$key] = null;
|
|
}
|
|
if (!\function_exists('get_field')) {
|
|
return self::$page_unic_cache[$key] = null;
|
|
}
|
|
$rows = \get_field('page_unic', 'option');
|
|
if (!is_array($rows)) {
|
|
return self::$page_unic_cache[$key] = null;
|
|
}
|
|
foreach ($rows as $row) {
|
|
if (!is_array($row)) {
|
|
continue;
|
|
}
|
|
if ((int) ($row['town'] ?? 0) === (int) $term->term_id
|
|
&& (int) ($row['page_old'] ?? 0) === $page_id_old) {
|
|
$new = (int) ($row['page_new'] ?? 0);
|
|
return self::$page_unic_cache[$key] = $new > 0 ? $new : null;
|
|
}
|
|
}
|
|
return self::$page_unic_cache[$key] = null;
|
|
}
|
|
|
|
public static function is_routable_path(?string $path = null): bool
|
|
{
|
|
if ($path === null) {
|
|
$path = $_SERVER['REQUEST_URI'] ?? '/';
|
|
}
|
|
if (!\function_exists('get_field')) {
|
|
return true;
|
|
}
|
|
$exclusions = \get_field('page_no_rep', 'option');
|
|
if (!is_array($exclusions) || $exclusions === []) {
|
|
return true;
|
|
}
|
|
foreach ($exclusions as $row) {
|
|
if (!is_array($row) || empty($row['link'])) {
|
|
continue;
|
|
}
|
|
$needle = (string) $row['link'];
|
|
if ($needle !== '' && strpos($path, $needle) !== false) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public static function without_url_filters(callable $fn)
|
|
{
|
|
self::$bypass_depth++;
|
|
try {
|
|
return $fn();
|
|
} finally {
|
|
self::$bypass_depth--;
|
|
}
|
|
}
|
|
|
|
public static function is_bypassed(): bool
|
|
{
|
|
return self::$bypass_depth > 0;
|
|
}
|
|
}
|