Skip to content
wiki.fftac.org

Workstation - Source Excerpt 01

Back to Workstation

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/ns12-manuscript/includes/workstation.php so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/includes/workstation.php

<?php

if (!defined('ABSPATH')) {
    exit;
}

function spiralist_book_pages_get_manuscript_workstation_meta_key(): string
{
    return '_spiralist_manuscript_folio_crops';
}

function spiralist_book_pages_get_manuscript_workstation_option_key(): string
{
    return 'spiralist_book_pages_manuscript_folio_crops';
}

function spiralist_book_pages_get_manuscript_page_post_id(): int
{
    static $page_id = null;

    if (is_int($page_id)) {
        return $page_id;
    }

    $page = get_page_by_path('manuscript');
    $page_id = $page instanceof WP_Post ? (int) $page->ID : 0;

    return $page_id;
}

function spiralist_book_pages_can_edit_manuscript_workstation(): bool
{
    $page_id = spiralist_book_pages_get_manuscript_page_post_id();

    if ($page_id > 0 && current_user_can('edit_post', $page_id)) {
        return true;
    }

    return current_user_can('edit_pages') || current_user_can('manage_options');
}

function spiralist_book_pages_get_manuscript_workstation_action_links(): array
{
    $page_id = spiralist_book_pages_get_manuscript_page_post_id();
    $upload_url = '';
    $library_url = '';
    $prompt_url = '';
    $fragment_url = '';

    if (function_exists('spiralist_book_pages_admin_can_manage') && spiralist_book_pages_admin_can_manage()) {
        $upload_url = admin_url('admin.php?page=ns12-manuscript-folios') . '#bulk-import';
        $library_url = admin_url('admin.php?page=ns12-manuscript-folios');
        $prompt_url = admin_url('admin.php?page=ns12-manuscript-prompts');
        $fragment_url = admin_url('admin.php?page=ns12-manuscript-fragments');
    } elseif (spiralist_book_pages_can_edit_manuscript_workstation()) {
        $upload_url = add_query_arg(
            [
                'post_id' => $page_id > 0 ? $page_id : 0,
            ],
            admin_url('media-new.php')
        );

        $library_url = admin_url('upload.php');
    }

    return [
        'upload_url' => $upload_url,
        'library_url' => $library_url,
        'prompt_url' => $prompt_url,
        'fragment_url' => $fragment_url,
    ];
}

function spiralist_book_pages_get_default_manuscript_crop_rect(): array
{
    return [
        'x' => 0.08,
        'y' => 0.06,
        'width' => 0.84,
        'height' => 0.88,
    ];
}

function spiralist_book_pages_clamp_manuscript_crop_value($value, float $fallback): float
{
    if (!is_numeric($value)) {
        return $fallback;
    }

    $normalized = round((float) $value, 6);

    return max(0.0, min(1.0, $normalized));
}

function spiralist_book_pages_sanitize_manuscript_crop_rect($crop): array
{
    $defaults = spiralist_book_pages_get_default_manuscript_crop_rect();

    if (!is_array($crop)) {
        return $defaults;
    }

    $x = spiralist_book_pages_clamp_manuscript_crop_value($crop['x'] ?? null, $defaults['x']);
    $y = spiralist_book_pages_clamp_manuscript_crop_value($crop['y'] ?? null, $defaults['y']);
    $width = spiralist_book_pages_clamp_manuscript_crop_value($crop['width'] ?? null, $defaults['width']);
    $height = spiralist_book_pages_clamp_manuscript_crop_value($crop['height'] ?? null, $defaults['height']);

    $width = max(0.05, min(1.0, $width));
    $height = max(0.05, min(1.0, $height));

    if ($x + $width > 1.0) {
        $x = max(0.0, 1.0 - $width);
    }

    if ($y + $height > 1.0) {
        $y = max(0.0, 1.0 - $height);
    }

    return [
        'x' => round($x, 6),
        'y' => round($y, 6),
        'width' => round($width, 6),
        'height' => round($height, 6),
    ];
}

function spiralist_book_pages_normalize_manuscript_crop_records($records): array
{
    if (!is_array($records)) {
        return [];
    }

    $normalized = [];

    foreach ($records as $slug => $record) {
        $slug = sanitize_title((string) $slug);
        if ($slug === '') {
            continue;
        }

        if (isset($record['x'], $record['y'], $record['width'], $record['height'])) {
            $rect = spiralist_book_pages_sanitize_manuscript_crop_rect($record);
            $record = ['rect' => $rect];
        }

        if (!is_array($record)) {
            continue;
        }

        $normalized[$slug] = [
            'rect' => spiralist_book_pages_sanitize_manuscript_crop_rect($record['rect'] ?? $record),
            'updated_at' => isset($record['updated_at']) ? sanitize_text_field((string) $record['updated_at']) : '',
            'updated_by' => isset($record['updated_by']) ? max(0, (int) $record['updated_by']) : 0,
            'auto_detected' => !empty($record['auto_detected']),
        ];
    }

    return $normalized;
}

