Hooktrail: switches recording on or off for the current user, * holds the site-wide options, and offers the plugin hook reference. * * @package Hooktrail */ if ( ! defined( 'ABSPATH' ) ) { exit; } class Hooktrail_Settings { const OPTION = 'hooktrail_settings'; const SLUG = 'hooktrail'; const SCAN_NONCE = 'hooktrail_scan'; const MAX_ROWS = 1000; const DEFAULTS = array( 'record_admin' => true, 'record_background' => true, 'hide_noisy' => true, ); public function __construct() { add_action( 'admin_menu', array( $this, 'register_page' ) ); add_action( 'admin_init', array( $this, 'register_settings' ) ); add_action( 'admin_post_hooktrail_hooks_md', array( $this, 'download_markdown' ) ); add_filter( 'plugin_action_links_' . plugin_basename( HOOKTRAIL_FILE ), array( $this, 'action_links' ) ); } /** * Settings with defaults. * * @return array { record_admin: bool, record_background: bool, hide_noisy: bool } */ public static function get() { $saved = get_option( self::OPTION, array() ); return wp_parse_args( is_array( $saved ) ? $saved : array(), self::DEFAULTS ); } public function register_page() { $hook = add_management_page( __( 'Hooktrail', 'hooktrail' ), __( 'Hooktrail', 'hooktrail' ), Hooktrail_Panel::CAPABILITY, self::SLUG, array( $this, 'render_page' ) ); add_action( 'admin_print_styles-' . $hook, function () { wp_enqueue_style( 'hooktrail-admin', HOOKTRAIL_URL . 'assets/hooktrail-admin.css', array(), HOOKTRAIL_VERSION ); } ); } public function register_settings() { register_setting( self::SLUG, self::OPTION, array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize' ), 'default' => self::DEFAULTS, ) ); } /** * @param mixed $input Submitted values. * @return array */ public function sanitize( $input ) { $input = is_array( $input ) ? $input : array(); $clean = array(); foreach ( array_keys( self::DEFAULTS ) as $key ) { $clean[ $key ] = ! empty( $input[ $key ] ); } return $clean; } /** * @param array $links Plugin row links. * @return array */ public function action_links( $links ) { array_unshift( $links, sprintf( '%s', esc_url( admin_url( 'tools.php?page=' . self::SLUG ) ), esc_html__( 'Settings', 'hooktrail' ) ) ); return $links; } public function render_page() { if ( ! current_user_can( Hooktrail_Panel::CAPABILITY ) ) { return; } $enabled = Hooktrail_Panel::is_enabled_for( get_current_user_id() ); $settings = self::get(); ?>

render_hook_reference(); ?>
scan_plugin( $selected ); } ?>

%s

', esc_html( $result->get_error_message() ) ); return; } $download = wp_nonce_url( add_query_arg( array( 'action' => 'hooktrail_hooks_md', 'plugin' => $selected, ), admin_url( 'admin-post.php' ) ), self::SCAN_NONCE ); ?>



self::MAX_ROWS ) { echo '

' . esc_html__( 'Only the first 1,000 are shown here. The Markdown download has all of them.', 'hooktrail' ) . '

'; } } /** * Send the hook reference for one plugin as a Markdown file. */ public function download_markdown() { if ( ! current_user_can( Hooktrail_Panel::CAPABILITY ) ) { wp_die( esc_html__( 'You do not have permission to do this.', 'hooktrail' ), '', array( 'response' => 403 ) ); } check_admin_referer( self::SCAN_NONCE ); $folder = isset( $_GET['plugin'] ) ? sanitize_file_name( wp_unslash( $_GET['plugin'] ) ) : ''; $scanner = new Hooktrail_Hook_Scanner(); $result = $scanner->scan_plugin( $folder ); if ( is_wp_error( $result ) ) { wp_die( esc_html( $result->get_error_message() ) ); } $choices = Hooktrail_Hook_Scanner::plugin_choices(); $markdown = Hooktrail_Hook_Scanner::to_markdown( $choices[ $folder ], $result ); nocache_headers(); header( 'Content-Type: text/markdown; charset=utf-8' ); header( 'Content-Disposition: attachment; filename="' . $folder . '-hooks.md"' ); header( 'X-Content-Type-Options: nosniff' ); // Plain-text Markdown file download, not HTML. echo $markdown; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped exit; } }