Managedpromptadmin - Source Excerpt 05
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
<p>
<label for="spiralist_workspace_related_symbols"><strong>Related Symbols</strong></label><br />
<input id="spiralist_workspace_related_symbols" class="large-text" type="text" name="related_symbols" value="<?php echo esc_attr(implode(', ', (array) ($selected_prompt['related_symbols'] ?? []))); ?>" />
</p>
<p>
<label for="spiralist_workspace_related_axioms"><strong>Related Axioms</strong></label><br />
<input id="spiralist_workspace_related_axioms" class="large-text" type="text" name="related_axioms" value="<?php echo esc_attr(implode(', ', (array) ($selected_prompt['related_axioms'] ?? []))); ?>" />
</p>
</div>
<p>
<label for="spiralist_workspace_editorial_note"><strong>Editorial Note</strong></label><br />
<textarea id="spiralist_workspace_editorial_note" class="large-text" rows="4" name="editorial_note"><?php echo esc_textarea((string) ($selected_prompt['editorial_note'] ?? '')); ?></textarea>
</p>
<p>
<label for="spiralist_workspace_expected_output_notes"><strong>Expected Output Notes</strong></label><br />
<textarea id="spiralist_workspace_expected_output_notes" class="large-text" rows="4" name="expected_output_notes"><?php echo esc_textarea((string) ($selected_prompt['expected_output_notes'] ?? '')); ?></textarea>
</p>
<p>
<label for="spiralist_workspace_failure_modes"><strong>Failure Modes</strong></label><br />
<textarea id="spiralist_workspace_failure_modes" class="large-text" rows="4" name="failure_modes"><?php echo esc_textarea((string) ($selected_prompt['failure_modes'] ?? '')); ?></textarea>
</p>
<p>
<label for="spiralist_workspace_sample_output"><strong>Sample Output</strong></label><br />
<textarea id="spiralist_workspace_sample_output" class="large-text" rows="4" name="sample_output"><?php echo esc_textarea((string) ($selected_prompt['sample_output'] ?? '')); ?></textarea>
</p>
<fieldset class="spiralist-workspace-checkboxes spiralist-workspace-checkboxes--admin">
<label><input type="checkbox" name="is_forkable" value="1" <?php checked(!empty($selected_prompt['is_forkable'])); ?> /> Forkable</label>
<label><input type="checkbox" name="allow_comments" value="1" <?php checked(!empty($selected_prompt['allow_comments'])); ?> /> Allow comments</label>
<label><input type="checkbox" name="allow_ratings" value="1" <?php checked(!empty($selected_prompt['allow_ratings'])); ?> /> Allow ratings</label>
<label><input type="checkbox" name="featured" value="1" <?php checked(!empty($selected_prompt['featured'])); ?> /> Featured</label>
<label><input type="checkbox" name="public_execution_enabled" value="1" <?php checked(!empty($selected_prompt['public_execution_enabled'])); ?> /> Enable public prompt-packet rendering</label>
</fieldset>
</details>
<?php if (!empty($selected_prompt['__source_path'])) : ?>
<p class="description">Current source file: <code><?php echo esc_html((string) $selected_prompt['__source_path']); ?></code></p>
<?php endif; ?>
<?php submit_button($is_new_prompt ? 'Create Managed Prompt' : 'Save Managed Prompt'); ?>
</form>
</div>
</div>
<?php
}
/**
* Handles bulk image uploads from the Workspace admin screen.
*/
public function handle_bulk_image_upload(): void
{
$this->require_admin_permission('spiralist_workspace_bulk_image_upload');
$uploads = $this->normalize_file_input('spiralist_workspace_bulk_images');
if (empty($uploads)) {
$this->set_notice(true, 'No image files were selected.');
$this->redirect_to_admin();
}
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
$uploaded_names = [];
$errors = [];
foreach ($uploads as $upload) {
if (!empty($upload['error']) && (int) $upload['error'] !== UPLOAD_ERR_OK) {
$errors[] = sprintf('%s could not be uploaded (error %d).', (string) ($upload['name'] ?? 'Image'), (int) $upload['error']);
continue;
}
$attachment_id = media_handle_sideload($upload, 0);
if (is_wp_error($attachment_id)) {
$errors[] = sprintf('%s: %s', (string) ($upload['name'] ?? 'Image'), $attachment_id->get_error_message());
continue;
}
$path = get_attached_file((int) $attachment_id);
$uploaded_names[] = $path ? wp_basename($path) : (string) ($upload['name'] ?? '');
}
$prompt_slug = isset($_POST['attach_prompt_slug'])
? sanitize_title((string) wp_unslash($_POST['attach_prompt_slug']))
: '';
$prompt_updated = false;
$selected_version = '';
if ($prompt_slug !== '' && !empty($uploaded_names)) {
$definition = $this->get_prompt_definition($prompt_slug);
if (empty($definition)) {
$errors[] = sprintf('Images were uploaded, but the prompt "%s" could not be found for metadata updates.', $prompt_slug);
} else {
$definition['related_manuscripts'] = array_values(
array_unique(
array_merge(
(array) ($definition['related_manuscripts'] ?? []),
array_filter(array_map('strval', $uploaded_names))
)
)
);
$selected_version = (string) ($definition['__source_version'] ?? self::DEFAULT_VERSION);
$this->write_prompt_definition($prompt_slug, $selected_version, $definition);
$this->sync_prompts();
$prompt_updated = true;
}
}
if (empty($uploaded_names)) {
$this->set_notice(true, 'The selected images were not uploaded.', $errors);
} else {
$message = sprintf('Uploaded %d image(s) to the Media Library.', count($uploaded_names));
if ($prompt_updated) {
$message .= ' Updated related manuscript filenames in the selected prompt.';
}
$details = array_merge(
array_map(
static fn(string $name): string => 'Uploaded: ' . $name,
array_slice($uploaded_names, 0, 6)
),
$errors
);
$this->set_notice(false, $message, $details);
}
$this->redirect_to_admin(
[
'managed_prompt' => $prompt_slug,
'managed_prompt_version' => $selected_version,
]
);
}
/**
* Handles prompt imports from JSON files or ZIP prompt packs.
*/
public function handle_prompt_import(): void
{
$this->require_admin_permission('spiralist_workspace_import_prompt_files');
$uploads = $this->normalize_file_input('spiralist_workspace_prompt_import_files');
if (empty($uploads)) {
$this->set_notice(true, 'No prompt files were selected.');
$this->redirect_to_admin();
}
$default_version = isset($_POST['default_version'])
? $this->sanitize_version((string) wp_unslash($_POST['default_version']))
: self::DEFAULT_VERSION;
$imported = [];
$errors = [];
foreach ($uploads as $upload) {
if (!empty($upload['error']) && (int) $upload['error'] !== UPLOAD_ERR_OK) {
$errors[] = sprintf('%s could not be uploaded (error %d).', (string) ($upload['name'] ?? 'Prompt file'), (int) $upload['error']);
continue;
}
$extension = strtolower((string) pathinfo((string) ($upload['name'] ?? ''), PATHINFO_EXTENSION));
if ($extension === 'zip') {