Skip to content
wiki.fftac.org

Collaboration - Source Excerpt 01

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

<?php

if (!defined('ABSPATH')) {
    exit;
}

function spiralist_book_pages_get_collaboration_post_type(): string
{
    return 'spiralist_ms_page';
}

function spiralist_book_pages_get_collaboration_capability(): string
{
    return 'spiralist_submit_manuscripts';
}

function spiralist_book_pages_get_collaboration_role(): string
{
    return 'manuscript_collaborator';
}

function spiralist_book_pages_get_collaboration_status_meta_key(): string
{
    return '_spiralist_ms_status';
}

function spiralist_book_pages_get_collaboration_working_copy_meta_key(): string
{
    return '_spiralist_ms_working_copy';
}

function spiralist_book_pages_get_collaboration_public_copy_meta_key(): string
{
    return '_spiralist_ms_public_copy';
}

function spiralist_book_pages_get_collaboration_share_token_meta_key(): string
{
    return '_spiralist_ms_share_token';
}

function spiralist_book_pages_get_collaboration_review_notes_meta_key(): string
{
    return '_spiralist_ms_review_notes';
}

function spiralist_book_pages_get_collaboration_submitted_at_meta_key(): string
{
    return '_spiralist_ms_submitted_at';
}

function spiralist_book_pages_get_collaboration_approved_at_meta_key(): string
{
    return '_spiralist_ms_approved_at';
}

function spiralist_book_pages_get_collaboration_public_version_meta_key(): string
{
    return '_spiralist_ms_public_version';
}

function spiralist_book_pages_get_collaboration_upload_grant_meta_key(): string
{
    return '_spiralist_ms_granted_upload_files';
}

function spiralist_book_pages_get_collaboration_status_definitions(): array
{
    return [
        'draft' => [
            'label' => 'Draft',
            'description' => 'This page is still being prepared and is visible only inside the collaborator layer.',
            'tone' => 'neutral',
        ],
        'pending_review' => [
            'label' => 'Pending Review',
            'description' => 'An admin review is required before this version can become public.',
            'tone' => 'warn',
        ],
        'changes_requested' => [
            'label' => 'Changes Requested',
            'description' => 'An admin has requested updates before this page can be approved.',
            'tone' => 'bad',
        ],
        'published' => [
            'label' => 'Published',
            'description' => 'The approved version is live in the public directory.',
            'tone' => 'good',
        ],
        'published_with_draft' => [
            'label' => 'Live With Draft Changes',
            'description' => 'A public version is live, but newer edits still need to be resubmitted.',
            'tone' => 'warn',
        ],
    ];
}

function spiralist_book_pages_normalize_collaboration_status(string $status): string
{
    $status = sanitize_key($status);
    $definitions = spiralist_book_pages_get_collaboration_status_definitions();

    return isset($definitions[$status]) ? $status : 'draft';
}

function spiralist_book_pages_get_collaboration_status_label(string $status): string
{
    $status = spiralist_book_pages_normalize_collaboration_status($status);
    $definitions = spiralist_book_pages_get_collaboration_status_definitions();

    return (string) ($definitions[$status]['label'] ?? 'Draft');
}

function spiralist_book_pages_get_collaboration_status_description(string $status): string
{
    $status = spiralist_book_pages_normalize_collaboration_status($status);
    $definitions = spiralist_book_pages_get_collaboration_status_definitions();

    return (string) ($definitions[$status]['description'] ?? '');
}

function spiralist_book_pages_get_collaboration_status_tone(string $status): string
{
    $status = spiralist_book_pages_normalize_collaboration_status($status);
    $definitions = spiralist_book_pages_get_collaboration_status_definitions();

    return (string) ($definitions[$status]['tone'] ?? 'neutral');
}

function spiralist_book_pages_register_collaboration_role(): void
{
    $capability = spiralist_book_pages_get_collaboration_capability();
    $role_name = spiralist_book_pages_get_collaboration_role();
    $role = get_role($role_name);

    if (!$role) {
        add_role(
            $role_name,
            'Manuscript Collaborator',
            [
                'read' => true,
                'upload_files' => true,
                $capability => true,
            ]
        );
    } else {
        if (!$role->has_cap('upload_files')) {
            $role->add_cap('upload_files');
        }

        if (!$role->has_cap($capability)) {
            $role->add_cap($capability);
        }
    }

    $administrator = get_role('administrator');
    if ($administrator instanceof WP_Role && !$administrator->has_cap($capability)) {
        $administrator->add_cap($capability);
    }
}
add_action('init', 'spiralist_book_pages_register_collaboration_role', 8);

