Files
wp-multisite-waas/inc/admin-pages/class-view-logs-admin-page.php
David Stone a815fdf179 Prep Plugin for release on WordPress.org
Escape everything that should be escaped.
Add nonce checks where needed.
Sanitize all inputs.
Apply Code style changes across the codebase.
Correct many deprecation notices.
Optimize load order of many filters.
2025-04-07 09:15:21 -06:00

366 lines
8.3 KiB
PHP

<?php
/**
* WP Multisite WaaS System Info Admin Page.
*
* @package WP_Ultimo
* @subpackage Admin_Pages
* @since 2.0.0
*/
namespace WP_Ultimo\Admin_Pages;
use WP_Ultimo\Logger;
// Exit if accessed directly
defined('ABSPATH') || exit;
/**
* WP Multisite WaaS System Info Admin Page.
*/
class View_Logs_Admin_Page extends Edit_Admin_Page {
/**
* Holds the ID for this page, this is also used as the page slug.
*
* @var string
*/
protected $id = 'wp-ultimo-view-logs';
/**
* Is this a top-level menu or a submenu?
*
* @since 1.8.2
* @var string
*/
protected $type = 'submenu';
/**
* If this is a submenu, we need a parent menu to attach this to
*
* @since 1.8.2
* @var string
*/
protected $parent = 'none';
/**
* Allows us to highlight another menu page, if this page has no parent page at all.
*
* @since 2.0.0
* @var boolean
*/
protected $highlight_menu_slug = 'wp-ultimo-events';
/**
* If this number is greater than 0, a badge with the number will be displayed alongside the menu title
*
* @since 1.8.2
* @var integer
*/
protected $badge_count = 0;
/**
* Holds the admin panels where this page should be displayed, as well as which capability to require.
*
* To add a page to the regular admin (wp-admin/), use: 'admin_menu' => 'capability_here'
* To add a page to the network admin (wp-admin/network), use: 'network_admin_menu' => 'capability_here'
* To add a page to the user (wp-admin/user) admin, use: 'user_admin_menu' => 'capability_here'
*
* @since 2.0.0
* @var array
*/
protected $supported_panels = [
'network_admin_menu' => 'manage_network',
];
/**
* Allow child classes to add further initializations.
*
* @since 1.8.2
* @return void
*/
public function init(): void {
add_action('wp_ajax_wu_handle_view_logs', [$this, 'handle_view_logs']);
}
/**
* Registers extra scripts needed for this page.
*
* @since 2.0.0
* @return void
*/
public function register_scripts(): void {
parent::register_scripts();
\WP_Ultimo\Scripts::get_instance()->register_script('wu-view-log', wu_get_asset('view-logs.js', 'js'), ['jquery']);
wp_localize_script(
'wu-view-log',
'wu_view_logs',
[
'i18n' => [
'copied' => __('Copied!', 'wp-multisite-waas'),
],
]
);
wp_enqueue_script('wu-view-log');
wp_enqueue_script('clipboard');
}
/**
* Returns the title of the page.
*
* @since 2.0.0
* @return string Title of the page.
*/
public function get_title() {
return __('View Log', 'wp-multisite-waas');
}
/**
* Returns the title of menu for this page.
*
* @since 2.0.0
* @return string Menu label of the page.
*/
public function get_menu_title() {
return __('View Log', 'wp-multisite-waas');
}
/**
* Handles the actions for the logs and system info.
*
* @since 2.0.0
*
* @return array
*/
public function handle_view_logs() {
$logs_list = list_files(
Logger::get_logs_folder(),
2,
[
'index.html',
]
);
$logs_list = array_combine(array_values($logs_list), array_map(fn($file) => str_replace(Logger::get_logs_folder(), '', (string) $file), $logs_list));
if (empty($logs_list)) {
$logs_list[''] = __('No log files found', 'wp-multisite-waas');
}
$file = wu_request('file');
$file_name = '';
$contents = '';
// Security check
if ($file && ! stristr((string) $file, Logger::get_logs_folder())) {
wp_die(__('You can see files that are not WP Multisite WaaS\'s logs', 'wp-multisite-waas'));
}
if ( ! $file && ! empty($logs_list)) {
$file = ! $file && ! empty($logs_list) ? current(array_keys($logs_list)) : false;
}
$file_name = str_replace(Logger::get_logs_folder(), '', (string) $file);
$default_content = wu_request('return_ascii', 'yes') === 'yes' ? wu_get_template_contents('events/ascii-badge') : __('No log entries found.', 'wp-multisite-waas');
$contents = $file && file_exists($file) ? file_get_contents($file) : $default_content;
$response = [
'file' => $file,
'file_name' => $file_name,
'contents' => $contents,
'logs_list' => $logs_list,
];
if (wp_doing_ajax()) {
wp_send_json_success($response);
} else {
return $response;
}
}
/**
* Allow child classes to register widgets, if they need them.
*
* @since 1.8.2
* @return void
*/
public function register_widgets(): void {
$info = $this->handle_view_logs();
add_meta_box('wp-ultimo-log-contents', __('Log Contents', 'wp-multisite-waas'), [$this, 'output_default_widget_payload'], get_current_screen()->id, 'normal', null, $info);
$this->add_fields_widget(
'file-selector',
[
'title' => __('Log Files', 'wp-multisite-waas'),
'fields' => [
'log_file' => [
'type' => 'select',
'title' => __('Select Log File', 'wp-multisite-waas'),
'placeholder' => __('Select Log File', 'wp-multisite-waas'),
'value' => wu_request('file'),
'tooltip' => '',
'options' => $info['logs_list'],
],
'download' => [
'type' => 'submit',
'title' => __('Download Log', 'wp-multisite-waas'),
'value' => 'download',
'classes' => 'button button-primary wu-w-full',
],
],
]
);
$this->add_fields_widget(
'info',
[
'title' => __('Timestamps', 'wp-multisite-waas'),
'position' => 'side',
'fields' => [
'date_modified' => [
'title' => __('Last Modified at', 'wp-multisite-waas'),
'type' => 'text-edit',
'date' => true,
'value' => date_i18n('Y-m-d H:i:s', filemtime($info['file'])),
'display_value' => date_i18n('Y-m-d H:i:s', filemtime($info['file'])),
],
],
]
);
}
/**
* Outputs the pre block that shows the content.
*
* @since 2.0.0
*
* @param mixed $unused Not sure.
* @param array $data Arguments passed by add_meta_box.
* @return void
*/
public function output_default_widget_payload($unused, $data): void {
wu_get_template(
'events/widget-payload',
[
'title' => __('Event Payload', 'wp-multisite-waas'),
'loading_text' => __('Loading Payload', 'wp-multisite-waas'),
'payload' => $data['args']['contents'],
]
);
}
/**
* Returns the labels to be used on the admin page.
*
* @since 2.0.0
* @return array
*/
public function get_labels() {
return [
'edit_label' => __('View Log', 'wp-multisite-waas'),
'add_new_label' => __('View Log', 'wp-multisite-waas'),
'title_placeholder' => __('Enter Customer', 'wp-multisite-waas'),
'title_description' => __('Viewing file: ', 'wp-multisite-waas'),
'delete_button_label' => __('Delete Log File', 'wp-multisite-waas'),
'delete_description' => __('Be careful. This action is irreversible.', 'wp-multisite-waas'),
];
}
/**
* Returns the object being edit at the moment.
*
* @since 2.0.0
* @return array
*/
public function get_object() {
return [];
}
/**
* Register additional hooks to page load such as the action links and the save processing.
*
* @since 2.0.0
* @return void
*/
public function page_loaded(): void {
/**
* Get the action links
*/
$this->action_links = $this->action_links();
/**
* Process save, if necessary
*/
$this->process_save();
}
/**
* Should implement the processes necessary to save the changes made to the object.
*
* @since 2.0.0
* @return void
*/
public function handle_save(): void {
$action = wu_request('submit_button', 'none');
if ('none' === $action) {
WP_Ultimo()->notices->add(__('Something wrong happened', 'wp-multisite-waas'), 'error', 'network-admin');
return;
}
$file = wu_request('log_file', false);
if ( ! file_exists($file)) {
WP_Ultimo()->notices->add(__('File not found', 'wp-multisite-waas'), 'error', 'network-admin');
return;
}
if ('download' === $action) {
$file_name = str_replace(Logger::get_logs_folder(), '', (string) $file);
header('Content-Type: application/octet-stream');
header("Content-Disposition: attachment; filename=$file_name");
header('Pragma: no-cache');
readfile($file);
exit;
} elseif ('delete' === $action) {
$status = unlink($file);
if ( ! $status) {
WP_Ultimo()->notices->add(__('We were unable to delete file', 'wp-multisite-waas'), 'error', 'network-admin');
return;
}
}
$url = remove_query_arg('log_file');
wp_safe_redirect(add_query_arg('deleted', 1, $url));
exit;
}
}