Rest API - Source Excerpt 04
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
{