Collaboration - Source Excerpt 03
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
'approved_at' => $approved_at,
'public_version' => $public_version,
'author' => [
'id' => (int) $post->post_author,
'display_name' => $author instanceof WP_User ? (string) $author->display_name : 'Contributor',
'slug' => $author instanceof WP_User ? sanitize_title((string) $author->user_nicename) : '',
],
];
$record['studio_url'] = spiralist_book_pages_get_manuscript_studio_url($record['slug']);
$record['public_url'] = $record['has_public_copy'] ? spiralist_book_pages_get_manuscript_community_url($record['slug']) : '';
$record['profile_url'] = spiralist_book_pages_get_manuscript_profile_url($record['author']['slug'], $record['slug']);
$record['profile_share_url'] = add_query_arg('share', rawurlencode($share_token), $record['profile_url']);
return $record;
}
function spiralist_book_pages_get_collaboration_submission_query(array $args = []): array
{
$defaults = [
'post_type' => spiralist_book_pages_get_collaboration_post_type(),
'post_status' => 'any',
'posts_per_page' => -1,
'orderby' => 'date',
'order' => 'DESC',
];
return get_posts(array_merge($defaults, $args));
}
function spiralist_book_pages_get_collaboration_submission_records(array $args = []): array
{
$records = [];
foreach (spiralist_book_pages_get_collaboration_submission_query($args) as $submission) {
$record = spiralist_book_pages_get_collaboration_submission_record($submission);
if (!empty($record)) {
$records[] = $record;
}
}
return $records;
}
function spiralist_book_pages_get_collaboration_user_records(int $user_id): array
{
return spiralist_book_pages_get_collaboration_submission_records(
[
'author' => max(0, $user_id),
]
);
}
function spiralist_book_pages_get_public_collaboration_records(): array
{
$records = array_values(
array_filter(
spiralist_book_pages_get_collaboration_submission_records(),
static function (array $record): bool {
return !empty($record['has_public_copy']);
}
)
);
usort(
$records,
static function (array $left, array $right): int {
return strcmp((string) ($right['approved_at'] ?? ''), (string) ($left['approved_at'] ?? ''));
}
);
return $records;
}
function spiralist_book_pages_get_pending_collaboration_records(): array
{
return array_values(
array_filter(
spiralist_book_pages_get_collaboration_submission_records(),
static function (array $record): bool {
return (string) ($record['status'] ?? '') === 'pending_review';
}
)
);
}
function spiralist_book_pages_get_collaboration_submission_by_slug(string $slug, int $author_id = 0): array
{
$slug = sanitize_title($slug);
if ($slug === '') {
return [];
}
$args = [
'name' => $slug,
'posts_per_page' => 1,
];
if ($author_id > 0) {
$args['author'] = $author_id;
}
$posts = spiralist_book_pages_get_collaboration_submission_query($args);
return !empty($posts[0]) ? spiralist_book_pages_get_collaboration_submission_record($posts[0]) : [];
}
function spiralist_book_pages_can_edit_collaboration_submission($submission, int $user_id = 0): bool
{
$record = is_array($submission)
? $submission
: spiralist_book_pages_get_collaboration_submission_record($submission);
if (empty($record)) {
return false;
}
$user_id = $user_id > 0 ? $user_id : get_current_user_id();
if ($user_id <= 0) {
return false;
}
if (user_can($user_id, 'manage_options')) {
return true;
}
return spiralist_book_pages_user_can_collaborate($user_id)
&& (int) ($record['author']['id'] ?? 0) === $user_id;
}
function spiralist_book_pages_can_view_profile_submission(array $record, string $share_token = ''): bool
{
if (empty($record)) {
return false;
}
if (spiralist_book_pages_can_edit_collaboration_submission($record)) {
return true;
}
$share_token = sanitize_text_field($share_token);
if ($share_token === '') {
return false;
}
$stored_token = (string) ($record['share_token'] ?? '');
return $stored_token !== '' && hash_equals($stored_token, $share_token);
}
function spiralist_book_pages_get_submission_editor_seed(array $record = []): array
{
$copy = !empty($record['working_copy']) ? (array) $record['working_copy'] : (!empty($record['public_copy']) ? (array) $record['public_copy'] : []);
return [
'title' => (string) ($copy['title'] ?? ''),
'summary' => (string) ($copy['summary'] ?? ''),
'alt' => (string) ($copy['alt'] ?? ''),
'image_id' => max(0, (int) ($copy['image_id'] ?? 0)),
'image_url' => (string) ($copy['image_url'] ?? ''),
'thumbnail_url' => (string) ($copy['thumbnail_url'] ?? ''),
];
}
function spiralist_book_pages_handle_collaboration_upload(string $field)
{
if (empty($_FILES[$field]) || !is_array($_FILES[$field])) {
return 0;
}
$file = $_FILES[$field];
$error = (int) ($file['error'] ?? UPLOAD_ERR_NO_FILE);
if ($error === UPLOAD_ERR_NO_FILE) {
return 0;
}
if ($error !== UPLOAD_ERR_OK) {
return new WP_Error('spiralist_book_pages_upload_failed', 'The manuscript image upload could not be completed.');
}
if (!current_user_can('upload_files')) {
return new WP_Error('spiralist_book_pages_upload_forbidden', 'This account cannot upload manuscript images yet.');
}
require_once ABSPATH . 'wp-admin/includes/file.php';
require_once ABSPATH . 'wp-admin/includes/image.php';
require_once ABSPATH . 'wp-admin/includes/media.php';
$attachment_id = media_handle_upload($field, 0, [], ['test_form' => false]);
if (is_wp_error($attachment_id)) {
return new WP_Error(
'spiralist_book_pages_upload_failed',
'The manuscript image could not be saved. ' . $attachment_id->get_error_message()
);
}
$attachment_id = (int) $attachment_id;
$validated_attachment_id = spiralist_book_pages_validate_collaboration_image_attachment($attachment_id);
if (is_wp_error($validated_attachment_id)) {
wp_delete_attachment($attachment_id, true);
return $validated_attachment_id;
}
return (int) $validated_attachment_id;
}
function spiralist_book_pages_prepare_collaboration_submission_payload(int $existing_submission_id = 0)
{
$existing = $existing_submission_id > 0
? spiralist_book_pages_get_collaboration_submission_record($existing_submission_id)
: [];
$seed = spiralist_book_pages_get_submission_editor_seed($existing);
$upload_result = spiralist_book_pages_handle_collaboration_upload('manuscript_image');
if (is_wp_error($upload_result)) {
return $upload_result;
}
$image_id = max(0, (int) $upload_result);
if ($image_id <= 0) {
$image_id = max(
0,
(int) wp_unslash($_POST['current_image_id'] ?? $seed['image_id'])
);
}
$validated_image_id = spiralist_book_pages_validate_collaboration_image_attachment($image_id);
if (is_wp_error($validated_image_id)) {
return $validated_image_id;
}
$title = sanitize_text_field((string) wp_unslash($_POST['submission_title'] ?? $seed['title']));
$summary = sanitize_textarea_field((string) wp_unslash($_POST['submission_summary'] ?? $seed['summary']));
$alt = sanitize_text_field((string) wp_unslash($_POST['submission_alt'] ?? $seed['alt']));
if ($title === '') {
return new WP_Error('spiralist_book_pages_missing_title', 'Give this manuscript page a title before saving it.');
}
return [
'title' => $title,
'summary' => $summary,
'alt' => $alt,
'image_id' => (int) $validated_image_id,
];
}
function spiralist_book_pages_save_collaboration_submission(array $payload, int $user_id, int $submission_id = 0, string $operation = 'save')
{
$existing = $submission_id > 0
? spiralist_book_pages_get_collaboration_submission_record($submission_id)
: [];
if ($submission_id > 0 && empty($existing)) {
return new WP_Error('spiralist_book_pages_missing_submission', 'The selected manuscript page could not be found.');
}
if ($submission_id > 0 && !spiralist_book_pages_can_edit_collaboration_submission($existing, $user_id)) {