Skip to content
wiki.fftac.org

Collaboration - Source Excerpt 05

Back to Collaboration

Summary

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

**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/includes/collaboration.php

? spiralist_book_pages_get_manuscript_studio_url((string) wp_unslash($_POST['submission_slug'] ?? ''))
                : spiralist_book_pages_get_manuscript_studio_url()
        );
        exit;
    }

    $saved = spiralist_book_pages_save_collaboration_submission(
        $payload,
        get_current_user_id(),
        $submission_id,
        $operation === 'submit' ? 'submit' : 'save'
    );

    if (is_wp_error($saved)) {
        spiralist_book_pages_set_collaboration_notice($saved->get_error_message(), 'error');
        wp_safe_redirect(spiralist_book_pages_get_manuscript_studio_url());
        exit;
    }

    spiralist_book_pages_set_collaboration_notice(
        $operation === 'submit'
            ? 'Your manuscript page was submitted for admin review.'
            : 'Your manuscript page draft was saved.'
    );

    wp_safe_redirect((string) ($saved['studio_url'] ?? spiralist_book_pages_get_manuscript_studio_url()));
    exit;
}
add_action('admin_post_spiralist_book_pages_frontend_submission_action', 'spiralist_book_pages_handle_frontend_submission_action');

function spiralist_book_pages_handle_collaboration_admin_action(): void
{
    if (!spiralist_book_pages_admin_can_manage()) {
        wp_die('You are not allowed to manage manuscript collaboration.');
    }

    check_admin_referer('spiralist_book_pages_collaboration_admin');

    $action = sanitize_key((string) wp_unslash($_POST['collaboration_admin_action'] ?? ''));
    $submission_id = max(0, (int) wp_unslash($_POST['submission_id'] ?? 0));
    $user_id = max(0, (int) wp_unslash($_POST['user_id'] ?? 0));

    switch ($action) {
        case 'approve_submission':
            $approved = spiralist_book_pages_approve_collaboration_submission($submission_id, get_current_user_id());
            if (is_wp_error($approved)) {
                spiralist_book_pages_admin_set_notice($approved->get_error_message(), 'error');
            } else {
                spiralist_book_pages_admin_set_notice('The submitted manuscript page is now live in the public directory.');
            }
            spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('community'));
            break;

        case 'request_changes':
            $changes = spiralist_book_pages_request_collaboration_changes(
                $submission_id,
                (string) wp_unslash($_POST['review_notes'] ?? '')
            );
            if (is_wp_error($changes)) {
                spiralist_book_pages_admin_set_notice($changes->get_error_message(), 'error');
            } else {
                spiralist_book_pages_admin_set_notice('Change requests were saved for this manuscript page.', 'warning');
            }
            spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('community'));
            break;

        case 'grant_collaboration':
            if ($user_id <= 0 || !spiralist_book_pages_set_collaborator_access($user_id, true)) {
                spiralist_book_pages_admin_set_notice('That user could not be granted collaboration access.', 'error');
            } else {
                spiralist_book_pages_admin_set_notice('Collaboration access was granted to the selected user.');
            }
            spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('collaborators'));
            break;

        case 'revoke_collaboration':
            if ($user_id <= 0 || !spiralist_book_pages_set_collaborator_access($user_id, false)) {
                spiralist_book_pages_admin_set_notice('That user could not be updated.', 'error');
            } else {
                spiralist_book_pages_admin_set_notice('Collaboration access was removed from the selected user.', 'warning');
            }
            spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('collaborators'));
            break;
    }

    spiralist_book_pages_admin_set_notice('That collaboration admin action is not supported.', 'error');
    spiralist_book_pages_admin_redirect(spiralist_book_pages_admin_page_slug('community'));
}
add_action('admin_post_spiralist_book_pages_collaboration_admin_action', 'spiralist_book_pages_handle_collaboration_admin_action');

function spiralist_book_pages_admin_render_collaboration_pages(): void
{
    if (!spiralist_book_pages_admin_can_manage()) {
        wp_die('You are not allowed to manage manuscript collaboration.');
    }

    $records = spiralist_book_pages_get_collaboration_submission_records();
    $pending = spiralist_book_pages_get_pending_collaboration_records();
    $published = array_values(
        array_filter(
            $records,
            static function (array $record): bool {
                return !empty($record['has_public_copy']);
            }
        )
    );

    spiralist_book_pages_admin_header(
        'Community Manuscript Pages',
        'Review collaborator submissions, approve public replacements, and keep the live directory tied to the latest approved version.',
        [
            ['label' => 'Public Directory', 'url' => spiralist_book_pages_get_manuscript_community_url(), 'class' => 'button button-primary'],
            ['label' => 'Collaborators', 'url' => spiralist_book_pages_admin_url(spiralist_book_pages_admin_page_slug('collaborators')), 'class' => 'button'],
        ]
    );
    ?>
        <section class="grid">
            <div class="panel"><div class="metric"><span class="kicker">Total Pages</span><strong><?php echo esc_html((string) count($records)); ?></strong><span>All collaborator manuscript submissions tracked by the plugin.</span></div></div>
            <div class="panel"><div class="metric"><span class="kicker">Pending Review</span><strong><?php echo esc_html((string) count($pending)); ?></strong><span>Pages currently waiting for an admin approval decision.</span></div></div>
            <div class="panel"><div class="metric"><span class="kicker">Public Directory</span><strong><?php echo esc_html((string) count($published)); ?></strong><span>Approved pages that are already live for public viewing.</span></div></div>
        </section>

        <?php if (empty($records)) : ?>
            <div class="empty"><p>No collaborator manuscript pages have been submitted yet.</p></div>
        <?php else : ?>
            <table class="widefat striped">
                <thead>
                    <tr>
                        <th>Page</th>
                        <th>Contributor</th>
                        <th>Status</th>
                        <th>Version</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($records as $record) : ?>
                        <tr>
                            <td>
                                <strong><?php echo esc_html((string) ($record['working_copy']['title'] ?? $record['slug'])); ?></strong><br />
                                <code><?php echo esc_html((string) ($record['slug'] ?? '')); ?></code><br />
                                <span><?php echo esc_html((string) ($record['working_copy']['summary'] ?? '')); ?></span>
                            </td>
                            <td>
                                <?php echo esc_html((string) ($record['author']['display_name'] ?? 'Contributor')); ?><br />
                                <code><?php echo esc_html((string) ($record['author']['slug'] ?? '')); ?></code>
                            </td>
                            <td>
                                <?php echo wp_kses_post(spiralist_book_pages_admin_badge((string) ($record['status_label'] ?? 'Draft'), (string) ($record['status_tone'] ?? 'neutral'))); ?><br />
                                <span><?php echo esc_html((string) ($record['status_description'] ?? '')); ?></span>
                            </td>
                            <td>
                                <strong><?php echo esc_html((string) max(0, (int) ($record['public_version'] ?? 0))); ?></strong><br />
                                <span><?php echo esc_html((string) ($record['approved_at'] ?: $record['submitted_at'])); ?></span>
                            </td>
                            <td>
                                <div class="stack" style="gap:10px;">
                                    <div class="tight-actions">
                                        <?php if (!empty($record['public_url'])) : ?><a class="button button-small" href="<?php echo esc_url((string) $record['public_url']); ?>">Public</a><?php endif; ?>
                                        <a class="button button-small" href="<?php echo esc_url((string) ($record['profile_share_url'] ?? '')); ?>">Profile Preview</a>
                                    </div>