Admin Core
**Site relevance:** Spiralist.org
**Memory type:** plugin source memory
**Source path:** Spiralist/wp-content/plugins/ns12-manuscript/includes/admin-core.php
**Size:** 7.8 KB
Summary
if (!defined('ABSPATH'))
Source Preview
This source file is short enough to preview directly on its source-memory page.
<?php
if (!defined('ABSPATH')) {
exit;
}
function spiralist_book_pages_admin_capability(): string
{
return 'manage_options';
}
function spiralist_book_pages_admin_can_manage(): bool
{
return current_user_can(spiralist_book_pages_admin_capability());
}
function spiralist_book_pages_admin_notice_key(): string
{
return 'spiralist_book_pages_admin_notice_' . get_current_user_id();
}
function spiralist_book_pages_admin_set_notice(string $message, string $type = 'success', array $details = []): void
{
set_transient(
spiralist_book_pages_admin_notice_key(),
[
'message' => $message,
'type' => $type,
'details' => array_values(array_filter(array_map('strval', $details), 'strlen')),
],
MINUTE_IN_SECONDS
);
}
function spiralist_book_pages_admin_get_notice(): array
{
$notice = get_transient(spiralist_book_pages_admin_notice_key());
if (!is_array($notice)) {
return [];
}
delete_transient(spiralist_book_pages_admin_notice_key());
return $notice;
}
function spiralist_book_pages_admin_pages(): array
{
return [
'overview' => 'ns12-manuscript',
'folios' => 'ns12-manuscript-folios',
'prompts' => 'ns12-manuscript-prompts',
'fragments' => 'ns12-manuscript-fragments',
'community' => 'ns12-manuscript-community',
'collaborators' => 'ns12-manuscript-collaborators',
];
}
function spiralist_book_pages_admin_page_slug(string $key): string
{
$pages = spiralist_book_pages_admin_pages();
return (string) ($pages[$key] ?? $pages['overview']);
}
function spiralist_book_pages_admin_normalize_page(string $page): string
{
$page = sanitize_key($page);
return in_array($page, spiralist_book_pages_admin_pages(), true)
? $page
: spiralist_book_pages_admin_page_slug('overview');
}
function spiralist_book_pages_admin_url(string $page, array $args = []): string
{
return add_query_arg(
array_merge(
[
'page' => spiralist_book_pages_admin_normalize_page($page),
],
$args
),
admin_url('admin.php')
);
}
function spiralist_book_pages_admin_redirect(string $page, array $args = []): void
{
wp_safe_redirect(spiralist_book_pages_admin_url($page, $args));
exit;
}
function spiralist_book_pages_admin_parse_list($value): array
{
if (is_string($value)) {
$value = preg_split('/[\r\n,]+/', $value) ?: [];
}
if (!is_array($value)) {
return [];
}
$items = array_map(
static function ($item): string {
return trim((string) $item);
},
$value
);
return array_values(array_unique(array_values(array_filter($items, 'strlen'))));
}
function spiralist_book_pages_admin_parse_slug_list($value): array
{
return array_values(
array_filter(
array_map('sanitize_title', spiralist_book_pages_admin_parse_list($value)),
'strlen'
)
);
}
function spiralist_book_pages_admin_is_list(array $value): bool
{
$expected = 0;
foreach (array_keys($value) as $key) {
if ($key !== $expected) {
return false;
}
$expected++;
}
return true;
}
function spiralist_book_pages_admin_humanize(string $value): string
{
$value = trim(str_replace(['_', '-'], ' ', $value));
if ($value === '') {
return '';
}
return ucwords(strtolower($value));
}
function spiralist_book_pages_admin_unique_slug(string $candidate, array $existing, string $fallback = 'item'): string
{
$slug = sanitize_title($candidate);
if ($slug === '') {
$slug = sanitize_title($fallback);
}
if ($slug === '') {
$slug = 'item';
}
$base = $slug;
$suffix = 2;
while (isset($existing[$slug])) {
$slug = $base . '-' . $suffix;
$suffix++;
}
return $slug;
}
function spiralist_book_pages_admin_badge(string $label, string $tone = 'neutral'): string
{
$class = 'badge';
if ($tone === 'good') {
$class .= ' good';
} elseif ($tone === 'warn') {
$class .= ' warn';
} elseif ($tone === 'bad') {
$class .= ' bad';
}
return '<span class="' . esc_attr($class) . '">' . esc_html($label) . '</span>';
}
function spiralist_book_pages_admin_status_tone(string $variant): string
{
if ($variant === 'fresh') {
return 'good';
}
if ($variant === 'missing' || $variant === 'stale') {
return 'warn';
}
return 'neutral';
}
function spiralist_book_pages_admin_render_styles(): void
{
static $done = false;
if ($done) {
return;
}
$done = true;
?>
<style>
.spiralist-book-admin{max-width:1320px}
.spiralist-book-admin .hero{display:grid;gap:18px;grid-template-columns:minmax(0,1.45fr) minmax(260px,.9fr);margin:18px 0 20px;padding:22px 24px;border:1px solid #dcdcde;border-radius:18px;background:linear-gradient(145deg,#fff 0%,#f7f2ea 100%);box-shadow:0 1px 2px rgba(15,23,42,.05)}
.spiralist-book-admin .kicker{margin:0 0 6px;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:#6b7280}
.spiralist-book-admin .actions,.spiralist-book-admin .inline,.spiralist-book-admin .tight-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.spiralist-book-admin .actions{justify-content:flex-end}
.spiralist-book-admin .grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));margin:18px 0}
.spiralist-book-admin .dual{display:grid;gap:16px;grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.spiralist-book-admin .stack{display:grid;gap:16px}
.spiralist-book-admin .panel{padding:18px;border:1px solid #dcdcde;border-radius:16px;background:#fff;box-shadow:0 1px 2px rgba(15,23,42,.04)}
.spiralist-book-admin .metric{display:grid;gap:8px}
.spiralist-book-admin .metric strong{font-size:30px;line-height:1}
.spiralist-book-admin .toolbar{display:flex;gap:12px;flex-wrap:wrap;justify-content:space-between;align-items:center;margin:18px 0}
.spiralist-book-admin .search{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.spiralist-book-admin .search input[type="search"]{min-width:280px}
.spiralist-book-admin .badge{display:inline-flex;align-items:center;padding:4px 10px;border-radius:999px;font-size:12px;font-weight:600;background:#eef2ff;color:#3730a3}
.spiralist-book-admin .badge.good{background:#f0fdf4;color:#166534}
.spiralist-book-admin .badge.warn{background:#fffbeb;color:#b45309}
.spiralist-book-admin .badge.bad{background:#fef2f2;color:#b91c1c}
.spiralist-book-admin .code{white-space:pre-wrap;overflow:auto;padding:14px 16px;border-radius:12px;background:#111827;color:#f9fafb;border:1px solid #dcdcde;font-family:Consolas,Monaco,monospace;font-size:12px;line-height:1.55}
.spiralist-book-admin .empty{padding:24px;text-align:center;border:1px dashed #dcdcde;border-radius:16px;background:#f6f7f7}
.spiralist-book-admin .fragment-list{display:grid;gap:10px;margin:0;padding:0;list-style:none}
.spiralist-book-admin .fragment-list a{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:12px 14px;border-radius:12px;border:1px solid #dcdcde;text-decoration:none;background:#fff}
.spiralist-book-admin .fragment-list a.active{border-color:#93c5fd;background:#eff6ff}
@media (max-width:960px){.spiralist-book-admin .hero{grid-template-columns:1fr}.spiralist-book-admin .actions{justify-content:flex-start}}
</style>
<?php
}