Skip to content
wiki.fftac.org

Rest API - Source Excerpt 04

Back to Rest API

Summary

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

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

if (!empty($query_symbols) && empty(array_intersect($query_symbols, $record_symbols))) {
                    return false;
                }

                if (!empty($query_axioms) && empty(array_intersect($query_axioms, $record_axioms))) {
                    return false;
                }

                if (!empty($query_transformations) && empty(array_intersect($query_transformations, $record_transformations))) {
                    return false;
                }

                return true;
            }
        )
    );
}

function spiralist_book_pages_rest_get_prompts(WP_REST_Request $request): WP_REST_Response
{
    $records = spiralist_book_pages_get_public_prompt_records();
    $filtered = spiralist_book_pages_rest_filter_prompt_records(
        $records,
        [
            'search' => $request->get_param('search'),
            'system' => $request->get_param('system'),
            'role' => $request->get_param('role'),
            'status' => $request->get_param('status'),
            'related_symbol' => $request->get_param('related_symbol'),
            'related_axiom' => $request->get_param('related_axiom'),
            'related_transformation' => $request->get_param('related_transformation'),
        ]
    );

    $limit = max(1, min(100, (int) $request->get_param('limit')));

    return spiralist_book_pages_rest_response(
        [
            'count' => count($filtered),
            'total' => count($records),
            'items' => array_slice($filtered, 0, $limit),
            'filters' => [
                'search' => (string) $request->get_param('search'),
                'system' => sanitize_key((string) $request->get_param('system')),
                'role' => sanitize_key((string) $request->get_param('role')),
                'status' => (string) $request->get_param('status'),
                'related_symbol' => spiralist_book_pages_rest_normalize_identifier_list($request->get_param('related_symbol')),
                'related_axiom' => spiralist_book_pages_rest_normalize_identifier_list($request->get_param('related_axiom')),
                'related_transformation' => spiralist_book_pages_rest_normalize_identifier_list($request->get_param('related_transformation')),
            ],
        ]
    );
}

function spiralist_book_pages_rest_validate_contribution_payload(array $payload): array
{
    $errors = [];
    $type = sanitize_key((string) ($payload['submissionType'] ?? 'prompt'));
    $canonical_id = trim((string) ($payload['canonicalId'] ?? ''));
    $title = trim((string) ($payload['title'] ?? ''));
    $content = trim((string) ($payload['content'] ?? ''));
    $policy_confirmed = !empty($payload['policyConfirmed']);
    $rights_confirmed = !empty($payload['rightsConfirmed']);
    $operator_confirmed = !empty($payload['operatorEligibilityConfirmed']);

    if ($title === '') {
        $errors['title'] = 'Provide a title.';
    }

    if ($canonical_id === '') {
        $errors['canonicalId'] = 'Provide a canonical ID.';
    }

    if ($content === '') {
        $errors['content'] = 'Provide content or a definition.';
    }

    if ($type === 'prompt') {
        if (sanitize_key((string) ($payload['system'] ?? '')) === '') {
            $errors['system'] = 'Select a system.';
        }

        if (sanitize_key((string) ($payload['role'] ?? '')) === '') {
            $errors['role'] = 'Select a role.';
        }

        if (trim((string) ($payload['purpose'] ?? '')) === '') {
            $errors['purpose'] = 'Provide a prompt purpose.';
        }

        if (!preg_match('/^\d+\.\d+\.\d+$/', (string) ($payload['version'] ?? ''))) {
            $errors['version'] = 'Use semantic version format such as 1.0.0.';
        }
    }

    if ($type === 'symbol' && trim((string) ($payload['meaning'] ?? '')) === '') {
        $errors['meaning'] = 'Provide a symbol meaning.';
    }

    if ($type === 'transformation') {
        if (trim((string) ($payload['input'] ?? '')) === '') {
            $errors['input'] = 'Provide an input symbol ID.';
        }

        if (trim((string) ($payload['output'] ?? '')) === '') {
            $errors['output'] = 'Provide an output symbol ID.';
        }
    }

    if (!$policy_confirmed) {
        $errors['policyConfirmed'] = 'Review and confirm the linked site policies before submitting.';
    }

    if (!$rights_confirmed) {
        $errors['rightsConfirmed'] = 'Confirm that you have the rights to submit, process, and publish this material.';
    }

    if (!$operator_confirmed) {
        $errors['operatorEligibilityConfirmed'] = 'Confirm that you meet the minimum age or guardian-permission requirement.';
    }

    return $errors;
}