function spiralist_book_pages_get_manuscript_crop_records(): array
{
    static $records = null;

    if (is_array($records)) {
        return $records;
    }

    $page_id = spiralist_book_pages_get_manuscript_page_post_id();
    $raw_records = $page_id > 0
        ? get_post_meta($page_id, spiralist_book_pages_get_manuscript_workstation_meta_key(), true)
        : get_option(spiralist_book_pages_get_manuscript_workstation_option_key(), []);

    $records = spiralist_book_pages_normalize_manuscript_crop_records($raw_records);

    return $records;
}

function spiralist_book_pages_store_manuscript_crop_records(array $records): bool
{
    $normalized = spiralist_book_pages_normalize_manuscript_crop_records($records);
    $page_id = spiralist_book_pages_get_manuscript_page_post_id();

    if ($page_id > 0) {
        $updated = update_post_meta($page_id, spiralist_book_pages_get_manuscript_workstation_meta_key(), $normalized);
        return $updated !== false;
    }

    return update_option(spiralist_book_pages_get_manuscript_workstation_option_key(), $normalized, false);
}

function spiralist_book_pages_get_manuscript_crop_for_folio(string $slug): array
{
    $normalized_slug = sanitize_title($slug);
    if ($normalized_slug === '') {
        return spiralist_book_pages_get_default_manuscript_crop_rect();
    }

    $records = spiralist_book_pages_get_manuscript_crop_records();

    if (!empty($records[$normalized_slug]['rect'])) {
        return spiralist_book_pages_sanitize_manuscript_crop_rect($records[$normalized_slug]['rect']);
    }

    return spiralist_book_pages_get_default_manuscript_crop_rect();
}

function spiralist_book_pages_get_manuscript_study_overlay_compare_key(string $value): string
{
    $value = wp_strip_all_tags($value);
    $value = preg_replace('/\s+/', ' ', $value);
    $value = is_string($value) ? trim(strtolower($value)) : strtolower(trim($value));

    return $value;
}

function spiralist_book_pages_get_manuscript_study_overlay_excerpt(string $text, int $words = 22): string
{
    $normalized = wp_strip_all_tags($text);
    $normalized = preg_replace('/\s+/', ' ', $normalized);
    $normalized = is_string($normalized) ? trim($normalized) : trim($text);

    if ($normalized === '') {
        return '';
    }

    return wp_trim_words($normalized, max(6, $words), '...');
}

function spiralist_book_pages_get_manuscript_study_overlay_terms(array $terms, array $blocked = [], int $limit = 4): array
{
    $blocked_keys = [];
    foreach ($blocked as $term) {
        $key = sanitize_title(trim(wp_strip_all_tags((string) $term)));
        if ($key !== '') {
            $blocked_keys[$key] = true;
        }
    }

    foreach (['manuscript', 'folio', 'page', 'book page', 'manuscript folio'] as $term) {
        $blocked_keys[sanitize_title($term)] = true;
    }

    $results = [];
    $seen = [];

    foreach ($terms as $term) {
        $normalized = trim(wp_strip_all_tags((string) $term));
        $normalized = preg_replace('/\s+/', ' ', $normalized);
        $normalized = is_string($normalized) ? trim($normalized) : '';
        if ($normalized === '' || preg_match('/^page\s+\d+$/i', $normalized)) {
            continue;
        }

        $key = sanitize_title($normalized);
        if ($key === '' || isset($blocked_keys[$key]) || isset($seen[$key])) {
            continue;
        }

        $seen[$key] = true;
        $results[] = $normalized;

        if (count($results) >= $limit) {
            break;
        }
    }

    return $results;
}

function spiralist_book_pages_get_manuscript_study_overlay_blueprint(string $section_slug): array
{
    switch ($section_slug) {
        case 'threshold':
            return [
                'style' => 'threshold-grid',
                'badges' => [
                    ['source' => 'label', 'x' => 0.04, 'y' => 0.05, 'align' => 'left', 'tone' => 'page'],
                    ['source' => 'eyebrow', 'x' => 0.5, 'y' => 0.05, 'align' => 'center', 'tone' => 'eyebrow'],
                    ['source' => 'section', 'x' => 0.96, 'y' => 0.05, 'align' => 'right', 'tone' => 'section'],
                ],