'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; } }