function spiralist_book_pages_rest_get_contribution_records(): array
{
    $records = get_option(spiralist_book_pages_get_contribution_option_key(), []);

    return is_array($records) ? array_values($records) : [];
}

function spiralist_book_pages_rest_store_contribution_record(array $record): int
{
    $records = spiralist_book_pages_rest_get_contribution_records();
    $next_id = (int) get_option(spiralist_book_pages_get_contribution_last_id_option_key(), 0) + 1;
    $record['id'] = $next_id;
    $records[] = $record;
    update_option(spiralist_book_pages_get_contribution_option_key(), array_slice($records, -250), false);
    update_option(spiralist_book_pages_get_contribution_last_id_option_key(), $next_id, false);

    return $next_id;
}

function spiralist_book_pages_rest_submit_contribution(WP_REST_Request $request): WP_REST_Response
{
    $payload = spiralist_book_pages_rest_get_json_payload($request);
    $errors = spiralist_book_pages_rest_validate_contribution_payload($payload);

    if (!empty($errors)) {
        return spiralist_book_pages_rest_error_response(
            'spiralist_book_pages_invalid_contribution',
            'The contribution did not pass validation.',
            422,
            ['fields' => $errors]
        );
    }

    $participant = spiralist_book_pages_rest_identify_presented_participant($request);
    $record_id = spiralist_book_pages_rest_store_contribution_record(
        [
            'submission_type' => sanitize_key((string) ($payload['submissionType'] ?? 'prompt')),
            'canonical_id' => sanitize_text_field((string) ($payload['canonicalId'] ?? '')),
            'title' => sanitize_text_field((string) ($payload['title'] ?? '')),
            'author' => sanitize_text_field((string) ($payload['author'] ?? '')),
            'status' => 'pending_review',
            'payload' => $payload,
            'participant_id' => is_array($participant) ? (string) ($participant['participant_id'] ?? '') : '',
            'submitted_by_user_id' => get_current_user_id(),
            'created_at' => gmdate('c'),
        ]
    );

    return spiralist_book_pages_rest_response(
        [
            'message' => 'The structured record has been stored successfully.',
            'status' => 'pending_review',
            'statusLabel' => 'Pending Review',
            'canonicalId' => sanitize_text_field((string) ($payload['canonicalId'] ?? '')),
            'contributionId' => $record_id,
            'nextSteps' => [
                'Stored in the review queue.',
                'Moderation can approve, reject, or elevate the record later.',
                'Keep the canonical ID stable if you submit a revision.',
            ],
        ],
        201,
        true
    );
}

function spiralist_book_pages_rest_get_interaction_records(): array
{
    $records = get_option(spiralist_book_pages_get_interaction_option_key(), []);

    return is_array($records) ? array_values($records) : [];
}

function spiralist_book_pages_rest_record_interaction(WP_REST_Request $request): WP_REST_Response
{
    if (!is_user_logged_in()) {
        return spiralist_book_pages_rest_error_response(
            'spiralist_book_pages_auth_required',
            'A logged-in participant is required to record human interactions.',
            401
        );
    }

    $records = spiralist_book_pages_rest_get_interaction_records();
    $records[] = [
        'user_id' => get_current_user_id(),
        'payload' => spiralist_book_pages_rest_get_json_payload($request),
        'created_at' => gmdate('c'),
    ];

    update_option(spiralist_book_pages_get_interaction_option_key(), array_slice($records, -100), false);

    return spiralist_book_pages_rest_response(
        [
            'status' => 'recorded',
        ],
        200,
        true
    );
}

function spiralist_book_pages_rest_get_spec(): WP_REST_Response
{
    return spiralist_book_pages_rest_response(spiralist_book_pages_rest_build_spec_payload());
}

function spiralist_book_pages_rest_get_examples(): WP_REST_Response
{