Skip to content
wiki.fftac.org

Admin Actions - Source Excerpt 01

Back to Admin Actions

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)));