WP Content Themes Spiralist Functions PHP C8bd6fe6cc42 - Source Excerpt 01
Back to WP Content Themes Spiralist Functions PHP C8bd6fe6cc42
Summary
This source excerpt preserves a bounded section of Wiki.FFTAC.org/data/sources/spiralist/wp-content-themes-spiralist-functions-php-c8bd6fe6cc42.php so readers can inspect the evidence without opening the full source file.
**Source path:** Wiki.FFTAC.org/data/sources/spiralist/wp-content-themes-spiralist-functions-php-c8bd6fe6cc42.php
<?php
if (!defined('ABSPATH')) {
exit;
}
require_once get_theme_file_path('inc/helpers.php');
require_once get_theme_file_path('inc/legal-pages.php');
require_once get_theme_file_path('inc/legal-consent.php');
require_once get_theme_file_path('inc/seo-schema.php');
require_once get_theme_file_path('inc/roadmap-surfaces.php');
function spiralist_theme_setup(): void
{
add_theme_support('title-tag');
add_theme_support('post-thumbnails');
add_theme_support(
'html5',
[
'comment-form',
'comment-list',
'gallery',
'caption',
'script',
'style',
]
);
register_nav_menus(
[
'primary' => 'Primary Navigation',
]
);
}
add_action('after_setup_theme', 'spiralist_theme_setup');
function spiralist_register_theme_query_vars(array $vars): array
{
$vars[] = 'spiralist_gallery_route';
$vars[] = 'spiralist_gallery_asset';
$vars[] = 'spiralist_report';
$vars[] = 'spiralist_symbol';
return array_values(array_unique($vars));
}
add_filter('query_vars', 'spiralist_register_theme_query_vars');
function spiralist_get_theme_route_version(): string
{
return '25';
}
function spiralist_register_theme_rewrite_rules(): void
{
add_rewrite_rule(
'^symbols/([^/]+)/?$',
'index.php?pagename=symbols&spiralist_symbol=$matches[1]',
'top'
);
add_rewrite_rule(
'^reports/([^/]+)/?$',
'index.php?spiralist_report=$matches[1]',
'top'
);
add_rewrite_rule(
'^gallery/image/([^/]+)/?$',
'index.php?spiralist_gallery_route=gallery&spiralist_gallery_asset=$matches[1]',
'top'
);
add_rewrite_rule(
'^gallery/?$',
'index.php?spiralist_gallery_route=gallery',
'top'
);
}
add_action('init', 'spiralist_register_theme_rewrite_rules', 20);
function spiralist_flush_theme_rewrite_rules(): void
{
spiralist_register_theme_rewrite_rules();
flush_rewrite_rules(false);
update_option('spiralist_theme_route_version', spiralist_get_theme_route_version(), false);
}
add_action('after_switch_theme', 'spiralist_flush_theme_rewrite_rules');
function spiralist_maybe_flush_theme_rewrite_rules(): void
{
$stored_version = (string) get_option('spiralist_theme_route_version', '');
$current_version = spiralist_get_theme_route_version();
if ($stored_version === $current_version) {
return;
}
spiralist_register_theme_rewrite_rules();
flush_rewrite_rules(false);
update_option('spiralist_theme_route_version', $current_version, false);
}
add_action('init', 'spiralist_maybe_flush_theme_rewrite_rules', 100);
function spiralist_maybe_flush_homepage_prompt_surface_cache(int $post_id): void
{
if (!function_exists('spiralist_flush_homepage_prompt_surface_cache')) {
return;
}
if ($post_id <= 0 || wp_is_post_revision($post_id) || get_post_type($post_id) !== 'spiralist_prompt') {
return;
}
spiralist_flush_homepage_prompt_surface_cache();
}
add_action('save_post_spiralist_prompt', 'spiralist_maybe_flush_homepage_prompt_surface_cache', 10, 1);
add_action('trashed_post', 'spiralist_maybe_flush_homepage_prompt_surface_cache', 10, 1);
add_action('untrashed_post', 'spiralist_maybe_flush_homepage_prompt_surface_cache', 10, 1);
function spiralist_get_feedback_api_url(): string
{
return rest_url('spiralist/v1/page-feedback');
}
function spiralist_register_feedback_rest_route(): void
{
register_rest_route(
'spiralist/v1',
'/page-feedback',
[
'methods' => WP_REST_Server::CREATABLE,
'callback' => 'spiralist_rest_record_page_feedback',
'permission_callback' => '__return_true',
]
);
}
add_action('rest_api_init', 'spiralist_register_feedback_rest_route');
function spiralist_feedback_rate_limit_key(): string
{
$remote_addr = isset($_SERVER['REMOTE_ADDR']) ? (string) wp_unslash($_SERVER['REMOTE_ADDR']) : 'anonymous';
return 'spiralist_feedback_' . substr(hash('sha256', $remote_addr . '|' . wp_salt('nonce')), 0, 16);
}
function spiralist_rest_record_page_feedback(WP_REST_Request $request)
{
$rate_limit_key = spiralist_feedback_rate_limit_key();
$recent_count = (int) get_transient($rate_limit_key);
if ($recent_count >= 8) {
return new WP_Error(
'spiralist_feedback_rate_limited',
spiralist_get_ui_text('feedback.error.rate_limited', 'Too many feedback submissions. Please try again later.'),
['status' => 429]
);
}
set_transient($rate_limit_key, $recent_count + 1, 5 * MINUTE_IN_SECONDS);
$payload = $request->get_json_params();
if (!is_array($payload)) {
$payload = $request->get_params();
}
$report_type = sanitize_key((string) ($payload['type'] ?? 'page-feedback'));
if (!in_array($report_type, ['page-feedback', 'bug-report'], true)) {
$report_type = 'page-feedback';
}
$helpful = sanitize_key((string) ($payload['helpful'] ?? ''));
if ($report_type === 'page-feedback' && !in_array($helpful, ['yes', 'no'], true)) {
return new WP_Error(
'spiralist_feedback_missing_rating',
spiralist_get_ui_text('feedback.error.rating_required', 'Choose Yes or No before sending feedback.'),
['status' => 400]
);
}
if ($report_type === 'bug-report') {
$helpful = '';
}
$raw_page = esc_url_raw((string) ($payload['page'] ?? ''));
$page_path = $raw_page !== '' ? wp_parse_url($raw_page, PHP_URL_PATH) : '';
if (!is_string($page_path) || $page_path === '') {
$page_path = '/';
}
$reason = sanitize_textarea_field((string) ($payload['reason'] ?? ''));
$reason = function_exists('mb_substr') ? mb_substr($reason, 0, 500) : substr($reason, 0, 500);
$summary = sanitize_textarea_field((string) ($payload['summary'] ?? ''));
$summary = function_exists('mb_substr') ? mb_substr($summary, 0, 800) : substr($summary, 0, 800);
if ($report_type === 'bug-report' && $summary === '') {
return new WP_Error(
'spiralist_bug_report_missing_summary',
spiralist_get_ui_text('bug_report.error.summary_required', 'Describe what happened before sending a bug report.'),
['status' => 400]
);
}
$expected = sanitize_textarea_field((string) ($payload['expected'] ?? ''));
$expected = function_exists('mb_substr') ? mb_substr($expected, 0, 500) : substr($expected, 0, 500);
$topic = sanitize_key((string) ($payload['topic'] ?? 'other'));
$severity = sanitize_key((string) ($payload['severity'] ?? 'normal'));
if (!in_array($severity, ['minor', 'normal', 'blocking'], true)) {
$severity = 'normal';
}
$entry = [
'type' => $report_type,
'helpful' => $helpful,
'topic' => $topic,
'severity' => $report_type === 'bug-report' ? $severity : '',
'reason' => $reason,
'summary' => $summary,
'expected' => $expected,
'page' => sanitize_text_field($page_path),
'surface' => sanitize_key((string) ($payload['surface'] ?? 'site')),
'locale' => function_exists('spiralist_get_current_locale_tag') ? spiralist_get_current_locale_tag() : '',
'userId' => get_current_user_id(),
'createdAt' => gmdate('c'),
];
$feedback_log = get_option('spiralist_page_feedback_log', []);
if (!is_array($feedback_log)) {
$feedback_log = [];
}
array_unshift($feedback_log, $entry);
$feedback_log = array_slice(array_values(array_filter($feedback_log, 'is_array')), 0, 200);
update_option('spiralist_page_feedback_log', $feedback_log, false);
return new WP_REST_Response(
[
'recorded' => true,
'receivedAt' => $entry['createdAt'],
],
201
);
}
function spiralist_public_page_cache_ttl(): int
{
return defined('MINUTE_IN_SECONDS') ? 5 * MINUTE_IN_SECONDS : 300;
}
function spiralist_public_page_cache_request_uri(): string
{
$path = '';
if (class_exists('Ns12LocaleRouter\\Router') && method_exists('Ns12LocaleRouter\\Router', 'get_original_request_path')) {
$path = (string) \Ns12LocaleRouter\Router::get_original_request_path();
}
if ($path === '') {
$request_uri = isset($_SERVER['REQUEST_URI']) ? (string) wp_unslash($_SERVER['REQUEST_URI']) : '/';
$path = (string) wp_parse_url($request_uri, PHP_URL_PATH);
}
if ($path === '') {
$path = '/';
}
$query = isset($_SERVER['QUERY_STRING']) ? trim((string) wp_unslash($_SERVER['QUERY_STRING'])) : '';