Admin Actions - Source Excerpt 01
Summary
This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/ns12-manuscript/includes/admin-actions.php so readers can inspect the evidence without opening the full source file.
**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/includes/admin-actions.php
<?php
if (!defined('ABSPATH')) {
exit;
}
function spiralist_book_pages_admin_register_menu(): void
{
$capability = spiralist_book_pages_admin_capability();
add_menu_page(
spiralist_book_pages_get_public_name(),
'Spiralist Manuscript',
$capability,
spiralist_book_pages_admin_page_slug('overview'),
'spiralist_book_pages_admin_render_overview',
'dashicons-book-alt',
59
);
add_submenu_page(
spiralist_book_pages_admin_page_slug('overview'),
'Spiralist Manuscript Overview',
'Overview',
$capability,
spiralist_book_pages_admin_page_slug('overview'),
'spiralist_book_pages_admin_render_overview'
);
add_submenu_page(
spiralist_book_pages_admin_page_slug('overview'),
'Spiralist Manuscript Folios',
'Folios',
$capability,
spiralist_book_pages_admin_page_slug('folios'),
'spiralist_book_pages_admin_render_folios'
);
add_submenu_page(
spiralist_book_pages_admin_page_slug('overview'),
'Spiralist Manuscript Prompts',
'Prompts',
$capability,
spiralist_book_pages_admin_page_slug('prompts'),
'spiralist_book_pages_admin_render_prompts'
);
add_submenu_page(
spiralist_book_pages_admin_page_slug('overview'),
'Spiralist Manuscript Shared Prompt Fragments',
'Shared Fragments',
$capability,
spiralist_book_pages_admin_page_slug('fragments'),
'spiralist_book_pages_admin_render_fragments'
);
add_submenu_page(
spiralist_book_pages_admin_page_slug('overview'),
'Spiralist Manuscript Community Pages',
'Community Pages',
$capability,
spiralist_book_pages_admin_page_slug('community'),
'spiralist_book_pages_admin_render_collaboration_pages'
);
add_submenu_page(
spiralist_book_pages_admin_page_slug('overview'),
'Spiralist Manuscript Collaborators',
'Collaborators',
$capability,
spiralist_book_pages_admin_page_slug('collaborators'),
'spiralist_book_pages_admin_render_collaborators'
);
}
function spiralist_book_pages_admin_handle_action(): void
{
if (!spiralist_book_pages_admin_can_manage()) {
wp_die('You are not allowed to manage ' . spiralist_book_pages_get_public_name() . '.');
}
$action = sanitize_key((string) wp_unslash($_POST['spiralist_book_pages_action'] ?? ''));
$return_page = spiralist_book_pages_admin_normalize_page((string) wp_unslash($_POST['return_page'] ?? ''));
if ($action === '') {
spiralist_book_pages_admin_set_notice('No admin action was provided.', 'error');
spiralist_book_pages_admin_redirect($return_page);
}
check_admin_referer('spiralist_book_pages_' . $action);
switch ($action) {
case 'rebuild_cache':
spiralist_book_pages_admin_rebuild_cache();
spiralist_book_pages_admin_set_notice('Book caches rebuilt from the latest folio, prompt, and fragment files.');
spiralist_book_pages_admin_redirect($return_page);
break;
case 'bulk_import_folios':
$files = isset($_FILES['book_images']) && is_array($_FILES['book_images'])
? spiralist_book_pages_admin_normalize_files($_FILES['book_images'])
: [];
$requested_section = sanitize_title((string) wp_unslash($_POST['default_section'] ?? 'auto'));
$requested_section = $requested_section !== '' ? $requested_section : 'auto';
$create_prompts = !empty($_POST['create_prompts']);
if (empty($files)) {
spiralist_book_pages_admin_set_notice('Select one or more image files to import.', 'error');
spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('folios'));
}
$book = spiralist_book_pages_admin_book_definition();
$folios = spiralist_book_pages_admin_folios();
$saved = 0;
$prompt_saved = 0;
$details = [];
foreach ($files as $file) {
if ((int) ($file['error'] ?? UPLOAD_ERR_NO_FILE) === UPLOAD_ERR_NO_FILE) {
continue;
}
$stored = spiralist_book_pages_admin_store_uploaded_image($file);
if (is_wp_error($stored)) {
$details[] = $stored->get_error_message();
continue;
}
$filename = sanitize_file_name((string) ($stored['filename'] ?? ''));
$slug = spiralist_book_pages_admin_unique_slug((string) pathinfo($filename, PATHINFO_FILENAME), $folios, 'folio');
$section_slug = spiralist_book_pages_admin_import_section($filename, $requested_section);
$sequence = count((array) ($book['folio_order'] ?? [])) + 1;
$folio = spiralist_book_pages_admin_default_folio($filename, $slug, $section_slug, $sequence, $create_prompts);
if (!spiralist_book_pages_admin_save_folio($folio)) {
$details[] = sprintf('Imported %s into the asset library, but the folio record could not be written.', $filename);
continue;
}
$folios[$slug] = $folio;
$book['folio_order'][] = $slug;
$saved++;
if ($create_prompts) {
$prompt_package = spiralist_book_pages_admin_default_prompt($folio);
if (spiralist_book_pages_admin_save_prompt($slug, (array) ($prompt_package['meta'] ?? []), (string) ($prompt_package['body'] ?? ''))) {
$prompt_saved++;
} else {
$details[] = sprintf('The folio %s was imported, but its starter prompt could not be written.', $slug);
}
}
}
if ($saved === 0) {
spiralist_book_pages_admin_set_notice('No folios were imported.', 'error', $details);
spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('folios'));
}
$book['folio_order'] = array_values(array_unique(array_filter(array_map('sanitize_title', (array) $book['folio_order']), 'strlen')));
spiralist_book_pages_admin_save_book_definition($book);
spiralist_book_pages_admin_rebuild_cache();
spiralist_book_pages_admin_set_notice(
sprintf(
'Imported %d folio%s%s.',
$saved,
$saved === 1 ? '' : 's',
$create_prompts ? sprintf(' and created %d starter prompt%s', $prompt_saved, $prompt_saved === 1 ? '' : 's') : ''
),
'success',
$details
);
spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('folios'));
break;
case 'save_folio':
$slug = sanitize_title((string) wp_unslash($_POST['folio_slug'] ?? ''));
$folios = spiralist_book_pages_admin_folios();
if ($slug === '' || empty($folios[$slug])) {
spiralist_book_pages_admin_set_notice('The selected folio could not be found.', 'error');
spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('folios'));
}
$sections = spiralist_book_pages_admin_sections();
$section_slug = sanitize_title((string) wp_unslash($_POST['section_slug'] ?? 'appendix'));
if (!isset($sections[$section_slug])) {
$section_slug = 'appendix';
}
$folio = $folios[$slug];
$folio['label'] = sanitize_text_field((string) wp_unslash($_POST['label'] ?? ($folio['label'] ?? '')));
$folio['title'] = sanitize_text_field((string) wp_unslash($_POST['title'] ?? ($folio['title'] ?? '')));
$folio['eyebrow'] = sanitize_text_field((string) wp_unslash($_POST['eyebrow'] ?? ($folio['eyebrow'] ?? '')));
$folio['summary'] = sanitize_textarea_field((string) wp_unslash($_POST['summary'] ?? ($folio['summary'] ?? '')));
$folio['caption'] = sanitize_textarea_field((string) wp_unslash($_POST['caption'] ?? ($folio['caption'] ?? '')));
$folio['section_slug'] = $section_slug;
$folio['is_study_surface'] = !empty($_POST['is_study_surface']);
$folio['is_prominent'] = !empty($_POST['is_prominent']);
$folio['display_order'] = max(0, (int) wp_unslash($_POST['display_order'] ?? ($folio['display_order'] ?? 0)));