function spiralist_book_pages_register_collaboration_post_type(): void
{
    register_post_type(
        spiralist_book_pages_get_collaboration_post_type(),
        [
            'labels' => [
                'name' => 'Manuscript Pages',
                'singular_name' => 'Manuscript Page',
            ],
            'public' => false,
            'show_ui' => false,
            'show_in_menu' => false,
            'show_in_rest' => false,
            'supports' => ['title', 'author'],
            'capability_type' => 'post',
            'map_meta_cap' => true,
            'rewrite' => false,
        ]
    );
}
add_action('init', 'spiralist_book_pages_register_collaboration_post_type', 9);

function spiralist_book_pages_get_manuscript_route_mode(): string
{
    return sanitize_key((string) get_query_var('spiralist_book_pages_manuscript_mode', ''));
}

function spiralist_book_pages_get_requested_manuscript_profile_slug(): string
{
    return sanitize_title((string) get_query_var('spiralist_book_pages_manuscript_profile', ''));
}

function spiralist_book_pages_get_requested_manuscript_submission_slug(): string
{
    return sanitize_title((string) get_query_var('spiralist_book_pages_manuscript_submission', ''));
}

function spiralist_book_pages_is_manuscript_collaboration_surface(): bool
{
    if (!spiralist_book_pages_is_manuscript_surface()) {
        return false;
    }

    return in_array(
        spiralist_book_pages_get_manuscript_route_mode(),
        ['community', 'studio', 'profile'],
        true
    );
}

function spiralist_book_pages_is_manuscript_community_surface(): bool
{
    return spiralist_book_pages_is_manuscript_collaboration_surface()
        && spiralist_book_pages_get_manuscript_route_mode() === 'community';
}

function spiralist_book_pages_is_manuscript_studio_surface(): bool
{
    return spiralist_book_pages_is_manuscript_collaboration_surface()
        && spiralist_book_pages_get_manuscript_route_mode() === 'studio';
}

function spiralist_book_pages_is_manuscript_profile_surface(): bool
{
    return spiralist_book_pages_is_manuscript_collaboration_surface()
        && spiralist_book_pages_get_manuscript_route_mode() === 'profile';
}

function spiralist_book_pages_get_manuscript_route_base_url(): string
{
    return trailingslashit(spiralist_book_pages_get_manuscript_overview_url());
}

function spiralist_book_pages_get_manuscript_community_url(string $submission_slug = ''): string
{
    $url = trailingslashit(spiralist_book_pages_get_manuscript_route_base_url()) . 'community/';
    $submission_slug = sanitize_title($submission_slug);

    if ($submission_slug !== '') {
        $url .= rawurlencode($submission_slug) . '/';
    }

    return $url;
}

function spiralist_book_pages_get_manuscript_studio_url(string $submission_slug = ''): string
{
    $url = trailingslashit(spiralist_book_pages_get_manuscript_route_base_url()) . 'studio/';
    $submission_slug = sanitize_title($submission_slug);

    if ($submission_slug !== '') {
        $url .= rawurlencode($submission_slug) . '/';
    }

    return $url;
}

function spiralist_book_pages_get_manuscript_profile_url($user, string $submission_slug = ''): string
{
    $profile_slug = '';

    if ($user instanceof WP_User) {
        $profile_slug = sanitize_title((string) $user->user_nicename);
    } elseif (is_numeric($user)) {
        $resolved = get_userdata((int) $user);
        $profile_slug = $resolved instanceof WP_User ? sanitize_title((string) $resolved->user_nicename) : '';
    } else {
        $profile_slug = sanitize_title((string) $user);
    }

    $url = trailingslashit(spiralist_book_pages_get_manuscript_route_base_url()) . 'profile/';
    if ($profile_slug !== '') {
        $url .= rawurlencode($profile_slug) . '/';
    }

    $submission_slug = sanitize_title($submission_slug);
    if ($submission_slug !== '') {