{$ctx->lang('admin_login')}:
{$ctx->lang('admin_password')}:
HTML; $js = << Authorized as {$admin_login} | Sign out
Uploads
{$ctx->lang('admin_errors')}
{$ctx->lang('admin_auth_log')}
{$ctx->lang('admin_actions_log')}
HTML; } // uploads page // ------------ function uploads($ctx, $uploads, $error, array $langs) { return <<if_true($error, $ctx->formError, $error)} {$ctx->bc([ ['text' => $ctx->lang('admin_title'), 'url' => '/admin/'], ['text' => $ctx->lang('blog_uploads')], ])}
{$ctx->lang('blog_upload_form_file')}:
{$ctx->lang('blog_upload_form_custom_name')}:
{$ctx->for_each($langs, fn($l) => $ctx->uploads_form_note_field($l))}
{$ctx->for_each($uploads, fn($u) => $ctx->uploads_item( id: $u->id, name: $u->name, direct_url: $u->getDirectUrl(), note_ru: $u->noteRu, note_en: $u->noteEn, addslashes_note_ru: $u->noteRu, addslashes_note_en: $u->noteEn, markdown: $u->getMarkdown(), size: $u->getSize(), ))}
HTML; } function uploads_form_note_field($ctx, PostLanguage $lang) { $label = $ctx->lang('blog_upload_form_note'); $label .= ' ('.$lang->name.')'; return <<
{$label}:
HTML; } function uploads_item($ctx, $id, $direct_url, $note_en, $note_ru, $addslashes_note_en, $addslashes_note_ru, $markdown, $name, $size) { return <<
{$ctx->lang('blog_upload_show_md')} | Edit note Ru | Edit note En | {$ctx->lang('blog_upload_delete')}
{$name}
{$size}
{$ctx->if_true($note_en, fn() => '
En'.$note_en.'
')} {$ctx->if_true($note_ru, fn() => '
Ru'.$note_ru.'
')} HTML; } function postForm(\SkinContext $ctx, string|Stringable $title, string|Stringable $text, string|Stringable $short_name, array $langs, array $js_texts, string|Stringable|null $date = null, bool $is_edit = false, ?bool $saved = null, ?bool $visible = null, ?bool $toc = null, string|Stringable|null $post_url = null, ?int $post_id = null, ?string $lang = null): array { $form_url = !$is_edit ? '/articles/write/' : $post_url.'edit/'; // breadcrumbs $bc_tree = [ ['url' => '/articles/?lang='.$lang, 'text' => $ctx->lang('articles')] ]; if ($is_edit) { $bc_tree[] = ['url' => $post_url.'?lang='.$lang, 'text' => $ctx->lang('blog_view_post')]; } else { $bc_tree[] = ['text' => $ctx->lang('blog_new_post')]; } $html = << {$ctx->if_true($saved, fn() => '
'.$ctx->lang('info_saved').'
')} {$ctx->bc($bc_tree, 'padding-bottom: 12px')}
{$ctx->lang('blog_write_form_title')}
{$ctx->lang('blog_write_form_text')}
{$ctx->lang('blog_post_options')}
{$ctx->lang('blog_text_options')}
 
{$ctx->lang('blog_write_form_date')}
if_true($date, ' value="'.$date.'"')}>
{$ctx->lang('blog_write_form_short_name')}
 
HTML; $js_params = [ 'langs' => array_map(fn($lang) => $lang->value, $langs), 'token' => $is_edit ? csrf_get('editpost'.$post_id) : csrf_get('post_add') ]; if ($is_edit) $js_params += [ 'edit' => true, 'id' => $post_id, 'texts' => $js_texts ]; $js_params = jsonEncode($js_params); $js = <<bc([ ['url' => '/'.$short_name.'/', 'text' => $ctx->lang('view_page')] ], 'padding-bottom: 12px'); } else { $bc_html = ''; } $html = << {$ctx->if_true($saved, fn() => '
'.$ctx->lang('info_saved').'
')} {$bc_html}
{$ctx->lang('pages_write_form_title')}
{$ctx->lang('pages_write_form_text')}
{$ctx->if_then_else($is_edit, fn() => $ctx->pageFormEditOptions($short_name, $visible), fn() => $ctx->pageFormAddOptions($short_name))}
HTML; $js_params = [ 'pages' => true, 'edit' => $is_edit, 'token' => $is_edit ? $ctx->csrf('editpage'.$short_name) : $ctx->csrf('addpage'), 'langs' => array_map(fn($lang) => $lang->value, $langs), // still needed for draft erasing ]; if ($js_text !== null) $js_params['text'] = $js_text; $js_params = jsonEncode($js_params); $js = <<
{$ctx->lang('pages_write_form_short_name')}
{$ctx->lang('pages_write_form_options')}
HTML; } function pageFormAddOptions($ctx, $short_name) { return <<
HTML; } function pageNew($ctx, $short_name) { return << HTML; } // misc function formError($ctx, $error) { return <<{$ctx->lang('error')}: {$error} HTML; } function markdownPreview($ctx, $unsafe_html, $title) { return <<
{$ctx->if_true($title, '

'.$title.'

')}
{$unsafe_html}
HTML; } function books($ctx) { return <<bc([ ['text' => $ctx->lang('admin_title'), 'url' => '/admin/'], ['text' => $ctx->lang('admin_books')], ])} HTML; } // ---------------------------------------------------- // ---------------------- ERRORS ---------------------- // ---------------------------------------------------- function errors($ctx, array $list, int $count, int $pn_page, int $pn_pages, string $url, ?string $ip_filter = null, ?int $ip = null, ?string $query = null, ?string $url_query = null, ?string $file_query = null, ?string $line_query = null) { return <<bc([ ['text' => $ctx->lang('admin_title'), 'url' => '/admin/'], ['text' => $ctx->lang('admin_errors')], ])}
{$ctx->if_true($ip, fn() => '')}
{$ctx->if_then_else(!empty($list), fn() => $ctx->errors_table($list), fn() => '
Error log is empty.
')} {$ctx->pagenav($pn_page, $pn_pages, $url.'page={page}')} HTML; } function errors_table($ctx, array $list) { return << Time Source Error {$ctx->for_each($list, fn($item) => $ctx->errors_table_item( date: $item['date'], is_cli: (bool)$item['is_cli'], is_custom: (bool)$item['custom'], user_agent: $item['ua'], ip: (int)$item['ip'], ip_s: $item['ip_s'], full_url: $item['full_url'], url: $item['url'], file: $item['file'], line: (int)$item['line'], admin_id: (int)$item['admin_id'], nl2br_text: $item['text'], num: (int)$item['num'], errtype: $item['errtype'] ?? null, time: $item['time'], stacktrace: $item['stacktrace'], item_id: (int)$item['id'] ))} HTML; } function errors_table_item($ctx, int $item_id, string $date, bool $is_cli, bool $is_custom, string $user_agent, int $ip, string $ip_s, string $full_url, string $url, string $file, int $line, int $admin_id, string $nl2br_text, int $num, ?string $errtype, string $time, string $stacktrace) { return << {$date} {$ctx->if_then_else(!$is_cli, fn() => ''.$ip_s.' '.$url.'
'.$user_agent, fn() => 'cmd')} {$ctx->if_true($admin_id, fn() => 'admin='.$admin_id.'')} {$ctx->if_then_else($is_custom, fn() => ''.$num.', '.$time.' '.$file.':'.$line.'
' .''.$errtype.' '.$nl2br_text, fn() => ''.$num.', '.$time.' '.$nl2br_text)} {$ctx->if_true($stacktrace, fn() => $ctx->errors_table_item_stacktrace($item_id, $stacktrace))} HTML; } function errors_table_item_stacktrace($ctx, $item_id, $nl2br_stacktrace) { return << Show/hide stacktrace HTML; } // ------------------------------------------------------ // ---------------------- AUTH LOG ---------------------- // ------------------------------------------------------ function auth_log($ctx, array $list, int $pn_page, int $pn_pages) { return <<bc([ ['text' => $ctx->lang('admin_title'), 'url' => '/admin/'], ['text' => $ctx->lang('admin_auth_log')], ])} {$ctx->if_then_else(!empty($list), fn() => $ctx->auth_log_table($list), fn() => '
Auth log is empty.
')} {$ctx->pagenav($pn_page, $pn_pages, '/admin/auth-log/?page={page}')} HTML; } function auth_log_table($ctx, array $list) { return << Admin Time IP User-Agent {$ctx->for_each($list, fn($item) => $ctx->auth_log_table_item( date: $item['date'], ip: $item['ip'], user_agent: $item['ua'], admin_login: $item['login'], admin_id: (int)$item['admin_id'], activity_ts: $item['activity_ts_s']))} HTML; } function auth_log_table_item($ctx, $date, $ip, $user_agent, string $admin_login, int $admin_id, string $activity_ts) { return << {$admin_login} (id={$admin_id}) {$date} {$ip} {$user_agent} HTML; } // --------------------------------------------------------- // ---------------------- ACTIONS LOG ---------------------- // --------------------------------------------------------- function actions_log($ctx, array $list, array $admin_logins, string $url, array $action_types, int $pn_page, int $pn_pages) { return <<bc([ ['text' => $ctx->lang('admin_title'), 'url' => '/admin/'], ['text' => $ctx->lang('admin_actions_log')], ])} {$ctx->if_then_else(!empty($list), fn() => $ctx->actions_log_table($list, $admin_logins, $action_types), fn() => '
Actions log is empty.
')} {$ctx->pagenav($pn_page, $pn_pages, $url.'page={page}')} HTML; } function actions_log_table($ctx, array $list, array $admin_logins, array $action_types) { return << Time Who Action Data {$ctx->for_each($list, fn(\AdminActions\BaseAction $item) => $ctx->actions_log_table_item( date: $item->getDate(), ip: $item->getIPv4(), is_cli: $item->isCommandLineAction(), admin_login: $admin_logins[$item->getAdminId()], action_name: $item->getActionName(), unsafe_data: $item->renderHtml()))} HTML; } function actions_log_table_item($ctx, string $date, string $ip, bool $is_cli, string $admin_login, string $action_name, string $unsafe_data) { return << {$date} {$ctx->if_then_else(!$is_cli, fn() => $admin_login.', '.$ip, fn() => 'console')} {$action_name} {$unsafe_data} HTML; }