Collaboration - Source Excerpt 05
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>