%d%s
',
$count > 0 && $heat !== '' ? ' is-' . esc_attr($heat) : '',
esc_url($url),
esc_attr($icon),
(int) $count,
esc_html($label),
);
}
public function render(): void
{
if (!self::connected()) {
echo '' . esc_html__('Change your site by asking, let visitors report bugs, and approve fixes right here. Two minutes to connect.', 'sarcio') . '
';
printf('%s
', esc_url(self::page(ReviewPage::SLUG)), esc_html__('Set up Sarcio', 'sarcio'));
return;
}
$summary = InboxSummary::get();
$kept = count(array_filter(KeptFixes::all(), static fn ($fix): bool => is_array($fix) && !empty($fix['enabled'])));
$requests = Requests::pendingCount();
if ($summary === null) {
echo '' . esc_html__('Sarcio could not be reached just now; the counts below are from this site only.', 'sarcio') . '
';
$summary = ['awaitingSecondApproval' => 0, 'live' => 0, 'needsReview' => 0, 'noticed' => 0, 'triaging' => 0];
}
echo '';
self::tile(self::page(ReviewPage::SLUG), 'dashicons-yes-alt', (int) $summary['needsReview'], __('Fixes ready to check', 'sarcio'), 'hot');
self::tile(self::page(ReviewPage::SLUG), 'dashicons-groups', (int) $summary['awaitingSecondApproval'], __('Waiting for a second approval', 'sarcio'), 'warm');
self::tile(self::page(RequestsPage::SLUG), 'dashicons-format-chat', $requests, __('Requests to apply', 'sarcio'), 'warm');
self::tile(self::page(ReviewPage::SLUG), 'dashicons-search', (int) $summary['triaging'], __('Reports being looked at', 'sarcio'));
self::tile(self::page(ReviewPage::LIVE_SLUG), 'dashicons-controls-play', (int) $summary['live'], __('Fixes live right now', 'sarcio'));
self::tile(self::page(KeptFixesPage::SLUG), 'dashicons-lock', $kept, __('Fixes kept on this site', 'sarcio'));
echo '
';
if ((int) $summary['needsReview'] + (int) $summary['awaitingSecondApproval'] + $requests === 0) {
echo '' . esc_html__('All caught up. Nothing is waiting for you.', 'sarcio') . '
';
}
echo '';
}
public function renderNoticed(): void
{
$summary = InboxSummary::get();
$workspace = Embed::workspaceUrl() ?? 'https://www.sarcio.io/app/';
if ($summary === null) {
echo '' . esc_html__('Sarcio could not be reached just now.', 'sarcio') . '
';
return;
}
if (!$summary['noticeEnabled']) {
echo '' . esc_html__('Sarcio can watch for what fails on your visitors’ pages (an error, a broken request) and open a report with a fix drafted when several of them hit the same thing, before anyone reports it. It is off for this site.', 'sarcio') . '
';
printf('%s
', esc_url($workspace), esc_html__('Turn on Sarcio noticed', 'sarcio'));
return;
}
echo '';
printf('
%d%s
', (int) $summary['noticed'], esc_html__('reports opened by Sarcio, last 7 days', 'sarcio'));
printf('
%d%s
', count($summary['signals']), esc_html__('failures seen by visitors', 'sarcio'));
echo '
';
if ($summary['signals'] === []) {
echo '' . esc_html__('Nothing failed for your visitors this week.', 'sarcio') . '
';
return;
}
echo '';
foreach ($summary['signals'] as $signal) {
$where = $signal['kind'] === 'request'
? trim(($signal['method'] ?? '') . ' ' . $signal['sample'] . ($signal['status'] !== null ? ' → ' . $signal['status'] : ''))
: $signal['sample'];
printf(
'
',
$signal['reported'] ? ' is-reported' : '',
$signal['kind'] === 'request' ? 'dashicons-warning' : 'dashicons-editor-code',
esc_html($where),
esc_html(sprintf(
/* translators: 1: the page path, 2: how many visitors, 3: "reported" or "watching". */
_n('on %1$s · %2$d visitor · %3$s', 'on %1$s · %2$d visitors · %3$s', $signal['count'], 'sarcio'),
$signal['urlPath'],
$signal['count'],
$signal['reported'] ? __('a report is open', 'sarcio') : __('watching', 'sarcio'),
)),
);
}
echo '
';
printf('', esc_url(self::page(ReviewPage::SLUG)), esc_html__('See the reports', 'sarcio'));
}
public function renderAssistant(): void
{
$recognised = Recognised::all();
$bridged = Recognised::bridged();
$updates = current_user_can('update_plugins') ? count(UpdateAbilities::pendingPlugins()) : 0;
$pending = array_values(array_filter(Scheduled::list(), static fn (array $schedule): bool => $schedule['status'] === 'pending'));
$recent = array_slice(array_values(array_filter(Journal::recent(), static fn (array $entry): bool => $entry['ability'] !== 'sarcio/changes-undo' && JournalAbilities::visible($entry))), 0, 3);
echo '';
foreach ($recognised as $plugin) {
printf(
' ',
esc_attr($plugin['icon']),
esc_html($plugin['name']),
esc_html($plugin['text']),
esc_url(self::assistantUrl($plugin['prompt'])),
esc_html(sprintf(
/* translators: %s: an example request. */
__('Try: “%s”', 'sarcio'),
$plugin['prompt'],
)),
);
}
if ($updates > 0) {
printf(
' ',
esc_html(sprintf(
/* translators: %d: how many plugins. */
_n('%d plugin update waiting', '%d plugin updates waiting', $updates, 'sarcio'),
$updates,
)),
esc_html__('The assistant updates them one at a time, and can put a WordPress.org plugin back to the version it had.', 'sarcio'),
esc_url(self::assistantUrl(__('What needs updating?', 'sarcio'))),
esc_html__('Try: “What needs updating?”', 'sarcio'),
);
}
if ($bridged !== []) {
$names = array_slice(array_keys($bridged), 0, 4);
printf(
'%s%s
',
esc_html(sprintf(
/* translators: %d: how many plugins. */
_n('%d other plugin the assistant can work', '%d other plugins the assistant can work', count($bridged), 'sarcio'),
count($bridged),
)),
esc_html(sprintf(
/* translators: %s: plugin names. */
__('They offer their own abilities: %s. Ask for what they do.', 'sarcio'),
implode(', ', $names),
)),
);
}
if ($recognised === [] && $bridged === [] && $updates === 0) {
echo ' ';
}
echo '
';
if ($pending !== []) {
echo '';
foreach (array_slice($pending, 0, 2) as $schedule) {
printf(
'- %s
',
esc_html(sprintf(
/* translators: 1: how many changes, 2: the date and time. */
_n('%1$d change goes live %2$s', '%1$d changes go live %2$s', count($schedule['changes']), 'sarcio'),
count($schedule['changes']),
str_replace('T', ' ', (string) $schedule['applyAt']),
)),
);
}
echo '
';
}
if ($recent !== []) {
echo '';
foreach ($recent as $entry) {
printf(
'- %s%s
',
$entry['undoneAt'] !== null ? 'dashicons-undo' : 'dashicons-yes',
esc_html($entry['summary']),
$entry['undoneAt'] !== null ? ' ' . esc_html__('(undone)', 'sarcio') : '',
);
}
echo '
';
}
$report = Report::build(Report::previousMonth());
echo '';
}
}