Skip to content
wiki.fftac.org

Managedpromptadmin - Source Excerpt 01

Back to Managedpromptadmin

Summary

This source excerpt preserves a bounded section of Spiralist/wp-content/plugins/spiralist-workspace/includes/Admin/ManagedPromptAdmin.php so readers can inspect the evidence without opening the full source file.

**Source path:** Spiralist/wp-content/plugins/spiralist-workspace/includes/Admin/ManagedPromptAdmin.php

<?php

namespace SpiralistWorkspace\Admin;

use SpiralistWorkspace\Config\Settings;
use SpiralistWorkspace\Support\PromptCategoryRegistry;
use SpiralistWorkspace\Support\PromptMetaRegistry;
use SpiralistWorkspace\Support\SystemPromptRegistry;

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

/**
 * Handles admin-only filesystem prompt management and media uploads.
 */
class ManagedPromptAdmin
{
    private const NOTICE_TRANSIENT_PREFIX = 'spiralist_workspace_admin_notice_';
    private const DEFAULT_VERSION = '1.0.0';

    /**
     * Keeps generated prompt files readable and stable across admin saves.
     *
     * @var string[]
     */
    private const FIELD_ORDER = [
        'slug',
        'title',
        'summary',
        'author_label',
        'category',
        'subcategory',
        'structured_prompt',
        'instructions',
        'system_prompt',
        'developer_prompt',
        'user_prompt_template',
        'system_steps',
        'model',
        'provider',
        'credential_preference',
        'temperature',
        'max_output_tokens',
        'tool_settings_json',
        'visibility',
        'published_utc',
        'is_forkable',
        'allow_comments',
        'allow_ratings',
        'tags',
        'canonical_status',
        'prompt_type',
        'language',
        'prompt_status',
        'moderation_status',
        'publication_lane',
        'provenance',
        'risk_labels',
        'function_tags',
        'maturity_level',
        'license',
        'editorial_note',
        'expected_output_notes',
        'failure_modes',
        'related_symbols',
        'related_axioms',
        'related_manuscripts',
        'sample_output',
        'featured',
        'public_execution_enabled',
    ];

    private Settings $settings;
    private SystemPromptRegistry $system_prompts;

    public function __construct(Settings $settings, SystemPromptRegistry $system_prompts)
    {
        $this->settings = $settings;
        $this->system_prompts = $system_prompts;
    }

