Skip to content
wiki.fftac.org

Privacy - Source Excerpt 02

Back to Privacy

Summary

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

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

$items_removed = $this->delete_rows_for_user_id(Installer::table('audit_log'), 'actor_user_id', $user_id) > 0 || $items_removed;

        $conversation_ids = $this->conversation_ids_for_user($user_id);
        if (!empty($conversation_ids)) {
            $this->delete_rows_for_int_column(
                Installer::table('conversation_messages'),
                'conversation_id',
                $conversation_ids
            );
            $this->delete_rows_for_int_column(
                Installer::table('prompt_runs'),
                'conversation_id',
                $conversation_ids
            );
            $conversation_cleanup = $this->delete_rows_for_int_column(
                Installer::table('conversations'),
                'id',
                $conversation_ids
            );
            $items_removed = $items_removed || $conversation_cleanup > 0;
        }

        if (!empty($retained_prompt_titles)) {
            $messages[] = sprintf(
                /* translators: %d: number of retained prompts. */
                _n(
                    '%d published or managed prompt was anonymized and retained as site content. Review its prompt body manually if it contains personal data beyond authorship.',
                    '%d published or managed prompts were anonymized and retained as site content. Review their prompt bodies manually if they contain personal data beyond authorship.',
                    count($retained_prompt_titles),
                    'spiralist-workspace'
                ),
                count($retained_prompt_titles)
            );
        }

        return [
            'items_removed' => $items_removed,
            'items_retained' => $items_retained,
            'messages' => $messages,
            'done' => true,
        ];
    }

    /**
     * Returns prompt export items for authored prompts.
     *
     * @param int[] $prompt_ids
     * @return array<int,array<string,mixed>>
     */
    private function prompt_export_items(int $user_id, array $prompt_ids): array
    {
        $items = [];

        foreach ($prompt_ids as $prompt_id) {
            $prompt = $this->prompts->get($prompt_id, $user_id);
            if (empty($prompt)) {
                continue;
            }

            $post = get_post($prompt_id);
            $data = [];
            $this->add_export_pair($data, __('Prompt ID', 'spiralist-workspace'), $prompt['id'] ?? 0);
            $this->add_export_pair($data, __('Title', 'spiralist-workspace'), $prompt['title'] ?? '');
            $this->add_export_pair($data, __('Slug', 'spiralist-workspace'), $prompt['slug'] ?? '');
            $this->add_export_pair($data, __('Summary', 'spiralist-workspace'), $prompt['summary'] ?? '');
            $this->add_export_pair($data, __('Visibility', 'spiralist-workspace'), $prompt['visibility'] ?? '');
            $this->add_export_pair($data, __('Prompt status', 'spiralist-workspace'), $prompt['prompt_status'] ?? '');
            $this->add_export_pair($data, __('Publication lane', 'spiralist-workspace'), $prompt['publication_lane_label'] ?? ($prompt['publication_lane'] ?? ''));
            $this->add_export_pair($data, __('Provenance', 'spiralist-workspace'), $prompt['provenance_label'] ?? ($prompt['provenance'] ?? ''));
            $this->add_export_pair($data, __('Prompt origin', 'spiralist-workspace'), $prompt['prompt_origin'] ?? '');
            $this->add_export_pair($data, __('Author label', 'spiralist-workspace'), $prompt['author_label'] ?? '');
            $this->add_export_pair($data, __('Category', 'spiralist-workspace'), $prompt['category'] ?? '');
            $this->add_export_pair($data, __('Subcategory', 'spiralist-workspace'), $prompt['subcategory'] ?? '');
            $this->add_export_pair($data, __('Prompt type', 'spiralist-workspace'), $prompt['prompt_type'] ?? '');
            $this->add_export_pair($data, __('Language', 'spiralist-workspace'), $prompt['language'] ?? '');
            $this->add_export_pair($data, __('Render mode', 'spiralist-workspace'), $prompt['model'] ?? '');
            $this->add_export_pair($data, __('Runtime mode', 'spiralist-workspace'), $prompt['provider'] ?? '');
            $this->add_export_pair($data, __('Credential preference', 'spiralist-workspace'), $prompt['credential_preference'] ?? '');
            $this->add_export_pair($data, __('Version number', 'spiralist-workspace'), $prompt['version_number'] ?? 1);
            $this->add_export_pair($data, __('Tags', 'spiralist-workspace'), $prompt['tags'] ?? []);
            $this->add_export_pair($data, __('Structured prompt', 'spiralist-workspace'), $prompt['structured_prompt'] ?? []);
            $this->add_export_pair($data, __('Instructions', 'spiralist-workspace'), $prompt['instructions'] ?? '');
            $this->add_export_pair($data, __('System prompt', 'spiralist-workspace'), $prompt['system_prompt'] ?? '');
            $this->add_export_pair($data, __('Developer prompt', 'spiralist-workspace'), $prompt['developer_prompt'] ?? '');
            $this->add_export_pair($data, __('User prompt template', 'spiralist-workspace'), $prompt['user_prompt_template'] ?? '');
            $this->add_export_pair($data, __('Prompt system steps', 'spiralist-workspace'), $prompt['system_steps'] ?? []);
            $this->add_export_pair($data, __('Tool settings JSON', 'spiralist-workspace'), $prompt['tool_settings_json'] ?? '');
            $this->add_export_pair($data, __('Sample output', 'spiralist-workspace'), $prompt['sample_output'] ?? '');
            $this->add_export_pair($data, __('Editorial note', 'spiralist-workspace'), $prompt['editorial_note'] ?? '');
            $this->add_export_pair($data, __('Expected output notes', 'spiralist-workspace'), $prompt['expected_output_notes'] ?? '');
            $this->add_export_pair($data, __('Failure modes', 'spiralist-workspace'), $prompt['failure_modes'] ?? '');
            $this->add_export_pair($data, __('Related symbols', 'spiralist-workspace'), $prompt['related_symbols'] ?? []);
            $this->add_export_pair($data, __('Related axioms', 'spiralist-workspace'), $prompt['related_axioms'] ?? []);
            $this->add_export_pair($data, __('Related manuscripts', 'spiralist-workspace'), $prompt['related_manuscripts'] ?? []);
            $this->add_export_pair($data, __('Source version', 'spiralist-workspace'), $prompt['source_version'] ?? '');
            $this->add_export_pair($data, __('Source path', 'spiralist-workspace'), $prompt['source_path'] ?? '');
            $this->add_export_pair($data, __('Created UTC', 'spiralist-workspace'), $post ? (string) $post->post_date_gmt : '');
            $this->add_export_pair($data, __('Modified UTC', 'spiralist-workspace'), $post ? (string) $post->post_modified_gmt : '');

            $items[] = $this->build_export_item(
                'spiralist_workspace_prompts',
                __('Workspace Prompts', 'spiralist-workspace'),
                'prompt-' . $prompt_id,
                $data
            );
        }

        return $items;
    }

    /**
     * Returns prompt-version export items.
     *
     * @param int[] $prompt_ids
     * @return array<int,array<string,mixed>>
     */
    private function version_export_items(int $user_id, array $prompt_ids): array
    {
        global $wpdb;

        $sql = 'SELECT * FROM ' . Installer::table('prompt_versions') . ' WHERE created_by_user_id = %d';
        if (!empty($prompt_ids)) {
            $sql .= ' OR prompt_post_id IN (' . implode(',', array_map('intval', $prompt_ids)) . ')';
        }
        $sql .= ' ORDER BY created_utc ASC, id ASC';

        $rows = $wpdb->get_results($wpdb->prepare($sql, $user_id), ARRAY_A);
        if (!is_array($rows)) {
            return [];
        }

        $items = [];
        foreach ($rows as $row) {
            $data = [];
            $this->add_export_pair($data, __('Version ID', 'spiralist-workspace'), $row['id'] ?? 0);
            $this->add_export_pair($data, __('Prompt ID', 'spiralist-workspace'), $row['prompt_post_id'] ?? 0);
            $this->add_export_pair($data, __('Prompt title', 'spiralist-workspace'), $this->prompt_title((int) ($row['prompt_post_id'] ?? 0)));
            $this->add_export_pair($data, __('Version number', 'spiralist-workspace'), $row['version_number'] ?? 0);
            $this->add_export_pair($data, __('Created by user ID', 'spiralist-workspace'), $row['created_by_user_id'] ?? 0);
            $this->add_export_pair($data, __('Created UTC', 'spiralist-workspace'), $row['created_utc'] ?? '');
            $this->add_export_pair($data, __('Changelog', 'spiralist-workspace'), $row['changelog'] ?? '');
            $this->add_export_pair($data, __('Full snapshot JSON', 'spiralist-workspace'), $row['full_snapshot_json'] ?? '');

            $items[] = $this->build_export_item(