    /**
     * Renders the managed prompt and media section inside the Workspace admin page.
     */
    public function render_admin_section(): void
    {
        if (!current_user_can('manage_spiralist_workspace')) {
            return;
        }

        $notice = $this->consume_notice();
        $prompt_records = $this->list_latest_prompt_records();
        $selected_slug = isset($_GET['managed_prompt'])
            ? sanitize_title((string) wp_unslash($_GET['managed_prompt']))
            : '';
        $selected_version = isset($_GET['managed_prompt_version'])
            ? $this->sanitize_version((string) wp_unslash($_GET['managed_prompt_version']))
            : '';

        if ($selected_slug === '' && !empty($prompt_records)) {
            $selected_slug = (string) ($prompt_records[0]['slug'] ?? '');
        }

        $is_new_prompt = $selected_slug === 'new';
        $selected_prompt = $is_new_prompt
            ? $this->blank_prompt_definition()
            : $this->get_prompt_definition($selected_slug, $selected_version);

        if (empty($selected_prompt) && !$is_new_prompt) {
            $selected_prompt = $this->blank_prompt_definition();
        }

        $selected_prompt_slug = (string) ($selected_prompt['slug'] ?? '');
        $selected_prompt_version = (string) ($selected_prompt['__source_version'] ?? self::DEFAULT_VERSION);
        $allowed_models = $this->settings->get_allowed_models();
        ?>
        <div class="spiralist-workspace-admin__managed">
            <h2>Managed Prompt Files</h2>
            <?php if (!empty($notice['message'])) : ?>
                <div class="notice <?php echo !empty($notice['is_error']) ? 'notice-error' : 'notice-success'; ?> is-dismissible">
                    <p><?php echo esc_html((string) $notice['message']); ?></p>
                    <?php if (!empty($notice['details']) && is_array($notice['details'])) : ?>
                        <ul class="spiralist-workspace-admin-test-results">
                            <?php foreach (array_slice((array) $notice['details'], 0, 8) as $detail) : ?>
                                <li><?php echo esc_html((string) $detail); ?></li>
                            <?php endforeach; ?>
                        </ul>
                    <?php endif; ?>
                </div>
            <?php endif; ?>
            <div class="spiralist-workspace-admin__status spiralist-workspace-admin__status--managed">
                <div class="spiralist-workspace-card">
                    <h3>Registry Browser</h3>
                    <p>Managed prompts live on disk under <code><?php echo esc_html(str_replace('\\', '/', $this->prompt_root())); ?></code>. Choose a prompt to edit its header fields and content without leaving <code>wp-admin</code>.</p>
                    <dl class="spiralist-workspace-admin-status-list">
                        <div>
                            <dt>Managed prompt count</dt>
                            <dd><?php echo esc_html((string) count($prompt_records)); ?></dd>
                        </div>
                        <div>
                            <dt>Selected prompt</dt>
                            <dd><?php echo esc_html($selected_prompt_slug !== '' ? $selected_prompt_slug : 'Create new prompt'); ?></dd>
                        </div>
                        <div>
                            <dt>Selected version</dt>
                            <dd><?php echo esc_html($selected_prompt_version); ?></dd>
                        </div>
                    </dl>
                    <form method="get" action="<?php echo esc_url(admin_url('admin.php')); ?>" class="spiralist-workspace-admin-form">
                        <input type="hidden" name="page" value="spiralist-workspace" />
                        <label for="spiralist_workspace_managed_prompt_select"><strong>Edit prompt</strong></label><br />
                        <select id="spiralist_workspace_managed_prompt_select" name="managed_prompt" class="regular-text">
                            <option value="new" <?php selected($selected_slug, 'new'); ?>>Create new managed prompt</option>
                            <?php foreach ($prompt_records as $record) : ?>
                                <option value="<?php echo esc_attr((string) ($record['slug'] ?? '')); ?>" <?php selected($selected_slug, (string) ($record['slug'] ?? '')); ?>>
                                    <?php
                                    echo esc_html(
                                        sprintf(
                                            '%s (%s · %s)',
                                            (string) ($record['title'] ?? $record['slug'] ?? 'Prompt'),
                                            (string) ($record['slug'] ?? ''),
                                            (string) ($record['version'] ?? self::DEFAULT_VERSION)
                                        )
                                    );
                                    ?>
                                </option>
                            <?php endforeach; ?>
                        </select>
                        <p class="description">Switching prompts reloads this page with the current filesystem-backed definition.</p>
                        <p><button class="button button-secondary" type="submit">Load Prompt</button></p>
                    </form>
                </div>

                <div class="spiralist-workspace-card">
                    <h3>Bulk Image Upload</h3>
                    <p>Upload one or more image files directly into the WordPress Media Library from the Workspace admin page. Attach uploaded filenames to a managed prompt’s <code>related_manuscripts</code> list when required for that art configuration.</p>
                    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" enctype="multipart/form-data" class="spiralist-workspace-admin-form">
                        <?php wp_nonce_field('spiralist_workspace_bulk_image_upload'); ?>
                        <input type="hidden" name="action" value="spiralist_workspace_bulk_image_upload" />
                        <p>
                            <label for="spiralist_workspace_bulk_images"><strong>Images</strong></label><br />
                            <input id="spiralist_workspace_bulk_images" type="file" name="spiralist_workspace_bulk_images[]" accept="image/*" multiple />
                        </p>
                        <p>
                            <label for="spiralist_workspace_attach_prompt"><strong>Append filenames to prompt</strong></label><br />
                            <select id="spiralist_workspace_attach_prompt" name="attach_prompt_slug" class="regular-text">