mirror of
https://github.com/felixfoertsch/wordpress-dev-env.git
synced 2026-04-18 07:18:43 +02:00
Initial commit
This commit is contained in:
24
wordpress_plugins/query-monitor/output/Headers.php
Normal file
24
wordpress_plugins/query-monitor/output/Headers.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
/**
|
||||
* Abstract output class for HTTP headers.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
abstract class QM_Output_Headers extends QM_Output {
|
||||
|
||||
public function output() {
|
||||
|
||||
$id = $this->collector->id;
|
||||
|
||||
foreach ( $this->get_output() as $key => $value ) {
|
||||
if ( is_scalar( $value ) ) {
|
||||
header( sprintf( 'X-QM-%s-%s: %s', $id, $key, $value ) );
|
||||
} else {
|
||||
header( sprintf( 'X-QM-%s-%s: %s', $id, $key, json_encode( $value ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
517
wordpress_plugins/query-monitor/output/Html.php
Normal file
517
wordpress_plugins/query-monitor/output/Html.php
Normal file
@@ -0,0 +1,517 @@
|
||||
<?php
|
||||
/**
|
||||
* Abstract output class for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
abstract class QM_Output_Html extends QM_Output {
|
||||
|
||||
protected static $file_link_format = null;
|
||||
|
||||
protected $current_id = null;
|
||||
protected $current_name = null;
|
||||
|
||||
public function name() {
|
||||
_deprecated_function(
|
||||
esc_html( get_class( $this->collector ) . '::name()' ),
|
||||
'3.5',
|
||||
esc_html( get_class( $this ) . '::name()' )
|
||||
);
|
||||
|
||||
return $this->collector->name();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html( $this->name() ),
|
||||
) );
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
public function get_output() {
|
||||
ob_start();
|
||||
// compat until I convert all the existing outputters to use `get_output()`
|
||||
$this->output();
|
||||
$out = ob_get_clean();
|
||||
return $out;
|
||||
}
|
||||
|
||||
protected function before_tabular_output( $id = null, $name = null ) {
|
||||
if ( null === $id ) {
|
||||
$id = $this->collector->id();
|
||||
}
|
||||
if ( null === $name ) {
|
||||
$name = $this->name();
|
||||
}
|
||||
|
||||
$this->current_id = $id;
|
||||
$this->current_name = $name;
|
||||
|
||||
printf(
|
||||
'<div class="qm" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
|
||||
esc_attr( $id )
|
||||
);
|
||||
|
||||
echo '<table class="qm-sortable">';
|
||||
|
||||
printf(
|
||||
'<caption class="qm-screen-reader-text"><h2 id="%1$s-caption">%2$s</h2></caption>',
|
||||
esc_attr( $id ),
|
||||
esc_html( $name )
|
||||
);
|
||||
}
|
||||
|
||||
protected function after_tabular_output() {
|
||||
echo '</table>';
|
||||
echo '</div>';
|
||||
|
||||
$this->output_concerns();
|
||||
}
|
||||
|
||||
protected function before_non_tabular_output( $id = null, $name = null ) {
|
||||
if ( null === $id ) {
|
||||
$id = $this->collector->id();
|
||||
}
|
||||
if ( null === $name ) {
|
||||
$name = $this->name();
|
||||
}
|
||||
|
||||
$this->current_id = $id;
|
||||
$this->current_name = $name;
|
||||
|
||||
printf(
|
||||
'<div class="qm qm-non-tabular" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
|
||||
esc_attr( $id )
|
||||
);
|
||||
|
||||
echo '<div class="qm-boxed">';
|
||||
|
||||
printf(
|
||||
'<h2 class="qm-screen-reader-text" id="%1$s-caption">%2$s</h2>',
|
||||
esc_attr( $id ),
|
||||
esc_html( $name )
|
||||
);
|
||||
}
|
||||
|
||||
protected function after_non_tabular_output() {
|
||||
echo '</div>';
|
||||
echo '</div>';
|
||||
|
||||
$this->output_concerns();
|
||||
}
|
||||
|
||||
protected function output_concerns() {
|
||||
$concerns = array(
|
||||
'concerned_actions' => array(
|
||||
__( 'Related Hooks with Actions Attached', 'query-monitor' ),
|
||||
__( 'Action', 'query-monitor' ),
|
||||
),
|
||||
'concerned_filters' => array(
|
||||
__( 'Related Hooks with Filters Attached', 'query-monitor' ),
|
||||
__( 'Filter', 'query-monitor' ),
|
||||
),
|
||||
);
|
||||
|
||||
if ( empty( $this->collector->concerned_actions ) && empty( $this->collector->concerned_filters ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf(
|
||||
'<div class="qm qm-concerns" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
|
||||
esc_attr( $this->current_id . '-concerned_hooks' )
|
||||
);
|
||||
|
||||
echo '<table>';
|
||||
|
||||
printf(
|
||||
'<caption><h2 id="%1$s-caption">%2$s</h2></caption>',
|
||||
esc_attr( $this->current_id . '-concerned_hooks' ),
|
||||
sprintf(
|
||||
/* translators: %s: Panel name */
|
||||
esc_html__( '%s: Related Hooks with Filters or Actions Attached', 'query-monitor' ),
|
||||
esc_html( $this->name() )
|
||||
)
|
||||
);
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Hook', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Priority', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Callback', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $concerns as $key => $labels ) {
|
||||
if ( empty( $this->collector->$key ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QM_Output_Html_Hooks::output_hook_table( $this->collector->$key );
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
protected function before_debug_bar_output( $id = null, $name = null ) {
|
||||
if ( null === $id ) {
|
||||
$id = $this->collector->id();
|
||||
}
|
||||
if ( null === $name ) {
|
||||
$name = $this->name();
|
||||
}
|
||||
|
||||
printf(
|
||||
'<div class="qm qm-debug-bar" id="%1$s" role="tabpanel" aria-labelledby="%1$s-caption" tabindex="-1">',
|
||||
esc_attr( $id )
|
||||
);
|
||||
|
||||
printf(
|
||||
'<h2 class="qm-screen-reader-text" id="%1$s-caption">%2$s</h2>',
|
||||
esc_attr( $id ),
|
||||
esc_html( $name )
|
||||
);
|
||||
}
|
||||
|
||||
protected function after_debug_bar_output() {
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
protected function build_notice( $notice ) {
|
||||
$return = '<section>';
|
||||
$return .= '<div class="qm-notice">';
|
||||
$return .= '<p>';
|
||||
$return .= $notice;
|
||||
$return .= '</p>';
|
||||
$return .= '</div>';
|
||||
$return .= '</section>';
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
public static function output_inner( $vars ) {
|
||||
|
||||
echo '<table>';
|
||||
|
||||
foreach ( $vars as $key => $value ) {
|
||||
echo '<tr>';
|
||||
echo '<td>' . esc_html( $key ) . '</td>';
|
||||
if ( is_array( $value ) ) {
|
||||
echo '<td>';
|
||||
self::output_inner( $value );
|
||||
echo '</td>';
|
||||
} elseif ( is_object( $value ) ) {
|
||||
echo '<td>';
|
||||
self::output_inner( get_object_vars( $value ) );
|
||||
echo '</td>';
|
||||
} elseif ( is_bool( $value ) ) {
|
||||
if ( $value ) {
|
||||
echo '<td class="qm-true">true</td>';
|
||||
} else {
|
||||
echo '<td class="qm-false">false</td>';
|
||||
}
|
||||
} else {
|
||||
echo '<td>';
|
||||
echo nl2br( esc_html( $value ) );
|
||||
echo '</td>';
|
||||
}
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
echo '</table>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the table filter controls. Safe for output.
|
||||
*
|
||||
* @param string $name The name for the `data-` attributes that get filtered by this control.
|
||||
* @param string[] $values Option values for this control.
|
||||
* @param string $label Label text for the filter control.
|
||||
* @param array $args {
|
||||
* @type string $highlight The name for the `data-` attributes that get highlighted by this control.
|
||||
* @type array $prepend Associative array of options to prepend to the list of values.
|
||||
* @type array $append Associative array of options to append to the list of values.
|
||||
* }
|
||||
* @return string Markup for the table filter controls.
|
||||
*/
|
||||
protected function build_filter( $name, array $values, $label, $args = array() ) {
|
||||
|
||||
if ( empty( $values ) ) {
|
||||
return esc_html( $label ); // Return label text, without being marked up as a label element.
|
||||
}
|
||||
|
||||
if ( ! is_array( $args ) ) {
|
||||
$args = array(
|
||||
'highlight' => $args,
|
||||
);
|
||||
}
|
||||
|
||||
$args = array_merge( array(
|
||||
'highlight' => '',
|
||||
'prepend' => array(),
|
||||
'append' => array(),
|
||||
), $args );
|
||||
|
||||
$core_val = __( 'Core', 'query-monitor' );
|
||||
$core_key = array_search( $core_val, $values, true );
|
||||
|
||||
if ( 'component' === $name && count( $values ) > 1 && false !== $core_key ) {
|
||||
$args['append'][ $core_val ] = $core_val;
|
||||
$args['append']['non-core'] = __( 'Non-Core', 'query-monitor' );
|
||||
unset( $values[ $core_key ] );
|
||||
}
|
||||
|
||||
$filter_id = 'qm-filter-' . $this->collector->id . '-' . $name;
|
||||
|
||||
$out = '<div class="qm-filter-container">';
|
||||
$out .= '<label for="' . esc_attr( $filter_id ) . '">' . esc_html( $label ) . '</label>';
|
||||
$out .= '<select id="' . esc_attr( $filter_id ) . '" class="qm-filter" data-filter="' . esc_attr( $name ) . '" data-highlight="' . esc_attr( $args['highlight'] ) . '">';
|
||||
$out .= '<option value="">' . esc_html_x( 'All', '"All" option for filters', 'query-monitor' ) . '</option>';
|
||||
|
||||
if ( ! empty( $args['prepend'] ) ) {
|
||||
foreach ( $args['prepend'] as $value => $label ) {
|
||||
$out .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $values as $key => $value ) {
|
||||
if ( is_int( $key ) && $key >= 0 ) {
|
||||
$out .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $value ) . '</option>';
|
||||
} else {
|
||||
$out .= '<option value="' . esc_attr( $key ) . '">' . esc_html( $value ) . '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $args['append'] ) ) {
|
||||
foreach ( $args['append'] as $value => $label ) {
|
||||
$out .= '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
|
||||
}
|
||||
}
|
||||
|
||||
$out .= '</select>';
|
||||
$out .= '</div>';
|
||||
|
||||
return $out;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the column sorter controls. Safe for output.
|
||||
*
|
||||
* @param string $heading Heading text for the column. Optional.
|
||||
* @return string Markup for the column sorter controls.
|
||||
*/
|
||||
protected function build_sorter( $heading = '' ) {
|
||||
$out = '';
|
||||
$out .= '<label class="qm-th">';
|
||||
$out .= '<span class="qm-sort-heading">';
|
||||
|
||||
if ( '#' === $heading ) {
|
||||
$out .= '<span class="qm-screen-reader-text">' . esc_html__( 'Sequence', 'query-monitor' ) . '</span>';
|
||||
} elseif ( $heading ) {
|
||||
$out .= esc_html( $heading );
|
||||
}
|
||||
|
||||
$out .= '</span>';
|
||||
$out .= '<button class="qm-sort-controls" aria-label="' . esc_attr__( 'Sort data by this column', 'query-monitor' ) . '">';
|
||||
$out .= '<span class="qm-sort-arrow" aria-hidden="true"></span>';
|
||||
$out .= '</button>';
|
||||
$out .= '</label>';
|
||||
return $out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a toggle control. Safe for output.
|
||||
*
|
||||
* @return string Markup for the column sorter controls.
|
||||
*/
|
||||
protected static function build_toggler() {
|
||||
$out = '<button class="qm-toggle" data-on="+" data-off="-" aria-expanded="false" aria-label="' . esc_attr__( 'Toggle more information', 'query-monitor' ) . '"><span aria-hidden="true">+</span></button>';
|
||||
return $out;
|
||||
}
|
||||
|
||||
protected function menu( array $args ) {
|
||||
|
||||
return array_merge( array(
|
||||
'id' => esc_attr( "query-monitor-{$this->collector->id}" ),
|
||||
'href' => esc_attr( '#' . $this->collector->id() ),
|
||||
), $args );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given SQL string in a nicely presented format. Safe for output.
|
||||
*
|
||||
* @param string $sql An SQL query string.
|
||||
* @return string The SQL formatted with markup.
|
||||
*/
|
||||
public static function format_sql( $sql ) {
|
||||
|
||||
$sql = str_replace( array( "\r\n", "\r", "\n", "\t" ), ' ', $sql );
|
||||
$sql = esc_html( $sql );
|
||||
$sql = trim( $sql );
|
||||
|
||||
$regex = 'ADD|AFTER|ALTER|AND|BEGIN|COMMIT|CREATE|DELETE|DESCRIBE|DO|DROP|ELSE|END|EXCEPT|EXPLAIN|FROM|GROUP|HAVING|INNER|INSERT|INTERSECT|LEFT|LIMIT|ON|OR|ORDER|OUTER|RENAME|REPLACE|RIGHT|ROLLBACK|SELECT|SET|SHOW|START|THEN|TRUNCATE|UNION|UPDATE|USE|USING|VALUES|WHEN|WHERE|XOR';
|
||||
$sql = preg_replace( '# (' . $regex . ') #', '<br> $1 ', $sql );
|
||||
|
||||
$keywords = '\b(?:ACTION|ADD|AFTER|ALTER|AND|ASC|AS|AUTO_INCREMENT|BEGIN|BETWEEN|BIGINT|BINARY|BIT|BLOB|BOOLEAN|BOOL|BREAK|BY|CASE|COLLATE|COLUMNS?|COMMIT|CONTINUE|CREATE|DATA(?:BASES?)?|DATE(?:TIME)?|DECIMAL|DECLARE|DEC|DEFAULT|DELAYED|DELETE|DESCRIBE|DESC|DISTINCT|DOUBLE|DO|DROP|DUPLICATE|ELSE|END|ENUM|EXCEPT|EXISTS|EXPLAIN|FIELDS|FLOAT|FOREIGN|FOR|FROM|FULL|FUNCTION|GROUP|HAVING|IF|IGNORE|INDEX|INNER|INSERT|INTEGER|INTERSECT|INTERVAL|INTO|INT|IN|IS|JOIN|KEYS?|LEFT|LIKE|LIMIT|LONG(?:BLOB|TEXT)|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|NOT|NO|NULLIF|ON|ORDER|OR|OUTER|PRIMARY|PROC(?:EDURE)?|REGEXP|RENAME|REPLACE|RIGHT|RLIKE|ROLLBACK|SCHEMA|SELECT|SET|SHOW|SMALLINT|START|TABLES?|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TRUNCATE|UNION|UNIQUE|UNSIGNED|UPDATE|USE|USING|VALUES?|VAR(?:BINARY|CHAR)|WHEN|WHERE|WHILE|XOR)\b';
|
||||
$sql = preg_replace( '#' . $keywords . '#', '<b>$0</b>', $sql );
|
||||
|
||||
return '<code>' . $sql . '</code>';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given URL in a nicely presented format. Safe for output.
|
||||
*
|
||||
* @param string $url A URL.
|
||||
* @return string The URL formatted with markup.
|
||||
*/
|
||||
public static function format_url( $url ) {
|
||||
return str_replace( array( '?', '&' ), array( '<br>?', '<br>&' ), esc_html( $url ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a file path, name, and line number, or a clickable link to the file. Safe for output.
|
||||
*
|
||||
* @link https://querymonitor.com/blog/2019/02/clickable-stack-traces-and-function-names-in-query-monitor/
|
||||
*
|
||||
* @param string $text The display text, such as a function name or file name.
|
||||
* @param string $file The full file path and name.
|
||||
* @param int $line Optional. A line number, if appropriate.
|
||||
* @param bool $is_filename Optional. Is the text a plain file name? Default false.
|
||||
* @return string The fully formatted file link or file name, safe for output.
|
||||
*/
|
||||
public static function output_filename( $text, $file, $line = 0, $is_filename = false ) {
|
||||
if ( empty( $file ) ) {
|
||||
if ( $is_filename ) {
|
||||
return esc_html( $text );
|
||||
} else {
|
||||
return '<code>' . esc_html( $text ) . '</code>';
|
||||
}
|
||||
}
|
||||
|
||||
$link_line = ( $line ) ? $line : 1;
|
||||
|
||||
if ( ! self::has_clickable_links() ) {
|
||||
$fallback = QM_Util::standard_dir( $file, '' );
|
||||
if ( $line ) {
|
||||
$fallback .= ':' . $line;
|
||||
}
|
||||
if ( $is_filename ) {
|
||||
$return = esc_html( $text );
|
||||
} else {
|
||||
$return = '<code>' . esc_html( $text ) . '</code>';
|
||||
}
|
||||
if ( $fallback !== $text ) {
|
||||
$return .= '<br><span class="qm-info qm-supplemental">' . esc_html( $fallback ) . '</span>';
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
$map = self::get_file_path_map();
|
||||
|
||||
if ( ! empty( $map ) ) {
|
||||
foreach ( $map as $from => $to ) {
|
||||
$file = str_replace( $from, $to, $file );
|
||||
}
|
||||
}
|
||||
|
||||
$link = sprintf( self::get_file_link_format(), rawurlencode( $file ), intval( $link_line ) );
|
||||
|
||||
if ( $is_filename ) {
|
||||
$format = '<a href="%s" class="qm-edit-link">%s</a>';
|
||||
} else {
|
||||
$format = '<a href="%s" class="qm-edit-link"><code>%s</code></a>';
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
$format,
|
||||
esc_attr( $link ),
|
||||
esc_html( $text )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a protocol URL for edit links in QM stack traces for various editors.
|
||||
*
|
||||
* @param string $editor the chosen code editor
|
||||
* @param string $default_format a format to use if no editor is found
|
||||
*
|
||||
* @return string a protocol URL format
|
||||
*/
|
||||
public static function get_editor_file_link_format( $editor, $default_format ) {
|
||||
switch ( $editor ) {
|
||||
case 'phpstorm':
|
||||
return 'phpstorm://open?file=%f&line=%l';
|
||||
case 'vscode':
|
||||
return 'vscode://file/%f:%l';
|
||||
case 'atom':
|
||||
return 'atom://open/?url=file://%f&line=%l';
|
||||
case 'sublime':
|
||||
return 'subl://open/?url=file://%f&line=%l';
|
||||
case 'textmate':
|
||||
return 'txmt://open/?url=file://%f&line=%l';
|
||||
case 'netbeans':
|
||||
return 'nbopen://%f:%l';
|
||||
default:
|
||||
return $default_format;
|
||||
}
|
||||
}
|
||||
|
||||
public static function get_file_link_format() {
|
||||
if ( ! isset( self::$file_link_format ) ) {
|
||||
$format = ini_get( 'xdebug.file_link_format' );
|
||||
|
||||
if ( defined( 'QM_EDITOR_COOKIE' ) && isset( $_COOKIE[ QM_EDITOR_COOKIE ] ) ) {
|
||||
$format = self::get_editor_file_link_format(
|
||||
$_COOKIE[ QM_EDITOR_COOKIE ],
|
||||
$format
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the clickable file link format.
|
||||
*
|
||||
* @link https://querymonitor.com/blog/2019/02/clickable-stack-traces-and-function-names-in-query-monitor/
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string $format The format of the clickable file link.
|
||||
*/
|
||||
$format = apply_filters( 'qm/output/file_link_format', $format );
|
||||
if ( empty( $format ) ) {
|
||||
self::$file_link_format = false;
|
||||
} else {
|
||||
self::$file_link_format = str_replace( array( '%f', '%l' ), array( '%1$s', '%2$d' ), $format );
|
||||
}
|
||||
}
|
||||
|
||||
return self::$file_link_format;
|
||||
}
|
||||
|
||||
public static function get_file_path_map() {
|
||||
/**
|
||||
* Filters the file path mapping for clickable file links.
|
||||
*
|
||||
* @link https://querymonitor.com/blog/2019/02/clickable-stack-traces-and-function-names-in-query-monitor/
|
||||
* @since 3.0.0
|
||||
*
|
||||
* @param string[] $file_map Array of file path mappings. Keys are the source paths and values are the replacement paths.
|
||||
*/
|
||||
return apply_filters( 'qm/output/file_path_map', array() );
|
||||
}
|
||||
|
||||
public static function has_clickable_links() {
|
||||
return ( false !== self::get_file_link_format() );
|
||||
}
|
||||
|
||||
}
|
||||
58
wordpress_plugins/query-monitor/output/headers/overview.php
Normal file
58
wordpress_plugins/query-monitor/output/headers/overview.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* General overview output for HTTP headers.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Headers_Overview extends QM_Output_Headers {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Overview Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function get_output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$headers = array();
|
||||
|
||||
$headers['time_taken'] = number_format_i18n( $data['time_taken'], 4 );
|
||||
$headers['time_usage'] = sprintf(
|
||||
/* translators: 1: Percentage of time limit used, 2: Time limit in seconds */
|
||||
__( '%1$s%% of %2$ss limit', 'query-monitor' ),
|
||||
number_format_i18n( $data['time_usage'], 1 ),
|
||||
number_format_i18n( $data['time_limit'] )
|
||||
);
|
||||
|
||||
if ( ! empty( $data['memory'] ) ) {
|
||||
$headers['memory'] = sprintf(
|
||||
/* translators: %s: Memory used in kilobytes */
|
||||
__( '%s kB', 'query-monitor' ),
|
||||
number_format_i18n( $data['memory'] / 1024 )
|
||||
);
|
||||
$headers['memory_usage'] = sprintf(
|
||||
/* translators: 1: Percentage of memory limit used, 2: Memory limit in kilobytes */
|
||||
__( '%1$s%% of %2$s kB limit', 'query-monitor' ),
|
||||
number_format_i18n( $data['memory_usage'], 1 ),
|
||||
number_format_i18n( $data['memory_limit'] / 1024 )
|
||||
);
|
||||
}
|
||||
|
||||
return $headers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_headers_overview( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'overview' );
|
||||
if ( $collector ) {
|
||||
$output['overview'] = new QM_Output_Headers_Overview( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/headers', 'register_qm_output_headers_overview', 10, 2 );
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP error output for HTTP headers.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
class QM_Output_Headers_PHP_Errors extends QM_Output_Headers {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_PHP_Errors Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function get_output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$headers = array();
|
||||
|
||||
if ( empty( $data['errors'] ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$count = 0;
|
||||
|
||||
foreach ( $data['errors'] as $type => $errors ) {
|
||||
|
||||
foreach ( $errors as $error_key => $error ) {
|
||||
|
||||
$count++;
|
||||
|
||||
# @TODO we should calculate the component during process() so we don't need to do it
|
||||
# separately in each output.
|
||||
if ( $error['trace'] ) {
|
||||
$component = $error['trace']->get_component()->name;
|
||||
$stack = $error['trace']->get_stack();
|
||||
} else {
|
||||
$component = __( 'Unknown', 'query-monitor' );
|
||||
$stack = array();
|
||||
}
|
||||
|
||||
$output_error = array(
|
||||
'key' => $error_key,
|
||||
'type' => $error['type'],
|
||||
'message' => $error['message'],
|
||||
'file' => QM_Util::standard_dir( $error['file'], '' ),
|
||||
'line' => $error['line'],
|
||||
'stack' => $stack,
|
||||
'component' => $component,
|
||||
);
|
||||
|
||||
$key = sprintf( 'error-%d', $count );
|
||||
$headers[ $key ] = json_encode( $output_error );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
array(
|
||||
'error-count' => $count,
|
||||
),
|
||||
$headers
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_headers_php_errors( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'php_errors' );
|
||||
if ( $collector ) {
|
||||
$output['php_errors'] = new QM_Output_Headers_PHP_Errors( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/headers', 'register_qm_output_headers_php_errors', 110, 2 );
|
||||
40
wordpress_plugins/query-monitor/output/headers/redirects.php
Normal file
40
wordpress_plugins/query-monitor/output/headers/redirects.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP redirects output for HTTP headers.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
class QM_Output_Headers_Redirects extends QM_Output_Headers {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Redirects Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function get_output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$headers = array();
|
||||
|
||||
if ( empty( $data['trace'] ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$headers['Redirect-Trace'] = implode( ', ', $data['trace']->get_stack() );
|
||||
return $headers;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_headers_redirects( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'redirects' );
|
||||
if ( $collector ) {
|
||||
$output['redirects'] = new QM_Output_Headers_Redirects( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/headers', 'register_qm_output_headers_redirects', 140, 2 );
|
||||
123
wordpress_plugins/query-monitor/output/html/admin.php
Normal file
123
wordpress_plugins/query-monitor/output/html/admin.php
Normal file
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
/**
|
||||
* Admin screen output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Admin extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Admin Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 60 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Admin Screen', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['current_screen'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>get_current_screen()</h3>';
|
||||
|
||||
echo '<table>';
|
||||
echo '<thead class="qm-screen-reader-text">';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Property', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Value', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['current_screen'] as $key => $value ) {
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html( $key ) . '</th>';
|
||||
echo '<td>' . esc_html( $value ) . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
echo '</section>';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Globals', 'query-monitor' ) . '</h3>';
|
||||
echo '<table>';
|
||||
echo '<thead class="qm-screen-reader-text">';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Global Variable', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Value', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
echo '<tbody>';
|
||||
|
||||
$admin_globals = array(
|
||||
'pagenow',
|
||||
'typenow',
|
||||
'taxnow',
|
||||
'hook_suffix',
|
||||
);
|
||||
|
||||
foreach ( $admin_globals as $key ) {
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">$' . esc_html( $key ) . '</th>';
|
||||
echo '<td>' . esc_html( $data[ $key ] ) . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
echo '</section>';
|
||||
|
||||
if ( ! empty( $data['list_table'] ) ) {
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'List Table', 'query-monitor' ) . '</h3>';
|
||||
|
||||
if ( ! empty( $data['list_table']['class_name'] ) ) {
|
||||
echo '<h4>' . esc_html__( 'Class:', 'query-monitor' ) . '</h4>';
|
||||
echo '<p><code>' . esc_html( $data['list_table']['class_name'] ) . '</code></p>';
|
||||
}
|
||||
|
||||
echo '<h4>' . esc_html__( 'Column Filters:', 'query-monitor' ) . '</h4>';
|
||||
echo '<p><code>' . esc_html( $data['list_table']['columns_filter'] ) . '</code></p>';
|
||||
echo '<p><code>' . esc_html( $data['list_table']['sortables_filter'] ) . '</code></p>';
|
||||
echo '<h4>' . esc_html__( 'Column Action:', 'query-monitor' ) . '</h4>';
|
||||
echo '<p><code>' . esc_html( $data['list_table']['column_action'] ) . '</code></p>';
|
||||
echo '</section>';
|
||||
|
||||
}
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_admin( array $output, QM_Collectors $collectors ) {
|
||||
if ( ! is_admin() ) {
|
||||
return $output;
|
||||
}
|
||||
$collector = QM_Collectors::get( 'response' );
|
||||
if ( $collector ) {
|
||||
$output['response'] = new QM_Output_Html_Admin( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_admin', 70, 2 );
|
||||
240
wordpress_plugins/query-monitor/output/html/assets.php
Normal file
240
wordpress_plugins/query-monitor/output/html/assets.php
Normal file
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
/**
|
||||
* Scripts and styles output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
abstract class QM_Output_Html_Assets extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Assets Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 70 );
|
||||
add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
|
||||
}
|
||||
|
||||
abstract public function get_type_labels();
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['assets'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$position_labels = array(
|
||||
// @TODO translator comments or context:
|
||||
'missing' => __( 'Missing', 'query-monitor' ),
|
||||
'broken' => __( 'Missing Dependencies', 'query-monitor' ),
|
||||
'header' => __( 'Header', 'query-monitor' ),
|
||||
'footer' => __( 'Footer', 'query-monitor' ),
|
||||
);
|
||||
|
||||
$type_label = $this->get_type_labels();
|
||||
$this->type = $this->collector->get_dependency_type();
|
||||
|
||||
$hosts = array(
|
||||
__( 'Other', 'query-monitor' ),
|
||||
);
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Position', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Handle', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
$args = array(
|
||||
'prepend' => array(
|
||||
'local' => $data['host'],
|
||||
),
|
||||
);
|
||||
echo $this->build_filter( $this->type . '-host', $hosts, __( 'Host', 'query-monitor' ), $args ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Source', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( $this->type . '-dependencies', $data['dependencies'], __( 'Dependencies', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( $this->type . '-dependents', $data['dependents'], __( 'Dependents', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $position_labels as $position => $label ) {
|
||||
if ( ! empty( $data['assets'][ $position ] ) ) {
|
||||
foreach ( $data['assets'][ $position ] as $handle => $asset ) {
|
||||
$this->dependency_row( $handle, $asset, $label );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
echo '<tfoot>';
|
||||
|
||||
echo '<tr>';
|
||||
printf(
|
||||
'<td colspan="7">%1$s</td>',
|
||||
sprintf(
|
||||
esc_html( $type_label['total'] ),
|
||||
'<span class="qm-items-number">' . esc_html( number_format_i18n( $data['counts']['total'] ) ) . '</span>'
|
||||
)
|
||||
);
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
protected function dependency_row( $handle, array $asset, $label ) {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$highlight_deps = array_map( array( $this, '_prefix_type' ), $asset['dependencies'] );
|
||||
$highlight_dependents = array_map( array( $this, '_prefix_type' ), $asset['dependents'] );
|
||||
|
||||
$dependencies_list = implode( ' ', $asset['dependencies'] );
|
||||
$dependents_list = implode( ' ', $asset['dependents'] );
|
||||
|
||||
$dependency_output = array();
|
||||
|
||||
foreach ( $asset['dependencies'] as $dep ) {
|
||||
if ( isset( $data['missing_dependencies'][ $dep ] ) ) {
|
||||
$dependency_output[] = sprintf(
|
||||
'<span style="white-space:nowrap"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%s</span>',
|
||||
sprintf(
|
||||
/* translators: %s: Name of missing script or style dependency */
|
||||
__( '%s (missing)', 'query-monitor' ),
|
||||
esc_html( $dep )
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$dependency_output[] = $dep;
|
||||
}
|
||||
}
|
||||
|
||||
$qm_host = ( $asset['local'] ) ? 'local' : __( 'Other', 'query-monitor' );
|
||||
|
||||
$class = '';
|
||||
|
||||
if ( $asset['warning'] ) {
|
||||
$class = 'qm-warn';
|
||||
}
|
||||
|
||||
echo '<tr data-qm-subject="' . esc_attr( $this->type . '-' . $handle ) . '" data-qm-' . esc_attr( $this->type ) . '-host="' . esc_attr( $qm_host ) . '" data-qm-' . esc_attr( $this->type ) . '-dependents="' . esc_attr( $dependents_list ) . '" data-qm-' . esc_attr( $this->type ) . '-dependencies="' . esc_attr( $dependencies_list ) . '" class="' . esc_attr( $class ) . '">';
|
||||
echo '<td class="qm-nowrap">';
|
||||
|
||||
if ( $asset['warning'] ) {
|
||||
echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
}
|
||||
|
||||
echo esc_html( $label );
|
||||
echo '</td>';
|
||||
|
||||
$host = $asset['host'];
|
||||
$parts = explode( '.', $host );
|
||||
|
||||
foreach ( $parts as $k => $part ) {
|
||||
if ( strlen( $part ) > 16 ) {
|
||||
$parts[ $k ] = substr( $parts[ $k ], 0, 6 ) . '…' . substr( $parts[ $k ], -6 );
|
||||
}
|
||||
}
|
||||
|
||||
$host = implode( '.', $parts );
|
||||
|
||||
echo '<td class="qm-nowrap qm-ltr">' . esc_html( $handle ) . '</td>';
|
||||
echo '<td class="qm-nowrap qm-ltr">' . esc_html( $host ) . '</td>';
|
||||
echo '<td class="qm-ltr">';
|
||||
if ( is_wp_error( $asset['source'] ) ) {
|
||||
$error_data = $asset['source']->get_error_data();
|
||||
if ( $error_data && isset( $error_data['src'] ) ) {
|
||||
printf(
|
||||
'<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%1$s:</span><br><a href="%2$s" class="qm-link">%2$s</a>',
|
||||
esc_html( $asset['source']->get_error_message() ),
|
||||
esc_url( $error_data['src'] )
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
'<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%s</span>',
|
||||
esc_html( $asset['source']->get_error_message() )
|
||||
);
|
||||
}
|
||||
} elseif ( ! empty( $asset['source'] ) ) {
|
||||
printf(
|
||||
'<a href="%s" class="qm-link">%s</a>',
|
||||
esc_url( $asset['source'] ),
|
||||
esc_html( $asset['display'] )
|
||||
);
|
||||
}
|
||||
echo '</td>';
|
||||
echo '<td class="qm-ltr qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $highlight_deps ) ) . '">';
|
||||
|
||||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo implode( ', ', $dependency_output );
|
||||
|
||||
echo '</td>';
|
||||
echo '<td class="qm-ltr qm-highlighter" data-qm-highlight="' . esc_attr( implode( ' ', $highlight_dependents ) ) . '">' . implode( ', ', array_map( 'esc_html', $asset['dependents'] ) ) . '</td>';
|
||||
echo '<td class="qm-ltr">' . esc_html( $asset['ver'] ) . '</td>';
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
public function _prefix_type( $val ) {
|
||||
return $this->type . '-' . $val;
|
||||
}
|
||||
|
||||
public function admin_class( array $class ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( ! empty( $data['broken'] ) || ! empty( $data['missing'] ) ) {
|
||||
$class[] = 'qm-error';
|
||||
}
|
||||
|
||||
return $class;
|
||||
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['assets'] ) ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$type_label = $this->get_type_labels();
|
||||
$label = sprintf(
|
||||
$type_label['count'],
|
||||
number_format_i18n( $data['counts']['total'] )
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'title' => esc_html( $label ),
|
||||
'id' => esc_attr( "query-monitor-{$this->collector->id}" ),
|
||||
'href' => esc_attr( '#' . $this->collector->id() ),
|
||||
);
|
||||
|
||||
if ( ! empty( $data['broken'] ) || ! empty( $data['missing'] ) ) {
|
||||
$args['meta']['classname'] = 'qm-error';
|
||||
}
|
||||
|
||||
$id = $this->collector->id();
|
||||
$menu[ $id ] = $this->menu( $args );
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Enqueued scripts output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Assets_Scripts extends QM_Output_Html_Assets {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Assets_Scripts Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function name() {
|
||||
return __( 'Scripts', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function get_type_labels() {
|
||||
return array(
|
||||
/* translators: %s: Total number of enqueued scripts */
|
||||
'total' => _x( 'Total: %s', 'Enqueued scripts', 'query-monitor' ),
|
||||
'plural' => __( 'Scripts', 'query-monitor' ),
|
||||
/* translators: %s: Total number of enqueued scripts */
|
||||
'count' => _x( 'Scripts (%s)', 'Enqueued scripts', 'query-monitor' ),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_assets_scripts( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'assets_scripts' );
|
||||
if ( $collector ) {
|
||||
$output['assets_scripts'] = new QM_Output_Html_Assets_Scripts( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_assets_scripts', 80, 2 );
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* Enqueued styles output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Assets_Styles extends QM_Output_Html_Assets {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Assets_Styles Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function name() {
|
||||
return __( 'Styles', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function get_type_labels() {
|
||||
return array(
|
||||
/* translators: %s: Total number of enqueued styles */
|
||||
'total' => _x( 'Total: %s', 'Enqueued styles', 'query-monitor' ),
|
||||
'plural' => __( 'Styles', 'query-monitor' ),
|
||||
/* translators: %s: Total number of enqueued styles */
|
||||
'count' => _x( 'Styles (%s)', 'Enqueued styles', 'query-monitor' ),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_assets_styles( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'assets_styles' );
|
||||
if ( $collector ) {
|
||||
$output['assets_styles'] = new QM_Output_Html_Assets_Styles( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_assets_styles', 80, 2 );
|
||||
283
wordpress_plugins/query-monitor/output/html/block_editor.php
Normal file
283
wordpress_plugins/query-monitor/output/html/block_editor.php
Normal file
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
/**
|
||||
* Block editor data output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Block_Editor extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Block_Editor Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 55 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Blocks', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['block_editor_enabled'] ) || empty( $data['post_blocks'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! $data['post_has_blocks'] ) {
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
$notice = __( 'This post contains no blocks.', 'query-monitor' );
|
||||
echo $this->build_notice( $notice ); // WPCS: XSS ok.
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">#</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Block Name', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Attributes', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Render Callback', 'query-monitor' ) . '</th>';
|
||||
|
||||
if ( isset( $data['has_block_timing'] ) ) {
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Render Time', 'query-monitor' ) . '</th>';
|
||||
}
|
||||
|
||||
echo '<th scope="col">' . esc_html__( 'Inner HTML', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['post_blocks'] as $i => $block ) {
|
||||
self::render_block( ++$i, $block, $data );
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
echo '<tfoot>';
|
||||
echo '<tr>';
|
||||
printf(
|
||||
'<td colspan="6">%s</td>',
|
||||
sprintf(
|
||||
/* translators: %s: Total number of content blocks used */
|
||||
esc_html( _nx( 'Total: %s', 'Total: %s', $data['total_blocks'], 'Content blocks used', 'query-monitor' ) ),
|
||||
'<span class="qm-items-number">' . esc_html( number_format_i18n( $data['total_blocks'] ) ) . '</span>'
|
||||
)
|
||||
);
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
protected static function render_block( $i, array $block, array $data ) {
|
||||
$block_error = false;
|
||||
$row_class = '';
|
||||
$referenced_post = null;
|
||||
$referenced_type = null;
|
||||
$referenced_pto = null;
|
||||
$error_message = null;
|
||||
|
||||
if ( 'core/block' === $block['blockName'] && ! empty( $block['attrs']['ref'] ) ) {
|
||||
$referenced_post = get_post( $block['attrs']['ref'] );
|
||||
|
||||
if ( ! $referenced_post ) {
|
||||
$block_error = true;
|
||||
$error_message = esc_html__( 'Referenced block does not exist.', 'query-monitor' );
|
||||
} else {
|
||||
$referenced_type = $referenced_post->post_type;
|
||||
$referenced_pto = get_post_type_object( $referenced_type );
|
||||
if ( 'wp_block' !== $referenced_type ) {
|
||||
$block_error = true;
|
||||
$error_message = sprintf(
|
||||
/* translators: %1$s: Erroneous post type name, %2$s: WordPress block post type name */
|
||||
esc_html__( 'Referenced post is of type %1$s instead of %2$s.', 'query-monitor' ),
|
||||
'<code>' . esc_html( $referenced_type ) . '</code>',
|
||||
'<code>wp_block</code>'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$media_blocks = array(
|
||||
'core/audio' => 'id',
|
||||
'core/cover-image' => 'id',
|
||||
'core/file' => 'id',
|
||||
'core/image' => 'id',
|
||||
'core/media-text' => 'mediaId', // (╯°□°)╯︵ ┻━┻
|
||||
'core/video' => 'id',
|
||||
);
|
||||
|
||||
if ( isset( $media_blocks[ $block['blockName'] ] ) && is_array( $block['attrs'] ) && ! empty( $block['attrs'][ $media_blocks[ $block['blockName'] ] ] ) ) {
|
||||
$referenced_post = get_post( $block['attrs'][ $media_blocks[ $block['blockName'] ] ] );
|
||||
|
||||
if ( ! $referenced_post ) {
|
||||
$block_error = true;
|
||||
$error_message = esc_html__( 'Referenced media does not exist.', 'query-monitor' );
|
||||
} else {
|
||||
$referenced_type = $referenced_post->post_type;
|
||||
$referenced_pto = get_post_type_object( $referenced_type );
|
||||
if ( 'attachment' !== $referenced_type ) {
|
||||
$block_error = true;
|
||||
$error_message = sprintf(
|
||||
/* translators: %1$s: Erroneous post type name, %2$s: WordPress attachment post type name */
|
||||
esc_html__( 'Referenced media is of type %1$s instead of %2$s.', 'query-monitor' ),
|
||||
'<code>' . esc_html( $referenced_type ) . '</code>',
|
||||
'<code>attachment</code>'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $block_error ) {
|
||||
$row_class = 'qm-warn';
|
||||
}
|
||||
|
||||
echo '<tr class="' . esc_attr( $row_class ) . '">';
|
||||
|
||||
echo '<th scope="row" class="qm-row-num qm-num"><span class="qm-sticky">' . esc_html( $i ) . '</span></th>';
|
||||
|
||||
echo '<td class="qm-row-block-name"><span class="qm-sticky">';
|
||||
|
||||
if ( $block['blockName'] ) {
|
||||
echo esc_html( $block['blockName'] );
|
||||
} else {
|
||||
echo '<em>' . esc_html__( 'None (Classic block)', 'query-monitor' ) . '</em>';
|
||||
}
|
||||
|
||||
if ( $error_message ) {
|
||||
echo '<br>';
|
||||
echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
echo $error_message; // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
if ( ! empty( $referenced_post ) && ! empty( $referenced_pto ) ) {
|
||||
echo '<br>';
|
||||
echo '<a href="' . esc_url( get_edit_post_link( $referenced_post ) ) . '" class="qm-link">' . esc_html( $referenced_pto->labels->edit_item ) . '</a>';
|
||||
}
|
||||
|
||||
echo '</span></td>';
|
||||
|
||||
echo '<td class="qm-row-block-attrs">';
|
||||
if ( $block['attrs'] && is_array( $block['attrs'] ) ) {
|
||||
echo '<pre class="qm-pre-wrap"><code>' . esc_html( QM_Util::json_format( $block['attrs'] ) ) . '</code></pre>';
|
||||
}
|
||||
echo '</td>';
|
||||
|
||||
if ( isset( $block['callback']['error'] ) ) {
|
||||
$class = ' qm-warn';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
|
||||
if ( $block['dynamic'] ) {
|
||||
if ( isset( $block['callback']['file'] ) ) {
|
||||
if ( self::has_clickable_links() ) {
|
||||
echo '<td class="qm-nowrap qm-ltr' . esc_attr( $class ) . '">';
|
||||
echo self::output_filename( $block['callback']['name'], $block['callback']['file'], $block['callback']['line'] ); // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-nowrap qm-ltr qm-has-toggle' . esc_attr( $class ) . '">';
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<ol>';
|
||||
echo '<li>';
|
||||
echo self::output_filename( $block['callback']['name'], $block['callback']['file'], $block['callback']['line'] ); // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
echo '</ol></td>';
|
||||
}
|
||||
} else {
|
||||
echo '<td class="qm-ltr qm-nowrap' . esc_attr( $class ) . '">';
|
||||
echo '<code>' . esc_html( $block['callback']['name'] ) . '</code>';
|
||||
|
||||
if ( isset( $block['callback']['error'] ) ) {
|
||||
echo '<br><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
echo esc_html( sprintf(
|
||||
/* translators: %s: Error message text */
|
||||
__( 'Error: %s', 'query-monitor' ),
|
||||
$block['callback']['error']->get_error_message()
|
||||
) );
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
if ( $data['has_block_timing'] ) {
|
||||
echo '<td class="qm-num">';
|
||||
if ( isset( $block['timing'] ) ) {
|
||||
echo esc_html( number_format_i18n( $block['timing'], 4 ) );
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
} else {
|
||||
echo '<td></td>';
|
||||
|
||||
if ( $data['has_block_timing'] ) {
|
||||
echo '<td></td>';
|
||||
}
|
||||
}
|
||||
|
||||
$inner_html = $block['innerHTML'];
|
||||
|
||||
if ( $block['size'] > 300 ) {
|
||||
echo '<td class="qm-ltr qm-has-toggle qm-row-block-html">';
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<div class="qm-inverse-toggled"><pre class="qm-pre-wrap"><code>';
|
||||
echo esc_html( substr( $inner_html, 0, 200 ) ) . ' …';
|
||||
echo '</code></pre></div>';
|
||||
echo '<div class="qm-toggled"><pre class="qm-pre-wrap"><code>';
|
||||
echo esc_html( $inner_html );
|
||||
echo '</code></pre></div>';
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-row-block-html"><pre class="qm-pre-wrap"><code>';
|
||||
echo esc_html( $inner_html );
|
||||
echo '</code></pre></td>';
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
if ( ! empty( $block['innerBlocks'] ) ) {
|
||||
foreach ( $block['innerBlocks'] as $j => $inner_block ) {
|
||||
$x = ++$j;
|
||||
self::render_block( "{$i}.{$x}", $inner_block, $data );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['block_editor_enabled'] ) || empty( $data['post_blocks'] ) ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html__( 'Blocks', 'query-monitor' ),
|
||||
) );
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_block_editor( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'block_editor' );
|
||||
if ( $collector ) {
|
||||
$output['block_editor'] = new QM_Output_Html_Block_Editor( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_block_editor', 60, 2 );
|
||||
223
wordpress_plugins/query-monitor/output/html/caps.php
Normal file
223
wordpress_plugins/query-monitor/output/html/caps.php
Normal file
@@ -0,0 +1,223 @@
|
||||
<?php
|
||||
/**
|
||||
* User capability checks output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Caps extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Caps Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 105 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Capability Checks', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$collector = $this->collector;
|
||||
|
||||
if ( ! $collector::enabled() ) {
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<section>';
|
||||
echo '<div class="qm-notice">';
|
||||
echo '<p>';
|
||||
printf(
|
||||
/* translators: %s: Configuration file name. */
|
||||
esc_html__( 'For performance reasons, this panel is not enabled by default. To enable it, add the following code to your %s file:', 'query-monitor' ),
|
||||
'<code>wp-config.php</code>'
|
||||
);
|
||||
echo '</p>';
|
||||
echo "<p><code>define( 'QM_ENABLE_CAPS_PANEL', true );</code></p>";
|
||||
echo '</div>';
|
||||
echo '</section>';
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( ! empty( $data['caps'] ) ) {
|
||||
$this->before_tabular_output();
|
||||
|
||||
$results = array(
|
||||
'true',
|
||||
'false',
|
||||
);
|
||||
$show_user = ( count( $data['users'] ) > 1 );
|
||||
$parts = $data['parts'];
|
||||
$components = $data['components'];
|
||||
|
||||
usort( $parts, 'strcasecmp' );
|
||||
usort( $components, 'strcasecmp' );
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'name', $parts, __( 'Capability Check', 'query-monitor' ) ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
|
||||
$users = $data['users'];
|
||||
|
||||
usort( $users, 'strcasecmp' );
|
||||
|
||||
echo '<th scope="col" class="qm-filterable-column qm-num">';
|
||||
echo $this->build_filter( 'user', $users, __( 'User', 'query-monitor' ) ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'result', $results, __( 'Result', 'query-monitor' ) ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'component', $components, __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['caps'] as $row ) {
|
||||
$component = $row['component'];
|
||||
|
||||
$row_attr = array();
|
||||
$row_attr['data-qm-name'] = implode( ' ', $row['parts'] );
|
||||
$row_attr['data-qm-user'] = $row['user'];
|
||||
$row_attr['data-qm-component'] = $component->name;
|
||||
$row_attr['data-qm-result'] = ( $row['result'] ) ? 'true' : 'false';
|
||||
|
||||
if ( 'core' !== $component->context ) {
|
||||
$row_attr['data-qm-component'] .= ' non-core';
|
||||
}
|
||||
|
||||
if ( '' === $row['name'] ) {
|
||||
$row_attr['class'] = 'qm-warn';
|
||||
}
|
||||
|
||||
$attr = '';
|
||||
|
||||
foreach ( $row_attr as $a => $v ) {
|
||||
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
||||
}
|
||||
|
||||
printf( // WPCS: XSS ok.
|
||||
'<tr %s>',
|
||||
$attr
|
||||
);
|
||||
|
||||
$name = esc_html( $row['name'] );
|
||||
|
||||
if ( ! empty( $row['args'] ) ) {
|
||||
foreach ( $row['args'] as $arg ) {
|
||||
$name .= ', ' . esc_html( QM_Util::display_variable( $arg ) );
|
||||
}
|
||||
}
|
||||
|
||||
printf( // WPCS: XSS ok.
|
||||
'<td class="qm-ltr qm-nowrap"><code>%s</code></td>',
|
||||
$name
|
||||
);
|
||||
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( $row['user'] )
|
||||
);
|
||||
|
||||
$result = ( $row['result'] ) ? '<span class="qm-true">true ✓</span>' : 'false';
|
||||
printf( // WPCS: XSS ok.
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
$result
|
||||
);
|
||||
|
||||
$stack = array();
|
||||
|
||||
foreach ( $row['filtered_trace'] as $item ) {
|
||||
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
||||
}
|
||||
|
||||
$caller = array_shift( $stack );
|
||||
|
||||
echo '<td class="qm-has-toggle qm-nowrap qm-ltr">';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
echo '<ol>';
|
||||
|
||||
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
||||
}
|
||||
|
||||
echo '</ol></td>';
|
||||
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
esc_html( $component->name )
|
||||
);
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
echo '<tfoot>';
|
||||
|
||||
$count = count( $data['caps'] );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td colspan="5">';
|
||||
printf(
|
||||
/* translators: %s: Number of user capability checks */
|
||||
esc_html( _nx( 'Total: %s', 'Total: %s', $count, 'User capability checks', 'query-monitor' ) ),
|
||||
'<span class="qm-items-number">' . esc_html( number_format_i18n( $count ) ) . '</span>'
|
||||
);
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
} else {
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
$notice = __( 'No capability checks were recorded.', 'query-monitor' );
|
||||
echo $this->build_notice( $notice ); // WPCS: XSS ok.
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => $this->name(),
|
||||
) );
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_caps( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'caps' );
|
||||
if ( $collector ) {
|
||||
$output['caps'] = new QM_Output_Html_Caps( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_caps', 105, 2 );
|
||||
107
wordpress_plugins/query-monitor/output/html/conditionals.php
Normal file
107
wordpress_plugins/query-monitor/output/html/conditionals.php
Normal file
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
/**
|
||||
* Template conditionals output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Conditionals extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Conditionals Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 1000 );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 1000 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Conditionals', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'True Conditionals', 'query-monitor' ) . '</h3>';
|
||||
|
||||
echo '<ul>';
|
||||
foreach ( $data['conds']['true'] as $cond ) {
|
||||
echo '<li class="qm-ltr qm-true"><code>' . esc_html( $cond ) . '() </code></li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
|
||||
echo '</section>';
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="qm-boxed">';
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'False Conditionals', 'query-monitor' ) . '</h3>';
|
||||
|
||||
echo '<ul>';
|
||||
foreach ( $data['conds']['false'] as $cond ) {
|
||||
echo '<li class="qm-ltr qm-false"><code>' . esc_html( $cond ) . '() </code></li>';
|
||||
}
|
||||
echo '</ul>';
|
||||
|
||||
echo '</section>';
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
foreach ( $data['conds']['true'] as $cond ) {
|
||||
$id = $this->collector->id() . '-' . $cond;
|
||||
$menu[ $id ] = $this->menu( array(
|
||||
'title' => esc_html( $cond . '()' ),
|
||||
'id' => 'query-monitor-conditionals-' . esc_attr( $cond ),
|
||||
'meta' => array(
|
||||
'classname' => 'qm-true qm-ltr',
|
||||
),
|
||||
) );
|
||||
}
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
foreach ( $data['conds']['true'] as $cond ) {
|
||||
$id = $this->collector->id() . '-' . $cond;
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html__( 'Conditionals', 'query-monitor' ),
|
||||
'id' => 'query-monitor-conditionals',
|
||||
) );
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_conditionals( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'conditionals' );
|
||||
if ( $collector ) {
|
||||
$output['conditionals'] = new QM_Output_Html_Conditionals( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_conditionals', 50, 2 );
|
||||
131
wordpress_plugins/query-monitor/output/html/db_callers.php
Normal file
131
wordpress_plugins/query-monitor/output/html/db_callers.php
Normal file
@@ -0,0 +1,131 @@
|
||||
<?php
|
||||
/**
|
||||
* Database query calling function output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_DB_Callers extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_DB_Callers Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 30 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Queries by Caller', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['types'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$total_time = 0;
|
||||
|
||||
if ( ! empty( $data['times'] ) ) {
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
|
||||
foreach ( $data['types'] as $type_name => $type_count ) {
|
||||
echo '<th scope="col" class="qm-num qm-ltr qm-sortable-column" role="columnheader" aria-sort="none">';
|
||||
echo $this->build_sorter( $type_name ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
}
|
||||
|
||||
echo '<th scope="col" class="qm-num qm-sorted-desc qm-sortable-column" role="columnheader" aria-sort="descending">';
|
||||
echo $this->build_sorter( __( 'Time', 'query-monitor' ) ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['times'] as $row ) {
|
||||
$total_time += $row['ltime'];
|
||||
$stime = number_format_i18n( $row['ltime'], 4 );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td class="qm-ltr"><button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="' . esc_attr( $row['caller'] ) . '"><code>' . esc_html( $row['caller'] ) . '</code></button></td>';
|
||||
|
||||
foreach ( $data['types'] as $type_name => $type_count ) {
|
||||
if ( isset( $row['types'][ $type_name ] ) ) {
|
||||
echo "<td class='qm-num'>" . esc_html( number_format_i18n( $row['types'][ $type_name ] ) ) . '</td>';
|
||||
} else {
|
||||
echo "<td class='qm-num'></td>";
|
||||
}
|
||||
}
|
||||
|
||||
echo '<td class="qm-num" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">' . esc_html( $stime ) . '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '<tfoot>';
|
||||
|
||||
$total_stime = number_format_i18n( $total_time, 4 );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td></td>';
|
||||
|
||||
foreach ( $data['types'] as $type_name => $type_count ) {
|
||||
echo '<td class="qm-num">' . esc_html( number_format_i18n( $type_count ) ) . '</td>';
|
||||
}
|
||||
|
||||
echo '<td class="qm-num">' . esc_html( $total_stime ) . '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
} else {
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<div class="qm-none">';
|
||||
echo '<p>' . esc_html__( 'None', 'query-monitor' ) . '</p>';
|
||||
echo '</div>';
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
$dbq = QM_Collectors::get( 'db_queries' );
|
||||
|
||||
if ( $dbq ) {
|
||||
$dbq_data = $dbq->get_data();
|
||||
if ( isset( $dbq_data['times'] ) ) {
|
||||
$menu['qm-db_queries-$wpdb']['children'][] = $this->menu( array(
|
||||
'title' => esc_html__( 'Queries by Caller', 'query-monitor' ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_db_callers( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'db_callers' );
|
||||
if ( $collector ) {
|
||||
$output['db_callers'] = new QM_Output_Html_DB_Callers( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_db_callers', 30, 2 );
|
||||
128
wordpress_plugins/query-monitor/output/html/db_components.php
Normal file
128
wordpress_plugins/query-monitor/output/html/db_components.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
/**
|
||||
* Database query calling component output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_DB_Components extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_DB_Components Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 40 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Queries by Component', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['types'] ) || empty( $data['times'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$total_time = 0;
|
||||
$span = count( $data['types'] ) + 2;
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
||||
|
||||
foreach ( $data['types'] as $type_name => $type_count ) {
|
||||
echo '<th scope="col" class="qm-num qm-sortable-column" role="columnheader" aria-sort="none">';
|
||||
echo $this->build_sorter( $type_name ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
}
|
||||
|
||||
echo '<th scope="col" class="qm-num qm-sorted-desc qm-sortable-column" role="columnheader" aria-sort="descending">';
|
||||
echo $this->build_sorter( __( 'Time', 'query-monitor' ) ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['times'] as $row ) {
|
||||
$total_time += $row['ltime'];
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td class="qm-row-component"><button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="component" data-qm-value="' . esc_attr( $row['component'] ) . '">' . esc_html( $row['component'] ) . '</button></td>';
|
||||
|
||||
foreach ( $data['types'] as $type_name => $type_count ) {
|
||||
if ( isset( $row['types'][ $type_name ] ) ) {
|
||||
echo '<td class="qm-num">' . esc_html( number_format_i18n( $row['types'][ $type_name ] ) ) . '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-num"> </td>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '<td class="qm-num" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">' . esc_html( number_format_i18n( $row['ltime'], 4 ) ) . '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '<tfoot>';
|
||||
|
||||
$total_stime = number_format_i18n( $total_time, 4 );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td> </td>';
|
||||
|
||||
foreach ( $data['types'] as $type_name => $type_count ) {
|
||||
echo '<td class="qm-num">' . esc_html( number_format_i18n( $type_count ) ) . '</td>';
|
||||
}
|
||||
|
||||
echo '<td class="qm-num">' . esc_html( $total_stime ) . '</td>';
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['types'] ) || empty( $data['times'] ) ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$dbq = QM_Collectors::get( 'db_queries' );
|
||||
|
||||
if ( $dbq ) {
|
||||
$dbq_data = $dbq->get_data();
|
||||
if ( isset( $dbq_data['component_times'] ) ) {
|
||||
$menu['qm-db_queries-$wpdb']['children'][] = $this->menu( array(
|
||||
'title' => esc_html__( 'Queries by Component', 'query-monitor' ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_db_components( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'db_components' );
|
||||
if ( $collector ) {
|
||||
$output['db_components'] = new QM_Output_Html_DB_Components( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_db_components', 40, 2 );
|
||||
161
wordpress_plugins/query-monitor/output/html/db_dupes.php
Normal file
161
wordpress_plugins/query-monitor/output/html/db_dupes.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php
|
||||
/**
|
||||
* Duplicate database query output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_DB_Dupes extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_DB_Dupes Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 45 );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 25 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Duplicate Queries', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['dupes'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Count', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Callers', 'query-monitor' ) . '</th>';
|
||||
if ( ! empty( $data['dupe_components'] ) ) {
|
||||
echo '<th scope="col">' . esc_html__( 'Components', 'query-monitor' ) . '</th>';
|
||||
}
|
||||
echo '<th scope="col">' . esc_html__( 'Potential Troublemakers', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
/* translators: %s: Number of calls to a PHP function */
|
||||
$call_text = _n_noop( '%s call', '%s calls', 'query-monitor' );
|
||||
|
||||
foreach ( $data['dupes'] as $sql => $queries ) {
|
||||
|
||||
// This should probably happen in the collector's processor
|
||||
$type = QM_Util::get_query_type( $sql );
|
||||
$sql_out = self::format_sql( $sql );
|
||||
|
||||
if ( 'SELECT' !== $type ) {
|
||||
$sql_out = "<span class='qm-nonselectsql'>{$sql_out}</span>";
|
||||
}
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td class="qm-row-sql qm-ltr qm-wrap">';
|
||||
echo $sql_out; // WPCS: XSS ok;
|
||||
echo '</td>';
|
||||
echo '<td class="qm-num">';
|
||||
echo esc_html( number_format_i18n( count( $queries ), 0 ) );
|
||||
echo '</td>';
|
||||
echo '<td class="qm-row-caller qm-nowrap qm-ltr">';
|
||||
foreach ( $data['dupe_callers'][ $sql ] as $caller => $calls ) {
|
||||
printf(
|
||||
'<button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="%s"><code>%s</code></button><br><span class="qm-info qm-supplemental">%s</span><br>',
|
||||
esc_attr( $caller ),
|
||||
esc_html( $caller ),
|
||||
esc_html( sprintf(
|
||||
translate_nooped_plural( $call_text, $calls, 'query-monitor' ),
|
||||
number_format_i18n( $calls )
|
||||
) )
|
||||
);
|
||||
}
|
||||
echo '</td>';
|
||||
if ( isset( $data['dupe_components'][ $sql ] ) ) {
|
||||
echo '<td class="qm-row-component qm-nowrap">';
|
||||
foreach ( $data['dupe_components'][ $sql ] as $component => $calls ) {
|
||||
printf(
|
||||
'%s<br><span class="qm-info qm-supplemental">%s</span><br>',
|
||||
esc_html( $component ),
|
||||
esc_html( sprintf(
|
||||
translate_nooped_plural( $call_text, $calls, 'query-monitor' ),
|
||||
number_format_i18n( $calls )
|
||||
) )
|
||||
);
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
echo '<td class="qm-row-caller qm-nowrap qm-ltr">';
|
||||
foreach ( $data['dupe_sources'][ $sql ] as $source => $calls ) {
|
||||
printf(
|
||||
'<code>%s</code><br><span class="qm-info qm-supplemental">%s</span><br>',
|
||||
esc_html( $source ),
|
||||
esc_html( sprintf(
|
||||
translate_nooped_plural( $call_text, $calls, 'query-monitor' ),
|
||||
number_format_i18n( $calls )
|
||||
) )
|
||||
);
|
||||
}
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
$dbq = QM_Collectors::get( 'db_dupes' );
|
||||
|
||||
if ( $dbq ) {
|
||||
$dbq_data = $dbq->get_data();
|
||||
if ( isset( $dbq_data['dupes'] ) && count( $dbq_data['dupes'] ) ) {
|
||||
$count = count( $dbq_data['dupes'] );
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html( sprintf(
|
||||
/* translators: %s: Number of duplicate database queries */
|
||||
__( 'Duplicate Queries (%s)', 'query-monitor' ),
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
}
|
||||
}
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
$id = $this->collector->id();
|
||||
if ( isset( $menu[ $id ] ) ) {
|
||||
$menu[ $id ]['title'] = $menu[ $id ]['title'];
|
||||
|
||||
$menu['qm-db_queries-$wpdb']['children'][] = $menu[ $id ];
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_db_dupes( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'db_dupes' );
|
||||
if ( $collector ) {
|
||||
$output['db_dupes'] = new QM_Output_Html_DB_Dupes( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_db_dupes', 45, 2 );
|
||||
618
wordpress_plugins/query-monitor/output/html/db_queries.php
Normal file
618
wordpress_plugins/query-monitor/output/html/db_queries.php
Normal file
@@ -0,0 +1,618 @@
|
||||
<?php
|
||||
/**
|
||||
* Database query output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_DB_Queries extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_DB_Queries Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public $query_row = 0;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 20 );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 20 );
|
||||
add_filter( 'qm/output/title', array( $this, 'admin_title' ), 20 );
|
||||
add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Database Queries', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['dbs'] ) ) {
|
||||
$this->output_empty_queries();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! empty( $data['errors'] ) ) {
|
||||
$this->output_error_queries( $data['errors'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $data['expensive'] ) ) {
|
||||
$this->output_expensive_queries( $data['expensive'] );
|
||||
}
|
||||
|
||||
foreach ( $data['dbs'] as $name => $db ) {
|
||||
$this->output_queries( $name, $db, $data );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function output_empty_queries() {
|
||||
$id = sprintf(
|
||||
'%s-wpdb',
|
||||
$this->collector->id()
|
||||
);
|
||||
$this->before_non_tabular_output( $id );
|
||||
|
||||
if ( ! SAVEQUERIES ) {
|
||||
$notice = sprintf(
|
||||
/* translators: 1: Name of PHP constant, 2: Value of PHP constant */
|
||||
esc_html__( 'No database queries were logged because the %1$s constant is set to %2$s.', 'query-monitor' ),
|
||||
'<code>SAVEQUERIES</code>',
|
||||
'<code>false</code>'
|
||||
);
|
||||
} else {
|
||||
$notice = __( 'No database queries were logged.', 'query-monitor' );
|
||||
}
|
||||
|
||||
echo $this->build_notice( $notice ); // WPCS: XSS ok.
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
protected function output_error_queries( array $errors ) {
|
||||
$this->before_tabular_output( 'qm-query-errors', __( 'Database Errors', 'query-monitor' ) );
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Error Message', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Error Code', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $errors as $row ) {
|
||||
$this->output_query_row( $row, array( 'sql', 'caller', 'component', 'errno', 'result' ) );
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
protected function output_expensive_queries( array $expensive ) {
|
||||
$dp = strlen( substr( strrchr( (string) QM_DB_EXPENSIVE, '.' ), 1 ) );
|
||||
|
||||
$panel_name = sprintf(
|
||||
/* translators: %s: Database query time in seconds */
|
||||
esc_html__( 'Slow Database Queries (above %ss)', 'query-monitor' ),
|
||||
'<span class="qm-warn">' . esc_html( number_format_i18n( QM_DB_EXPENSIVE, $dp ) ) . '</span>'
|
||||
);
|
||||
$this->before_tabular_output( 'qm-query-expensive', $panel_name );
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Query', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
|
||||
if ( isset( $expensive[0]['component'] ) ) {
|
||||
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
||||
}
|
||||
|
||||
if ( isset( $expensive[0]['result'] ) ) {
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Rows', 'query-monitor' ) . '</th>';
|
||||
}
|
||||
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Time', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $expensive as $row ) {
|
||||
$this->output_query_row( $row, array( 'sql', 'caller', 'component', 'result', 'time' ) );
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
protected function output_queries( $name, stdClass $db, array $data ) {
|
||||
$this->query_row = 0;
|
||||
$span = 4;
|
||||
|
||||
if ( $db->has_result ) {
|
||||
$span++;
|
||||
}
|
||||
if ( $db->has_trace ) {
|
||||
$span++;
|
||||
}
|
||||
|
||||
$panel_id = sprintf(
|
||||
'%s-%s',
|
||||
$this->collector->id(),
|
||||
sanitize_title_with_dashes( $name )
|
||||
);
|
||||
$panel_name = sprintf(
|
||||
/* translators: %s: Name of database controller */
|
||||
__( '%s Queries', 'query-monitor' ),
|
||||
$name
|
||||
);
|
||||
|
||||
if ( ! empty( $db->rows ) ) {
|
||||
$this->before_tabular_output( $panel_id, $panel_name );
|
||||
|
||||
echo '<thead>';
|
||||
|
||||
/**
|
||||
* Filter whether to show the QM extended query information prompt.
|
||||
*
|
||||
* By default QM shows a prompt to install the QM db.php drop-in,
|
||||
* this filter allows a dev to choose not to show the prompt.
|
||||
*
|
||||
* @since 2.9.0
|
||||
*
|
||||
* @param bool $show_prompt Whether to show the prompt.
|
||||
*/
|
||||
if ( apply_filters( 'qm/show_extended_query_prompt', true ) && ! $db->has_trace && ( '$wpdb' === $name ) ) {
|
||||
echo '<tr>';
|
||||
echo '<th colspan="' . intval( $span ) . '" class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
if ( file_exists( WP_CONTENT_DIR . '/db.php' ) ) {
|
||||
/* translators: 1: Symlink file name, 2: URL to wiki page */
|
||||
$message = __( 'Extended query information such as the component and affected rows is not available. A conflicting %1$s file is present. <a href="%2$s" target="_blank" class="qm-external-link">See this wiki page for more information.</a>', 'query-monitor' );
|
||||
} else {
|
||||
/* translators: 1: Symlink file name, 2: URL to wiki page */
|
||||
$message = __( 'Extended query information such as the component and affected rows is not available. Query Monitor was unable to symlink its %1$s file into place. <a href="%2$s" target="_blank" class="qm-external-link">See this wiki page for more information.</a>', 'query-monitor' );
|
||||
}
|
||||
echo wp_kses( sprintf(
|
||||
$message,
|
||||
'<code>db.php</code>',
|
||||
'https://github.com/johnbillion/query-monitor/wiki/db.php-Symlink'
|
||||
), array(
|
||||
'a' => array(
|
||||
'href' => array(),
|
||||
'target' => array(),
|
||||
'class' => array(),
|
||||
),
|
||||
) );
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
$types = array_keys( $db->types );
|
||||
$prepend = array();
|
||||
$callers = wp_list_pluck( $data['times'], 'caller' );
|
||||
|
||||
sort( $types );
|
||||
usort( $callers, 'strcasecmp' );
|
||||
|
||||
if ( count( $types ) > 1 ) {
|
||||
$prepend['non-select'] = __( 'Non-SELECT', 'query-monitor' );
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'prepend' => $prepend,
|
||||
);
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="col" class="qm-sorted-asc qm-sortable-column" role="columnheader" aria-sort="ascending">';
|
||||
echo $this->build_sorter( '#' ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'type', $types, __( 'Query', 'query-monitor' ), $args ); // WPCS: XSS ok;
|
||||
echo '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
|
||||
$prepend = array();
|
||||
|
||||
if ( $db->has_main_query ) {
|
||||
$prepend['qm-main-query'] = __( 'Main Query', 'query-monitor' );
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'prepend' => $prepend,
|
||||
);
|
||||
echo $this->build_filter( 'caller', $callers, __( 'Caller', 'query-monitor' ), $args ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
|
||||
if ( $db->has_trace ) {
|
||||
$components = wp_list_pluck( $data['component_times'], 'component' );
|
||||
|
||||
usort( $components, 'strcasecmp' );
|
||||
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'component', $components, __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
}
|
||||
|
||||
if ( $db->has_result ) {
|
||||
if ( empty( $data['errors'] ) ) {
|
||||
$class = 'qm-num';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
echo '<th scope="col" class="' . esc_attr( $class ) . ' qm-sortable-column" role="columnheader" aria-sort="none">';
|
||||
echo $this->build_sorter( __( 'Rows', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
}
|
||||
|
||||
echo '<th scope="col" class="qm-num qm-sortable-column" role="columnheader" aria-sort="none">';
|
||||
echo $this->build_sorter( __( 'Time', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $db->rows as $row ) {
|
||||
$this->output_query_row( $row, array( 'row', 'sql', 'caller', 'component', 'result', 'time' ) );
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '<tfoot>';
|
||||
|
||||
$total_stime = number_format_i18n( $db->total_time, 4 );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td colspan="' . intval( $span - 1 ) . '">';
|
||||
printf(
|
||||
/* translators: %s: Number of database queries */
|
||||
esc_html( _nx( 'Total: %s', 'Total: %s', $db->total_qs, 'Query count', 'query-monitor' ) ),
|
||||
'<span class="qm-items-number">' . esc_html( number_format_i18n( $db->total_qs ) ) . '</span>'
|
||||
);
|
||||
echo '</td>';
|
||||
echo '<td class="qm-num qm-items-time">' . esc_html( $total_stime ) . '</td>';
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
} else {
|
||||
$this->before_non_tabular_output( $panel_id, $panel_name );
|
||||
|
||||
$notice = __( 'No queries! Nice work.', 'query-monitor' );
|
||||
echo $this->build_notice( $notice ); // WPCS: XSS ok.
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
}
|
||||
|
||||
protected function output_query_row( array $row, array $cols ) {
|
||||
|
||||
$cols = array_flip( $cols );
|
||||
|
||||
if ( ! isset( $row['component'] ) ) {
|
||||
unset( $cols['component'] );
|
||||
}
|
||||
if ( ! isset( $row['result'] ) ) {
|
||||
unset( $cols['result'], $cols['errno'] );
|
||||
}
|
||||
|
||||
$stime = number_format_i18n( $row['ltime'], 4 );
|
||||
|
||||
$sql = self::format_sql( $row['sql'] );
|
||||
|
||||
if ( 'SELECT' !== $row['type'] ) {
|
||||
$sql = "<span class='qm-nonselectsql'>{$sql}</span>";
|
||||
}
|
||||
|
||||
if ( isset( $row['trace'] ) ) {
|
||||
|
||||
$caller = $row['trace']->get_caller();
|
||||
$caller_name = self::output_filename( $row['caller'], $caller['calling_file'], $caller['calling_line'] );
|
||||
$stack = array();
|
||||
$filtered_trace = $row['trace']->get_display_trace();
|
||||
array_shift( $filtered_trace );
|
||||
|
||||
foreach ( $filtered_trace as $item ) {
|
||||
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
||||
}
|
||||
} else {
|
||||
|
||||
if ( ! empty( $row['caller'] ) ) {
|
||||
$caller_name = '<code>' . esc_html( $row['caller'] ) . '</code>';
|
||||
} else {
|
||||
$caller_name = '<code>' . esc_html__( 'Unknown', 'query-monitor' ) . '</code>';
|
||||
}
|
||||
|
||||
$stack = explode( ', ', $row['stack'] );
|
||||
$stack = array_reverse( $stack );
|
||||
array_shift( $stack );
|
||||
$stack = array_map( function( $item ) {
|
||||
return '<code>' . esc_html( $item ) . '</code>';
|
||||
}, $stack );
|
||||
|
||||
}
|
||||
|
||||
$row_attr = array();
|
||||
|
||||
if ( is_wp_error( $row['result'] ) ) {
|
||||
$row_attr['class'] = 'qm-warn';
|
||||
}
|
||||
if ( isset( $cols['sql'] ) ) {
|
||||
$row_attr['data-qm-type'] = $row['type'];
|
||||
if ( 'SELECT' !== $row['type'] ) {
|
||||
$row_attr['data-qm-type'] .= ' non-select';
|
||||
}
|
||||
}
|
||||
if ( isset( $cols['component'] ) && $row['component'] ) {
|
||||
$row_attr['data-qm-component'] = $row['component']->name;
|
||||
|
||||
if ( 'core' !== $row['component']->context ) {
|
||||
$row_attr['data-qm-component'] .= ' non-core';
|
||||
}
|
||||
}
|
||||
if ( isset( $cols['caller'] ) && ! empty( $row['caller_name'] ) ) {
|
||||
$row_attr['data-qm-caller'] = $row['caller_name'];
|
||||
|
||||
if ( $row['is_main_query'] ) {
|
||||
$row_attr['data-qm-caller'] .= ' qm-main-query';
|
||||
}
|
||||
}
|
||||
if ( isset( $cols['time'] ) ) {
|
||||
$row_attr['data-qm-time'] = $row['ltime'];
|
||||
}
|
||||
|
||||
$attr = '';
|
||||
|
||||
foreach ( $row_attr as $a => $v ) {
|
||||
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
||||
}
|
||||
|
||||
echo "<tr{$attr}>"; // WPCS: XSS ok.
|
||||
|
||||
if ( isset( $cols['row'] ) ) {
|
||||
echo '<th scope="row" class="qm-row-num qm-num">' . intval( ++$this->query_row ) . '</th>';
|
||||
}
|
||||
|
||||
if ( isset( $cols['sql'] ) ) {
|
||||
printf( // WPCS: XSS ok.
|
||||
'<td class="qm-row-sql qm-ltr qm-wrap">%s</td>',
|
||||
$sql
|
||||
);
|
||||
}
|
||||
|
||||
if ( isset( $cols['caller'] ) ) {
|
||||
echo '<td class="qm-row-caller qm-ltr qm-has-toggle qm-nowrap">';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
echo '<ol>';
|
||||
echo "<li>{$caller_name}</li>"; // WPCS: XSS ok.
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
||||
}
|
||||
|
||||
echo '</ol>';
|
||||
if ( $row['is_main_query'] ) {
|
||||
printf(
|
||||
'<p>%s</p>',
|
||||
esc_html__( 'Main Query', 'query-monitor' )
|
||||
);
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
if ( isset( $cols['stack'] ) ) {
|
||||
echo '<td class="qm-row-caller qm-row-stack qm-nowrap qm-ltr"><ol>';
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<li>' . implode( '</li><li>', $stack ) . '</li>'; // WPCS: XSS ok.
|
||||
}
|
||||
echo "<li>{$caller_name}</li>"; // WPCS: XSS ok.
|
||||
echo '</ol></td>';
|
||||
}
|
||||
|
||||
if ( isset( $cols['component'] ) ) {
|
||||
if ( $row['component'] ) {
|
||||
echo "<td class='qm-row-component qm-nowrap'>" . esc_html( $row['component']->name ) . "</td>\n";
|
||||
} else {
|
||||
echo "<td class='qm-row-component qm-nowrap'>" . esc_html__( 'Unknown', 'query-monitor' ) . "</td>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $cols['result'] ) ) {
|
||||
if ( is_wp_error( $row['result'] ) ) {
|
||||
echo "<td class='qm-row-result qm-row-error'><span class='dashicons dashicons-warning' aria-hidden='true'></span>" . esc_html( $row['result']->get_error_message() ) . "</td>\n";
|
||||
} else {
|
||||
echo "<td class='qm-row-result qm-num'>" . esc_html( $row['result'] ) . "</td>\n";
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $cols['errno'] ) && is_wp_error( $row['result'] ) ) {
|
||||
echo "<td class='qm-row-result qm-row-error'>" . esc_html( $row['result']->get_error_code() ) . "</td>\n";
|
||||
}
|
||||
|
||||
if ( isset( $cols['time'] ) ) {
|
||||
$expensive = $this->collector->is_expensive( $row );
|
||||
$td_class = ( $expensive ) ? ' qm-warn' : '';
|
||||
|
||||
echo '<td class="qm-num qm-row-time' . esc_attr( $td_class ) . '" data-qm-sort-weight="' . esc_attr( $row['ltime'] ) . '">';
|
||||
|
||||
if ( $expensive ) {
|
||||
echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
}
|
||||
|
||||
echo esc_html( $stime );
|
||||
echo "</td>\n";
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
public function admin_title( array $existing ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( isset( $data['dbs'] ) ) {
|
||||
foreach ( $data['dbs'] as $key => $db ) {
|
||||
/* translators: %s: Database query time in seconds */
|
||||
$text = _nx( '%s S', '%s S', $db->total_time, 'Query time', 'query-monitor' );
|
||||
|
||||
// Avoid a potentially blank translation for the plural form.
|
||||
// @see https://meta.trac.wordpress.org/ticket/5377
|
||||
if ( '' === $text ) {
|
||||
$text = '%s S';
|
||||
}
|
||||
|
||||
$title[] = sprintf(
|
||||
esc_html( '%s' . $text ),
|
||||
( count( $data['dbs'] ) > 1 ? '• ' : '' ),
|
||||
number_format_i18n( $db->total_time, 4 )
|
||||
);
|
||||
|
||||
/* translators: %s: Number of database queries */
|
||||
$text = _nx( '%s Q', '%s Q', $db->total_qs, 'Query count', 'query-monitor' );
|
||||
|
||||
// Avoid a potentially blank translation for the plural form.
|
||||
// @see https://meta.trac.wordpress.org/ticket/5377
|
||||
if ( '' === $text ) {
|
||||
$text = '%s Q';
|
||||
}
|
||||
|
||||
$title[] = sprintf(
|
||||
esc_html( $text ),
|
||||
number_format_i18n( $db->total_qs )
|
||||
);
|
||||
}
|
||||
} elseif ( isset( $data['total_qs'] ) ) {
|
||||
/* translators: %s: Number of database queries */
|
||||
$text = _nx( '%s Q', '%s Q', $data['total_qs'], 'Query count', 'query-monitor' );
|
||||
|
||||
// Avoid a potentially blank translation for the plural form.
|
||||
// @see https://meta.trac.wordpress.org/ticket/5377
|
||||
if ( '' === $text ) {
|
||||
$text = '%s Q';
|
||||
}
|
||||
|
||||
$title[] = sprintf(
|
||||
/* translators: %s: Number of database queries */
|
||||
esc_html( $text ),
|
||||
number_format_i18n( $data['total_qs'] )
|
||||
);
|
||||
}
|
||||
|
||||
foreach ( $title as &$t ) {
|
||||
$t = preg_replace( '#\s?([^0-9,\.]+)#', '<small>$1</small>', $t );
|
||||
}
|
||||
|
||||
$title = array_merge( $existing, $title );
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
public function admin_class( array $class ) {
|
||||
|
||||
if ( $this->collector->get_errors() ) {
|
||||
$class[] = 'qm-error';
|
||||
}
|
||||
if ( $this->collector->get_expensive() ) {
|
||||
$class[] = 'qm-expensive';
|
||||
}
|
||||
return $class;
|
||||
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$errors = $this->collector->get_errors();
|
||||
$expensive = $this->collector->get_expensive();
|
||||
|
||||
if ( isset( $data['dbs'] ) && count( $data['dbs'] ) > 1 ) {
|
||||
foreach ( $data['dbs'] as $name => $db ) {
|
||||
$name_attr = sanitize_title_with_dashes( $name );
|
||||
$id = $this->collector->id() . '-' . $name_attr;
|
||||
$menu[ $id ] = $this->menu( array(
|
||||
'id' => esc_attr( sprintf( 'query-monitor-%s-db-%s', $this->collector->id(), $name_attr ) ),
|
||||
'title' => esc_html( sprintf(
|
||||
/* translators: %s: Name of database controller */
|
||||
__( 'Queries: %s', 'query-monitor' ),
|
||||
$name
|
||||
) ),
|
||||
'href' => esc_attr( sprintf( '#%s-%s', $this->collector->id(), $name_attr ) ),
|
||||
) );
|
||||
}
|
||||
} else {
|
||||
$id = $this->collector->id() . '-$wpdb';
|
||||
$menu[ $id ] = $this->menu( array(
|
||||
'title' => esc_html__( 'Queries', 'query-monitor' ),
|
||||
'href' => esc_attr( sprintf( '#%s-wpdb', $this->collector->id() ) ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( $errors ) {
|
||||
$id = $this->collector->id() . '-errors';
|
||||
$count = count( $errors );
|
||||
$menu[ $id ] = $this->menu( array(
|
||||
'id' => 'query-monitor-errors',
|
||||
'href' => '#qm-query-errors',
|
||||
'title' => esc_html( sprintf(
|
||||
/* translators: %s: Number of database errors */
|
||||
__( 'Database Errors (%s)', 'query-monitor' ),
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
}
|
||||
|
||||
if ( $expensive ) {
|
||||
$id = $this->collector->id() . '-expensive';
|
||||
$count = count( $expensive );
|
||||
$menu[ $id ] = $this->menu( array(
|
||||
'id' => 'query-monitor-expensive',
|
||||
'href' => '#qm-query-expensive',
|
||||
'title' => esc_html( sprintf(
|
||||
/* translators: %s: Number of slow database queries */
|
||||
__( 'Slow Queries (%s)', 'query-monitor' ),
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
}
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
foreach ( array( 'errors', 'expensive' ) as $sub ) {
|
||||
$id = $this->collector->id() . '-' . $sub;
|
||||
if ( isset( $menu[ $id ] ) ) {
|
||||
$menu[ $id ]['title'] = $menu[ $id ]['title'];
|
||||
|
||||
$menu['qm-db_queries-$wpdb']['children'][] = $menu[ $id ];
|
||||
unset( $menu[ $id ] );
|
||||
}
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_db_queries( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'db_queries' );
|
||||
if ( $collector ) {
|
||||
$output['db_queries'] = new QM_Output_Html_DB_Queries( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_db_queries', 20, 2 );
|
||||
91
wordpress_plugins/query-monitor/output/html/debug_bar.php
Normal file
91
wordpress_plugins/query-monitor/output/html/debug_bar.php
Normal file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* 'Debug Bar' output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Debug_Bar extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Debug_Bar Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 200 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
$title = $this->collector->get_panel()->title();
|
||||
|
||||
return sprintf(
|
||||
/* translators: Debug Bar add-on name */
|
||||
__( 'Debug Bar: %s', 'query-monitor' ),
|
||||
$title
|
||||
);
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$target = sanitize_html_class( get_class( $this->collector->get_panel() ) );
|
||||
|
||||
$this->before_debug_bar_output();
|
||||
|
||||
echo '<div id="debug-menu-target-' . esc_attr( $target ) . '" class="debug-menu-target qm-debug-bar-output">';
|
||||
|
||||
ob_start();
|
||||
$this->collector->render();
|
||||
$panel = ob_get_clean();
|
||||
|
||||
$panel = str_replace( array(
|
||||
'<h4',
|
||||
'<h3',
|
||||
'<h2',
|
||||
'<h1',
|
||||
'</h4>',
|
||||
'</h3>',
|
||||
'</h2>',
|
||||
'</h1>',
|
||||
), array(
|
||||
'<h5',
|
||||
'<h4',
|
||||
'<h3',
|
||||
'<h2',
|
||||
'</h5>',
|
||||
'</h4>',
|
||||
'</h3>',
|
||||
'</h2>',
|
||||
), $panel );
|
||||
|
||||
echo $panel; // phpcs:ignore
|
||||
|
||||
echo '</div>';
|
||||
|
||||
$this->after_debug_bar_output();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_debug_bar( array $output, QM_Collectors $collectors ) {
|
||||
global $debug_bar;
|
||||
|
||||
if ( empty( $debug_bar ) ) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
foreach ( $debug_bar->panels as $panel ) {
|
||||
$panel_id = strtolower( sanitize_html_class( get_class( $panel ) ) );
|
||||
$collector = QM_Collectors::get( "debug_bar_{$panel_id}" );
|
||||
|
||||
if ( $collector && $collector->is_visible() ) {
|
||||
$output[ "debug_bar_{$panel_id}" ] = new QM_Output_Html_Debug_Bar( $collector );
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_debug_bar', 200, 2 );
|
||||
321
wordpress_plugins/query-monitor/output/html/environment.php
Normal file
321
wordpress_plugins/query-monitor/output/html/environment.php
Normal file
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
/**
|
||||
* Environment data output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Environment extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Environment Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 110 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Environment', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>PHP</h3>';
|
||||
|
||||
echo '<table>';
|
||||
echo '<tbody>';
|
||||
|
||||
$append = '';
|
||||
$class = '';
|
||||
$php_warning = $data['php']['old'];
|
||||
|
||||
if ( $php_warning ) {
|
||||
$append .= sprintf(
|
||||
' <span class="qm-info">(<a href="%s" target="_blank" class="qm-external-link">%s</a>)</span>',
|
||||
'https://wordpress.org/support/update-php/',
|
||||
esc_html__( 'Help', 'query-monitor' )
|
||||
);
|
||||
$class = 'qm-warn';
|
||||
}
|
||||
|
||||
echo '<tr class="' . esc_attr( $class ) . '">';
|
||||
echo '<th scope="row">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
|
||||
echo '<td>';
|
||||
|
||||
if ( $php_warning ) {
|
||||
echo '<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
}
|
||||
|
||||
echo esc_html( $data['php']['version'] );
|
||||
echo $append; // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">SAPI</th>';
|
||||
echo '<td>' . esc_html( $data['php']['sapi'] ) . '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html__( 'User', 'query-monitor' ) . '</th>';
|
||||
if ( ! empty( $data['php']['user'] ) ) {
|
||||
echo '<td>' . esc_html( $data['php']['user'] ) . '</td>';
|
||||
} else {
|
||||
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
|
||||
foreach ( $data['php']['variables'] as $key => $val ) {
|
||||
$class = '';
|
||||
$warners = array(
|
||||
'max_execution_time',
|
||||
'memory_limit',
|
||||
);
|
||||
|
||||
if ( ! $val && in_array( $key, $warners, true ) ) {
|
||||
$class = 'qm-warn';
|
||||
}
|
||||
|
||||
echo '<tr class="' . esc_attr( $class ) . '">';
|
||||
echo '<th scope="row">' . esc_html( $key ) . '</th>';
|
||||
echo '<td>';
|
||||
|
||||
if ( 'qm-warn' === $class ) {
|
||||
echo '<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
}
|
||||
|
||||
echo esc_html( $val['after'] );
|
||||
|
||||
if ( $val['after'] !== $val['before'] ) {
|
||||
printf(
|
||||
'<br><span class="qm-info qm-supplemental">%s</span>',
|
||||
esc_html( sprintf(
|
||||
/* translators: %s: Original value of a variable */
|
||||
__( 'Overridden at runtime from %s', 'query-monitor' ),
|
||||
$val['before']
|
||||
) )
|
||||
);
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
$out = array();
|
||||
|
||||
foreach ( $data['php']['error_levels'] as $level => $reported ) {
|
||||
if ( $reported ) {
|
||||
$out[] = esc_html( $level ) . ' ✓';
|
||||
} else {
|
||||
$out[] = '<span class="qm-false">' . esc_html( $level ) . '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
$error_levels = implode( '</li><li>', $out );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html__( 'Error Reporting', 'query-monitor' ) . '</th>';
|
||||
echo '<td class="qm-has-toggle qm-ltr">';
|
||||
|
||||
echo esc_html( $data['php']['error_reporting'] );
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
|
||||
echo '<div class="qm-toggled">';
|
||||
echo "<ul class='qm-supplemental'><li>{$error_levels}</li></ul>"; // WPCS: XSS ok.
|
||||
echo '</div>';
|
||||
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
if ( ! empty( $data['php']['extensions'] ) ) {
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html__( 'Extensions', 'query-monitor' ) . '</th>';
|
||||
echo '<td class="qm-has-inner qm-has-toggle qm-ltr">';
|
||||
|
||||
printf( // WPCS: XSS ok.
|
||||
'<div class="qm-inner-toggle">%1$s %2$s</div>',
|
||||
esc_html( number_format_i18n( count( $data['php']['extensions'] ) ) ),
|
||||
self::build_toggler()
|
||||
);
|
||||
|
||||
echo '<div class="qm-toggled">';
|
||||
self::output_inner( $data['php']['extensions'] );
|
||||
echo '</div>';
|
||||
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
|
||||
echo '</section>';
|
||||
|
||||
if ( isset( $data['db'] ) ) {
|
||||
|
||||
foreach ( $data['db'] as $id => $db ) {
|
||||
|
||||
if ( 1 === count( $data['db'] ) ) {
|
||||
$name = __( 'Database', 'query-monitor' );
|
||||
} else {
|
||||
/* translators: %s: Name of database controller */
|
||||
$name = sprintf( __( 'Database: %s', 'query-monitor' ), $id );
|
||||
}
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html( $name ) . '</h3>';
|
||||
|
||||
echo '<table>';
|
||||
echo '<tbody>';
|
||||
|
||||
$info = array(
|
||||
'server-version' => __( 'Server Version', 'query-monitor' ),
|
||||
'extension' => __( 'Extension', 'query-monitor' ),
|
||||
'client-version' => __( 'Client Version', 'query-monitor' ),
|
||||
'user' => __( 'User', 'query-monitor' ),
|
||||
'host' => __( 'Host', 'query-monitor' ),
|
||||
'database' => __( 'Database', 'query-monitor' ),
|
||||
);
|
||||
|
||||
foreach ( $info as $field => $label ) {
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html( $label ) . '</th>';
|
||||
|
||||
if ( ! isset( $db['info'][ $field ] ) ) {
|
||||
echo '<td><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>' . esc_html__( 'Unknown', 'query-monitor' ) . '</span></td>';
|
||||
} else {
|
||||
echo '<td>' . esc_html( $db['info'][ $field ] ) . '</td>';
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
foreach ( $db['variables'] as $setting ) {
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
$key = $setting->Variable_name;
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
|
||||
$val = $setting->Value;
|
||||
|
||||
$append = '';
|
||||
|
||||
if ( is_numeric( $val ) && ( $val >= ( 1024 * 1024 ) ) ) {
|
||||
$append .= sprintf(
|
||||
' <span class="qm-info">(~%s)</span>',
|
||||
esc_html( size_format( $val ) )
|
||||
);
|
||||
}
|
||||
|
||||
echo '<tr>';
|
||||
|
||||
echo '<th scope="row">' . esc_html( $key ) . '</th>';
|
||||
echo '<td>';
|
||||
echo esc_html( $val );
|
||||
echo $append; // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
|
||||
echo '</section>';
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>WordPress</h3>';
|
||||
|
||||
echo '<table>';
|
||||
echo '<tbody>';
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html__( 'Version', 'query-monitor' ) . '</th>';
|
||||
echo '<td>' . esc_html( $data['wp']['version'] ) . '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
if ( isset( $data['wp']['environment_type'] ) ) {
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">';
|
||||
esc_html_e( 'Environment Type', 'query-monitor' );
|
||||
printf(
|
||||
' <span class="qm-info">(<a href="%s" target="_blank" class="qm-external-link">%s</a>)</span>',
|
||||
'https://make.wordpress.org/core/2020/07/24/new-wp_get_environment_type-function-in-wordpress-5-5/',
|
||||
esc_html__( 'Help', 'query-monitor' )
|
||||
);
|
||||
echo '</th>';
|
||||
echo '<td>' . esc_html( $data['wp']['environment_type'] ) . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
foreach ( $data['wp']['constants'] as $key => $val ) {
|
||||
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html( $key ) . '</th>';
|
||||
echo '<td>' . esc_html( $val ) . '</td>';
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
|
||||
echo '</section>';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Server', 'query-monitor' ) . '</h3>';
|
||||
|
||||
$server = array(
|
||||
'name' => __( 'Software', 'query-monitor' ),
|
||||
'version' => __( 'Version', 'query-monitor' ),
|
||||
'address' => __( 'Address', 'query-monitor' ),
|
||||
'host' => __( 'Host', 'query-monitor' ),
|
||||
'OS' => __( 'OS', 'query-monitor' ),
|
||||
);
|
||||
|
||||
echo '<table>';
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $server as $field => $label ) {
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html( $label ) . '</th>';
|
||||
if ( ! empty( $data['server'][ $field ] ) ) {
|
||||
echo '<td>' . esc_html( $data['server'][ $field ] ) . '</td>';
|
||||
} else {
|
||||
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
||||
}
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '</table>';
|
||||
echo '</section>';
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_environment( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'environment' );
|
||||
if ( $collector ) {
|
||||
$output['environment'] = new QM_Output_Html_Environment( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_environment', 120, 2 );
|
||||
117
wordpress_plugins/query-monitor/output/html/headers.php
Normal file
117
wordpress_plugins/query-monitor/output/html/headers.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
/**
|
||||
* Request and response headers output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Headers extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Raw_Request Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Collector name.
|
||||
*
|
||||
* This is unused.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function name() {
|
||||
return __( 'Request Data', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$this->output_request();
|
||||
$this->output_response();
|
||||
}
|
||||
|
||||
public function output_request() {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
$this->output_header_table( $data['request']['headers'], __( 'Request Header Name', 'query-monitor' ) );
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function output_response() {
|
||||
$data = $this->collector->get_data();
|
||||
$id = sprintf( 'qm-%s-response', $this->collector->id );
|
||||
|
||||
$this->before_tabular_output( $id );
|
||||
|
||||
$this->output_header_table( $data['response']['headers'], __( 'Response Header Name', 'query-monitor' ) );
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
protected function output_header_table( array $headers, $title ) {
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th>';
|
||||
echo esc_html( $title );
|
||||
echo '</th><th>';
|
||||
esc_html_e( 'Value', 'query-monitor' );
|
||||
echo '</th></tr>';
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $headers as $name => $value ) {
|
||||
echo '<tr>';
|
||||
$formatted = str_replace( ' ', '-', ucwords( strtolower( str_replace( array( '-', '_' ), ' ', $name ) ) ) );
|
||||
printf( '<th scope="row"><code>%s</code></th>', esc_html( $formatted ) );
|
||||
printf( '<td><pre class="qm-pre-wrap"><code>%s</code></pre></td>', esc_html( $value ) );
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
echo '<tfoot>';
|
||||
echo '<tr>';
|
||||
echo '<td colspan="2">';
|
||||
esc_html_e( 'Note that header names are not case-sensitive.', 'query-monitor' );
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
if ( ! isset( $menu['qm-request'] ) ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$ids = array(
|
||||
$this->collector->id() => __( 'Request Headers', 'query-monitor' ),
|
||||
$this->collector->id() . '-response' => __( 'Response Headers', 'query-monitor' ),
|
||||
);
|
||||
foreach ( $ids as $id => $title ) {
|
||||
$menu['qm-request']['children'][] = array(
|
||||
'id' => $id,
|
||||
'href' => '#' . $id,
|
||||
'title' => esc_html( $title ),
|
||||
);
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
}
|
||||
|
||||
function register_qm_output_html_headers( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'raw_request' );
|
||||
if ( $collector ) {
|
||||
$output['raw_request'] = new QM_Output_Html_Headers( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_headers', 100, 2 );
|
||||
203
wordpress_plugins/query-monitor/output/html/hooks.php
Normal file
203
wordpress_plugins/query-monitor/output/html/hooks.php
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Hooks and actions output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Hooks extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Hooks Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Hooks & Actions', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['hooks'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'name', $data['parts'], __( 'Hook', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Priority', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Action', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'component', $data['components'], __( 'Component', 'query-monitor' ), array(
|
||||
'highlight' => 'subject',
|
||||
) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
self::output_hook_table( $data['hooks'] );
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public static function output_hook_table( array $hooks ) {
|
||||
$core = __( 'Core', 'query-monitor' );
|
||||
|
||||
foreach ( $hooks as $hook ) {
|
||||
$row_attr = array();
|
||||
$row_attr['data-qm-name'] = implode( ' ', $hook['parts'] );
|
||||
$row_attr['data-qm-component'] = implode( ' ', $hook['components'] );
|
||||
|
||||
if ( ! empty( $row_attr['data-qm-component'] ) && $core !== $row_attr['data-qm-component'] ) {
|
||||
$row_attr['data-qm-component'] .= ' non-core';
|
||||
}
|
||||
|
||||
$attr = '';
|
||||
|
||||
if ( ! empty( $hook['actions'] ) ) {
|
||||
$rowspan = count( $hook['actions'] );
|
||||
} else {
|
||||
$rowspan = 1;
|
||||
}
|
||||
|
||||
foreach ( $row_attr as $a => $v ) {
|
||||
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
||||
}
|
||||
|
||||
if ( ! empty( $hook['actions'] ) ) {
|
||||
|
||||
$first = true;
|
||||
|
||||
foreach ( $hook['actions'] as $action ) {
|
||||
$component = '';
|
||||
$subject = '';
|
||||
|
||||
if ( isset( $action['callback']['component'] ) ) {
|
||||
$component = $action['callback']['component']->name;
|
||||
$subject = $component;
|
||||
}
|
||||
|
||||
if ( $core !== $component ) {
|
||||
$subject .= ' non-core';
|
||||
}
|
||||
|
||||
printf( // WPCS: XSS ok.
|
||||
'<tr data-qm-subject="%s" %s>',
|
||||
esc_attr( $subject ),
|
||||
$attr
|
||||
);
|
||||
|
||||
if ( $first ) {
|
||||
|
||||
echo '<th scope="row" rowspan="' . intval( $rowspan ) . '" class="qm-nowrap qm-ltr"><span class="qm-sticky">';
|
||||
echo '<code>' . esc_html( $hook['name'] ) . '</code>';
|
||||
if ( 'all' === $hook['name'] ) {
|
||||
echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
printf(
|
||||
/* translators: %s: Action name */
|
||||
esc_html__( 'Warning: The %s action is extremely resource intensive. Try to avoid using it.', 'query-monitor' ),
|
||||
'<code>all</code>'
|
||||
);
|
||||
echo '</span>';
|
||||
}
|
||||
echo '</span></th>';
|
||||
|
||||
}
|
||||
|
||||
if ( isset( $action['callback']['error'] ) ) {
|
||||
$class = ' qm-warn';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
|
||||
echo '<td class="qm-num' . esc_attr( $class ) . '">';
|
||||
|
||||
echo esc_html( $action['priority'] );
|
||||
|
||||
if ( PHP_INT_MAX === $action['priority'] ) {
|
||||
echo ' <span class="qm-info">(PHP_INT_MAX)</span>';
|
||||
// phpcs:ignore PHPCompatibility.Constants.NewConstants.php_int_minFound
|
||||
} elseif ( defined( 'PHP_INT_MIN' ) && PHP_INT_MIN === $action['priority'] ) {
|
||||
echo ' <span class="qm-info">(PHP_INT_MIN)</span>';
|
||||
} elseif ( -PHP_INT_MAX === $action['priority'] ) {
|
||||
echo ' <span class="qm-info">(-PHP_INT_MAX)</span>';
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
|
||||
if ( isset( $action['callback']['file'] ) ) {
|
||||
if ( self::has_clickable_links() ) {
|
||||
echo '<td class="qm-nowrap qm-ltr' . esc_attr( $class ) . '">';
|
||||
echo self::output_filename( $action['callback']['name'], $action['callback']['file'], $action['callback']['line'] ); // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-nowrap qm-ltr qm-has-toggle' . esc_attr( $class ) . '">';
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<ol>';
|
||||
echo '<li>';
|
||||
echo self::output_filename( $action['callback']['name'], $action['callback']['file'], $action['callback']['line'] ); // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
echo '</ol></td>';
|
||||
}
|
||||
} else {
|
||||
echo '<td class="qm-ltr qm-nowrap' . esc_attr( $class ) . '">';
|
||||
echo '<code>' . esc_html( $action['callback']['name'] ) . '</code>';
|
||||
|
||||
if ( isset( $action['callback']['error'] ) ) {
|
||||
echo '<br><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
echo esc_html( sprintf(
|
||||
/* translators: %s: Error message text */
|
||||
__( 'Error: %s', 'query-monitor' ),
|
||||
$action['callback']['error']->get_error_message()
|
||||
) );
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
echo '<td class="qm-nowrap' . esc_attr( $class ) . '">';
|
||||
echo esc_html( $component );
|
||||
echo '</td>';
|
||||
echo '</tr>';
|
||||
$first = false;
|
||||
}
|
||||
} else {
|
||||
echo "<tr{$attr}>"; // WPCS: XSS ok.
|
||||
echo '<th scope="row" class="qm-ltr">';
|
||||
echo '<code>' . esc_html( $hook['name'] ) . '</code>';
|
||||
echo '</th>';
|
||||
echo '<td></td>';
|
||||
echo '<td></td>';
|
||||
echo '<td></td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_hooks( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'hooks' );
|
||||
if ( $collector ) {
|
||||
$output['hooks'] = new QM_Output_Html_Hooks( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_hooks', 80, 2 );
|
||||
398
wordpress_plugins/query-monitor/output/html/http.php
Normal file
398
wordpress_plugins/query-monitor/output/html/http.php
Normal file
@@ -0,0 +1,398 @@
|
||||
<?php
|
||||
/**
|
||||
* HTTP API request output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_HTTP extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_HTTP Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 90 );
|
||||
add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'HTTP API Calls', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( ! empty( $data['http'] ) ) {
|
||||
$statuses = array_keys( $data['types'] );
|
||||
$components = wp_list_pluck( $data['component_times'], 'component' );
|
||||
|
||||
usort( $statuses, 'strcasecmp' );
|
||||
usort( $components, 'strcasecmp' );
|
||||
|
||||
$status_output = array();
|
||||
|
||||
foreach ( $statuses as $key => $status ) {
|
||||
if ( -1 === $status ) {
|
||||
$status_output[-1] = __( 'Error', 'query-monitor' );
|
||||
} elseif ( -2 === $status ) {
|
||||
/* translators: A non-blocking HTTP API request */
|
||||
$status_output[-2] = __( 'Non-blocking', 'query-monitor' );
|
||||
} else {
|
||||
$status_output[] = $status;
|
||||
}
|
||||
}
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Method', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'URL', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'type', $status_output, __( 'Status', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'component', $components, __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Timeout', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Time', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
$i = 0;
|
||||
|
||||
foreach ( $data['http'] as $key => $row ) {
|
||||
$ltime = $row['ltime'];
|
||||
$i++;
|
||||
$is_error = false;
|
||||
$row_attr = array();
|
||||
$css = '';
|
||||
|
||||
if ( is_wp_error( $row['response'] ) ) {
|
||||
$response = $row['response']->get_error_message();
|
||||
$is_error = true;
|
||||
} elseif ( ! $row['args']['blocking'] ) {
|
||||
/* translators: A non-blocking HTTP API request */
|
||||
$response = __( 'Non-blocking', 'query-monitor' );
|
||||
} else {
|
||||
$code = wp_remote_retrieve_response_code( $row['response'] );
|
||||
$msg = wp_remote_retrieve_response_message( $row['response'] );
|
||||
|
||||
if ( intval( $code ) >= 400 ) {
|
||||
$is_error = true;
|
||||
}
|
||||
|
||||
$response = $code . ' ' . $msg;
|
||||
|
||||
}
|
||||
|
||||
if ( $is_error ) {
|
||||
$css = 'qm-warn';
|
||||
}
|
||||
|
||||
$url = self::format_url( $row['url'] );
|
||||
$info = '';
|
||||
|
||||
$url = preg_replace( '|^http:|', '<span class="qm-warn">http</span>:', $url );
|
||||
|
||||
if ( 'https' === parse_url( $row['url'], PHP_URL_SCHEME ) ) {
|
||||
if ( empty( $row['args']['sslverify'] ) && empty( $row['args']['local'] ) ) {
|
||||
$info .= '<span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>' . esc_html( sprintf(
|
||||
/* translators: An HTTP API request has disabled certificate verification. 1: Relevant argument name */
|
||||
__( 'Certificate verification disabled (%s)', 'query-monitor' ),
|
||||
'sslverify=false'
|
||||
) ) . '</span><br>';
|
||||
$url = preg_replace( '|^https:|', '<span class="qm-warn">https</span>:', $url );
|
||||
} elseif ( ! $is_error && $row['args']['blocking'] ) {
|
||||
$url = preg_replace( '|^https:|', '<span class="qm-true">https</span>:', $url );
|
||||
}
|
||||
}
|
||||
|
||||
$component = $row['component'];
|
||||
|
||||
$stack = array();
|
||||
$filtered_trace = $row['trace']->get_display_trace();
|
||||
|
||||
$filtered_trace = array_filter( $filtered_trace, function( $item ) {
|
||||
// @TODO This should happen during collection.
|
||||
if ( isset( $item['class'] ) ) {
|
||||
return ! in_array( $item['class'], array(
|
||||
'WP_Http',
|
||||
), true );
|
||||
}
|
||||
|
||||
if ( isset( $item['function'] ) ) {
|
||||
return ! in_array( $item['function'], array(
|
||||
'wp_safe_remote_request',
|
||||
'wp_safe_remote_get',
|
||||
'wp_safe_remote_post',
|
||||
'wp_safe_remote_head',
|
||||
'wp_remote_request',
|
||||
'wp_remote_get',
|
||||
'wp_remote_post',
|
||||
'wp_remote_head',
|
||||
'wp_remote_fopen',
|
||||
'download_url',
|
||||
'vip_safe_wp_remote_get',
|
||||
'wpcom_vip_file_get_contents',
|
||||
), true );
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
|
||||
foreach ( $filtered_trace as $item ) {
|
||||
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
||||
}
|
||||
|
||||
$row_attr['data-qm-component'] = $component->name;
|
||||
$row_attr['data-qm-type'] = $row['type'];
|
||||
$row_attr['data-qm-time'] = $row['ltime'];
|
||||
|
||||
if ( 'core' !== $component->context ) {
|
||||
$row_attr['data-qm-component'] .= ' non-core';
|
||||
}
|
||||
|
||||
$attr = '';
|
||||
foreach ( $row_attr as $a => $v ) {
|
||||
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
||||
}
|
||||
|
||||
printf( // WPCS: XSS ok.
|
||||
'<tr %s class="%s">',
|
||||
$attr,
|
||||
esc_attr( $css )
|
||||
);
|
||||
printf(
|
||||
'<td>%s</td>',
|
||||
esc_html( $row['args']['method'] )
|
||||
);
|
||||
|
||||
if ( ! empty( $row['redirected_to'] ) ) {
|
||||
$url .= sprintf(
|
||||
'<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%1$s</span><br>%2$s',
|
||||
/* translators: An HTTP API request redirected to another URL */
|
||||
__( 'Redirected to:', 'query-monitor' ),
|
||||
self::format_url( $row['redirected_to'] )
|
||||
);
|
||||
}
|
||||
|
||||
printf( // WPCS: XSS ok.
|
||||
'<td class="qm-url qm-ltr qm-wrap">%s%s</td>',
|
||||
$info,
|
||||
$url
|
||||
);
|
||||
|
||||
$show_toggle = ( ! empty( $row['transport'] ) && ! empty( $row['info'] ) );
|
||||
|
||||
echo '<td class="qm-has-toggle qm-col-status">';
|
||||
if ( $is_error ) {
|
||||
echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
}
|
||||
echo esc_html( $response );
|
||||
|
||||
if ( $show_toggle ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<ul class="qm-toggled">';
|
||||
}
|
||||
|
||||
if ( ! empty( $row['transport'] ) ) {
|
||||
$transport = sprintf(
|
||||
/* translators: %s HTTP API transport name */
|
||||
__( 'HTTP API Transport: %s', 'query-monitor' ),
|
||||
$row['transport']
|
||||
);
|
||||
printf(
|
||||
'<li><span class="qm-info qm-supplemental">%s</span></li>',
|
||||
esc_html( $transport )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $row['info'] ) ) {
|
||||
$time_fields = array(
|
||||
'namelookup_time' => __( 'DNS Resolution Time', 'query-monitor' ),
|
||||
'connect_time' => __( 'Connection Time', 'query-monitor' ),
|
||||
'starttransfer_time' => __( 'Transfer Start Time (TTFB)', 'query-monitor' ),
|
||||
);
|
||||
foreach ( $time_fields as $key => $value ) {
|
||||
if ( ! isset( $row['info'][ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
printf(
|
||||
'<li><span class="qm-info qm-supplemental">%1$s: %2$s</span></li>',
|
||||
esc_html( $value ),
|
||||
esc_html( number_format_i18n( $row['info'][ $key ], 4 ) )
|
||||
);
|
||||
}
|
||||
|
||||
$size_fields = array(
|
||||
'size_download' => __( 'Response Size', 'query-monitor' ),
|
||||
);
|
||||
foreach ( $size_fields as $key => $value ) {
|
||||
if ( ! isset( $row['info'][ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
printf(
|
||||
'<li><span class="qm-info qm-supplemental">%1$s: %2$s</span></li>',
|
||||
esc_html( $value ),
|
||||
esc_html( size_format( $row['info'][ $key ] ) )
|
||||
);
|
||||
}
|
||||
|
||||
$other_fields = array(
|
||||
'content_type' => __( 'Response Content Type', 'query-monitor' ),
|
||||
'primary_ip' => __( 'IP Address', 'query-monitor' ),
|
||||
);
|
||||
foreach ( $other_fields as $key => $value ) {
|
||||
if ( ! isset( $row['info'][ $key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
printf(
|
||||
'<li><span class="qm-info qm-supplemental">%1$s: %2$s</span></li>',
|
||||
esc_html( $value ),
|
||||
esc_html( $row['info'][ $key ] )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $show_toggle ) {
|
||||
echo '</ul>';
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
|
||||
$caller = array_shift( $stack );
|
||||
|
||||
echo '<td class="qm-has-toggle qm-nowrap qm-ltr">';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
echo '<ol>';
|
||||
|
||||
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
||||
}
|
||||
|
||||
echo '</ol></td>';
|
||||
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
esc_html( $component->name )
|
||||
);
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( $row['args']['timeout'] )
|
||||
);
|
||||
|
||||
if ( empty( $ltime ) ) {
|
||||
$stime = '';
|
||||
} else {
|
||||
$stime = number_format_i18n( $ltime, 4 );
|
||||
}
|
||||
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( $stime )
|
||||
);
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
echo '<tfoot>';
|
||||
|
||||
$total_stime = number_format_i18n( $data['ltime'], 4 );
|
||||
$count = count( $data['http'] );
|
||||
|
||||
echo '<tr>';
|
||||
printf(
|
||||
'<td colspan="6">%s</td>',
|
||||
sprintf(
|
||||
/* translators: %s: Number of HTTP API requests */
|
||||
esc_html( _nx( 'Total: %s', 'Total: %s', $count, 'HTTP API calls', 'query-monitor' ) ),
|
||||
'<span class="qm-items-number">' . esc_html( number_format_i18n( $count ) ) . '</span>'
|
||||
)
|
||||
);
|
||||
echo '<td class="qm-num qm-items-time">' . esc_html( $total_stime ) . '</td>';
|
||||
echo '</tr>';
|
||||
echo '</tfoot>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
} else {
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
$notice = __( 'No HTTP API calls.', 'query-monitor' );
|
||||
echo $this->build_notice( $notice ); // WPCS: XSS ok.
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
}
|
||||
|
||||
public function admin_class( array $class ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( isset( $data['errors']['alert'] ) ) {
|
||||
$class[] = 'qm-alert';
|
||||
}
|
||||
if ( isset( $data['errors']['warning'] ) ) {
|
||||
$class[] = 'qm-warning';
|
||||
}
|
||||
|
||||
return $class;
|
||||
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$count = isset( $data['http'] ) ? count( $data['http'] ) : 0;
|
||||
|
||||
$title = ( empty( $count ) )
|
||||
? __( 'HTTP API Calls', 'query-monitor' )
|
||||
/* translators: %s: Number of calls to the HTTP API */
|
||||
: __( 'HTTP API Calls (%s)', 'query-monitor' );
|
||||
|
||||
$args = array(
|
||||
'title' => esc_html( sprintf(
|
||||
$title,
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
);
|
||||
|
||||
if ( isset( $data['errors']['alert'] ) ) {
|
||||
$args['meta']['classname'] = 'qm-alert';
|
||||
}
|
||||
if ( isset( $data['errors']['warning'] ) ) {
|
||||
$args['meta']['classname'] = 'qm-warning';
|
||||
}
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( $args );
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_http( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'http' );
|
||||
if ( $collector ) {
|
||||
$output['http'] = new QM_Output_Html_HTTP( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_http', 90, 2 );
|
||||
124
wordpress_plugins/query-monitor/output/html/languages.php
Normal file
124
wordpress_plugins/query-monitor/output/html/languages.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
/**
|
||||
* Language and locale output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Languages extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Languages Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 80 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Languages', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['languages'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Text Domain', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Type', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Translation File', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Size', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['languages'] as $textdomain => $mofiles ) {
|
||||
foreach ( $mofiles as $mofile ) {
|
||||
echo '<tr>';
|
||||
|
||||
if ( $mofile['handle'] ) {
|
||||
echo '<td class="qm-ltr">' . esc_html( $mofile['domain'] ) . ' (' . esc_html( $mofile['handle'] ) . ')</td>';
|
||||
} else {
|
||||
echo '<td class="qm-ltr">' . esc_html( $mofile['domain'] ) . '</td>';
|
||||
}
|
||||
|
||||
echo '<td>' . esc_html( $mofile['type'] ) . '</td>';
|
||||
|
||||
if ( self::has_clickable_links() ) {
|
||||
echo '<td class="qm-nowrap qm-ltr">';
|
||||
echo self::output_filename( $mofile['caller']['display'], $mofile['caller']['file'], $mofile['caller']['line'] ); // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-nowrap qm-ltr qm-has-toggle">';
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<ol>';
|
||||
echo '<li>';
|
||||
echo self::output_filename( $mofile['caller']['display'], $mofile['caller']['file'], $mofile['caller']['line'] ); // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
echo '</ol></td>';
|
||||
}
|
||||
|
||||
echo '<td class="qm-ltr">';
|
||||
if ( $mofile['file'] ) {
|
||||
echo esc_html( QM_Util::standard_dir( $mofile['file'], '' ) );
|
||||
} else {
|
||||
echo '<em>' . esc_html__( 'None', 'query-monitor' ) . '</em>';
|
||||
}
|
||||
echo '</td>';
|
||||
|
||||
echo '<td class="qm-nowrap">';
|
||||
|
||||
if ( $mofile['found'] ) {
|
||||
echo esc_html( $mofile['found_formatted'] );
|
||||
} else {
|
||||
echo esc_html__( 'Not Found', 'query-monitor' );
|
||||
}
|
||||
|
||||
echo '</td>';
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$args = array(
|
||||
'title' => esc_html( $this->name() ),
|
||||
);
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( $args );
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_languages( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'languages' );
|
||||
if ( $collector ) {
|
||||
$output['languages'] = new QM_Output_Html_Languages( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_languages', 81, 2 );
|
||||
198
wordpress_plugins/query-monitor/output/html/logger.php
Normal file
198
wordpress_plugins/query-monitor/output/html/logger.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
/**
|
||||
* PSR-3 compatible logging output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Logger extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Logger Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 12 );
|
||||
add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Logger', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['logs'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$levels = array_map( 'ucfirst', $this->collector->get_levels() );
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'type', $levels, __( 'Level', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col" class="qm-col-message">' . esc_html__( 'Message', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'component', $data['components'], __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['logs'] as $row ) {
|
||||
$component = $row['trace']->get_component();
|
||||
|
||||
$row_attr = array();
|
||||
$row_attr['data-qm-component'] = $component->name;
|
||||
$row_attr['data-qm-type'] = ucfirst( $row['level'] );
|
||||
|
||||
$attr = '';
|
||||
|
||||
foreach ( $row_attr as $a => $v ) {
|
||||
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
||||
}
|
||||
|
||||
$is_warning = in_array( $row['level'], $this->collector->get_warning_levels(), true );
|
||||
|
||||
if ( $is_warning ) {
|
||||
$class = 'qm-warn';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
|
||||
echo '<tr' . $attr . ' class="' . esc_attr( $class ) . '">'; // WPCS: XSS ok.
|
||||
|
||||
echo '<td scope="row" class="qm-nowrap">';
|
||||
|
||||
if ( $is_warning ) {
|
||||
echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
} else {
|
||||
echo '<span class="dashicons" aria-hidden="true"></span>';
|
||||
}
|
||||
|
||||
echo esc_html( ucfirst( $row['level'] ) );
|
||||
echo '</td>';
|
||||
|
||||
if ( 'dump' === $row['type'] ) {
|
||||
printf(
|
||||
'<td><pre>%s</pre></td>',
|
||||
esc_html( $row['message'] )
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
'<td>%s</td>',
|
||||
esc_html( $row['message'] )
|
||||
);
|
||||
}
|
||||
|
||||
$stack = array();
|
||||
$filtered_trace = $row['trace']->get_display_trace();
|
||||
|
||||
foreach ( $filtered_trace as $item ) {
|
||||
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
||||
}
|
||||
|
||||
$caller = array_shift( $stack );
|
||||
|
||||
echo '<td class="qm-has-toggle qm-nowrap qm-ltr">';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
echo '<ol>';
|
||||
|
||||
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
||||
}
|
||||
|
||||
echo '</ol></td>';
|
||||
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
esc_html( $component->name )
|
||||
);
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_class( array $class ) {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['logs'] ) ) {
|
||||
return $class;
|
||||
}
|
||||
|
||||
foreach ( $data['logs'] as $log ) {
|
||||
if ( in_array( $log['level'], $this->collector->get_warning_levels(), true ) ) {
|
||||
$class[] = 'qm-warning';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['logs'] ) ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$key = 'log';
|
||||
|
||||
foreach ( $data['logs'] as $log ) {
|
||||
if ( in_array( $log['level'], $this->collector->get_warning_levels(), true ) ) {
|
||||
$key = 'warning';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$count = count( $data['logs'] );
|
||||
|
||||
/* translators: %s: Number of logs that are available */
|
||||
$label = __( 'Logs (%s)', 'query-monitor' );
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'id' => "query-monitor-logger-{$key}",
|
||||
'title' => esc_html( sprintf(
|
||||
$label,
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_logger( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'logger' );
|
||||
if ( $collector ) {
|
||||
$output['logger'] = new QM_Output_Html_Logger( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_logger', 12, 2 );
|
||||
297
wordpress_plugins/query-monitor/output/html/overview.php
Normal file
297
wordpress_plugins/query-monitor/output/html/overview.php
Normal file
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
/**
|
||||
* General overview output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Overview extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Overview Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/title', array( $this, 'admin_title' ), 10 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Overview', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$db_query_num = null;
|
||||
$db_queries = QM_Collectors::get( 'db_queries' );
|
||||
|
||||
if ( $db_queries ) {
|
||||
# @TODO: make this less derpy:
|
||||
$db_queries_data = $db_queries->get_data();
|
||||
if ( isset( $db_queries_data['types'] ) && isset( $db_queries_data['total_time'] ) ) {
|
||||
$db_query_num = $db_queries_data['types'];
|
||||
$db_query_time = $db_queries_data['total_time'];
|
||||
}
|
||||
}
|
||||
|
||||
$raw_request = QM_Collectors::get( 'raw_request' );
|
||||
$cache = QM_Collectors::get( 'cache' );
|
||||
|
||||
$qm_broken = __( 'A JavaScript problem on the page is preventing Query Monitor from working correctly. jQuery may have been blocked from loading.', 'query-monitor' );
|
||||
$ajax_errors = __( 'PHP errors were triggered during an Ajax request. See your browser developer console for details.', 'query-monitor' );
|
||||
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<section id="qm-broken">';
|
||||
echo '<p class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>' . esc_html( $qm_broken ) . '</p>';
|
||||
echo '</section>';
|
||||
|
||||
echo '<section id="qm-ajax-errors">';
|
||||
echo '<p class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>' . esc_html( $ajax_errors ) . '</p>';
|
||||
echo '</section>';
|
||||
|
||||
if ( $raw_request ) {
|
||||
echo '<section id="qm-overview-raw-request">';
|
||||
$raw_data = $raw_request->get_data();
|
||||
|
||||
if ( ! empty( $raw_data['response']['status'] ) ) {
|
||||
$status = $raw_data['response']['status'];
|
||||
} else {
|
||||
$status = __( 'Unknown HTTP Response Code', 'query-monitor' );
|
||||
}
|
||||
|
||||
printf(
|
||||
'<h3>%1$s %2$s → %3$s</h3>',
|
||||
esc_html( $raw_data['request']['method'] ),
|
||||
esc_html( $raw_data['request']['url'] ),
|
||||
esc_html( $status )
|
||||
);
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
echo '<div class="qm-boxed">';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Page Generation Time', 'query-monitor' ) . '</h3>';
|
||||
echo '<p>';
|
||||
echo esc_html( number_format_i18n( $data['time_taken'], 4 ) );
|
||||
|
||||
if ( $data['time_limit'] > 0 ) {
|
||||
if ( $data['display_time_usage_warning'] ) {
|
||||
echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
} else {
|
||||
echo '<br><span class="qm-info">';
|
||||
}
|
||||
echo esc_html( sprintf(
|
||||
/* translators: 1: Percentage of time limit used, 2: Time limit in seconds */
|
||||
__( '%1$s%% of %2$ss limit', 'query-monitor' ),
|
||||
number_format_i18n( $data['time_usage'], 1 ),
|
||||
number_format_i18n( $data['time_limit'] )
|
||||
) );
|
||||
echo '</span>';
|
||||
} else {
|
||||
echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
printf(
|
||||
/* translators: 1: Name of the PHP directive, 2: Value of the PHP directive */
|
||||
esc_html__( 'No execution time limit. The %1$s PHP configuration directive is set to %2$s.', 'query-monitor' ),
|
||||
'<code>max_execution_time</code>',
|
||||
'0'
|
||||
);
|
||||
echo '</span>';
|
||||
}
|
||||
echo '</p>';
|
||||
echo '</section>';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Peak Memory Usage', 'query-monitor' ) . '</h3>';
|
||||
echo '<p>';
|
||||
|
||||
if ( empty( $data['memory'] ) ) {
|
||||
esc_html_e( 'Unknown', 'query-monitor' );
|
||||
} else {
|
||||
echo esc_html( sprintf(
|
||||
/* translators: %s: Memory used in kilobytes */
|
||||
__( '%s kB', 'query-monitor' ),
|
||||
number_format_i18n( $data['memory'] / 1024 )
|
||||
) );
|
||||
|
||||
if ( $data['memory_limit'] > 0 ) {
|
||||
if ( $data['display_memory_usage_warning'] ) {
|
||||
echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
} else {
|
||||
echo '<br><span class="qm-info">';
|
||||
}
|
||||
echo esc_html( sprintf(
|
||||
/* translators: 1: Percentage of memory limit used, 2: Memory limit in kilobytes */
|
||||
__( '%1$s%% of %2$s kB limit', 'query-monitor' ),
|
||||
number_format_i18n( $data['memory_usage'], 1 ),
|
||||
number_format_i18n( $data['memory_limit'] / 1024 )
|
||||
) );
|
||||
echo '</span>';
|
||||
} else {
|
||||
echo '<br><span class="qm-warn"><span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
printf(
|
||||
/* translators: 1: Name of the PHP directive, 2: Value of the PHP directive */
|
||||
esc_html__( 'No memory limit. The %1$s PHP configuration directive is set to %2$s.', 'query-monitor' ),
|
||||
'<code>memory_limit</code>',
|
||||
'0'
|
||||
);
|
||||
echo '</span>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</p>';
|
||||
echo '</section>';
|
||||
|
||||
if ( isset( $db_queries_data ) ) {
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Database Query Time', 'query-monitor' ) . '</h3>';
|
||||
echo '<p>';
|
||||
echo esc_html( number_format_i18n( $db_queries_data['total_time'], 4 ) );
|
||||
echo '</p>';
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
if ( isset( $db_query_num ) && isset( $db_queries_data ) ) {
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Database Queries', 'query-monitor' ) . '</h3>';
|
||||
echo '<p>';
|
||||
|
||||
if ( ! isset( $db_query_num['SELECT'] ) || count( $db_query_num ) > 1 ) {
|
||||
foreach ( $db_query_num as $type_name => $type_count ) {
|
||||
printf(
|
||||
'<button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="type" data-qm-value="%1$s">%2$s: %3$s</button><br>',
|
||||
esc_attr( $type_name ),
|
||||
esc_html( $type_name ),
|
||||
esc_html( number_format_i18n( $type_count ) )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
printf(
|
||||
'<button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="type" data-qm-value="">%1$s: %2$s</button>',
|
||||
esc_html( _x( 'Total', 'database queries', 'query-monitor' ) ),
|
||||
esc_html( number_format_i18n( $db_queries_data['total_qs'] ) )
|
||||
);
|
||||
|
||||
echo '</p>';
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
if ( $cache ) {
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Object Cache', 'query-monitor' ) . '</h3>';
|
||||
|
||||
$cache_data = $cache->get_data();
|
||||
if ( isset( $cache_data['stats'] ) && isset( $cache_data['cache_hit_percentage'] ) ) {
|
||||
$cache_hit_percentage = $cache_data['cache_hit_percentage'];
|
||||
}
|
||||
|
||||
if ( isset( $cache_hit_percentage ) ) {
|
||||
echo '<p>';
|
||||
echo esc_html( sprintf(
|
||||
/* translators: 1: Cache hit rate percentage, 2: number of cache hits, 3: number of cache misses */
|
||||
__( '%1$s%% hit rate (%2$s hits, %3$s misses)', 'query-monitor' ),
|
||||
number_format_i18n( $cache_hit_percentage, 1 ),
|
||||
number_format_i18n( $cache_data['stats']['cache_hits'], 0 ),
|
||||
number_format_i18n( $cache_data['stats']['cache_misses'], 0 )
|
||||
) );
|
||||
echo '</p>';
|
||||
} else {
|
||||
echo '<p>';
|
||||
echo esc_html__( 'Object cache statistics are not available', 'query-monitor' );
|
||||
echo '</p>';
|
||||
}
|
||||
|
||||
if ( $cache_data['has_object_cache'] ) {
|
||||
echo '<p><span class="qm-info">';
|
||||
printf(
|
||||
'<a href="%s" class="qm-link">%s</a>',
|
||||
esc_url( network_admin_url( 'plugins.php?plugin_status=dropins' ) ),
|
||||
esc_html__( 'External object cache in use', 'query-monitor' )
|
||||
);
|
||||
echo '</span></p>';
|
||||
} else {
|
||||
echo '<p>';
|
||||
echo esc_html__( 'External object cache not in use', 'query-monitor' );
|
||||
echo '</p>';
|
||||
|
||||
$potentials = array_filter( $cache_data['object_cache_extensions'] );
|
||||
|
||||
if ( ! empty( $potentials ) ) {
|
||||
foreach ( $potentials as $name => $value ) {
|
||||
echo '<p>';
|
||||
echo esc_html( sprintf(
|
||||
/* translators: %s: PHP extension name */
|
||||
__( 'The %s extension for PHP is installed but is not in use by WordPress', 'query-monitor' ),
|
||||
$name
|
||||
) );
|
||||
echo '</p>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $cache_data['has_opcode_cache'] ) {
|
||||
foreach ( array_filter( $cache_data['opcode_cache_extensions'] ) as $opcache_name => $opcache_state ) {
|
||||
echo '<p>';
|
||||
echo esc_html( sprintf(
|
||||
/* translators: %s: Name of cache driver */
|
||||
__( 'Opcode cache in use: %s', 'query-monitor' ),
|
||||
$opcache_name
|
||||
) );
|
||||
echo '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_title( array $existing ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['memory'] ) ) {
|
||||
$memory = '??';
|
||||
} else {
|
||||
$memory = number_format_i18n( ( $data['memory'] / 1024 ), 0 );
|
||||
}
|
||||
|
||||
$title[] = sprintf(
|
||||
/* translators: %s: Page load time in seconds with a decimal fraction */
|
||||
esc_html_x( '%s S', 'Page load time', 'query-monitor' ),
|
||||
number_format_i18n( $data['time_taken'], 2 )
|
||||
);
|
||||
$title[] = sprintf(
|
||||
/* translators: %s: Memory usage in kilobytes */
|
||||
esc_html_x( '%s kB', 'Memory usage', 'query-monitor' ),
|
||||
$memory
|
||||
);
|
||||
|
||||
foreach ( $title as &$t ) {
|
||||
$t = preg_replace( '#\s?([^0-9,\.]+)#', '<small>$1</small>', $t );
|
||||
}
|
||||
|
||||
$title = array_merge( $existing, $title );
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_overview( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'overview' );
|
||||
if ( $collector ) {
|
||||
$output['overview'] = new QM_Output_Html_Overview( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_overview', 10, 2 );
|
||||
304
wordpress_plugins/query-monitor/output/html/php_errors.php
Normal file
304
wordpress_plugins/query-monitor/output/html/php_errors.php
Normal file
@@ -0,0 +1,304 @@
|
||||
<?php
|
||||
/**
|
||||
* PHP error output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_PHP_Errors extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_PHP_Errors Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 10 );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 10 );
|
||||
add_filter( 'qm/output/menu_class', array( $this, 'admin_class' ) );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'PHP Errors', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['errors'] ) && empty( $data['silenced'] ) && empty( $data['suppressed'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$levels = array(
|
||||
'Warning',
|
||||
'Notice',
|
||||
'Strict',
|
||||
'Deprecated',
|
||||
);
|
||||
$components = $data['components'];
|
||||
|
||||
usort( $components, 'strcasecmp' );
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'type', $levels, __( 'Level', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '<th scope="col" class="qm-col-message">' . esc_html__( 'Message', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Count', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Location', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-filterable-column">';
|
||||
echo $this->build_filter( 'component', $components, __( 'Component', 'query-monitor' ) ); // WPCS: XSS ok.
|
||||
echo '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $this->collector->types as $error_group => $error_types ) {
|
||||
foreach ( $error_types as $type => $title ) {
|
||||
|
||||
if ( ! isset( $data[ $error_group ][ $type ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $data[ $error_group ][ $type ] as $error_key => $error ) {
|
||||
|
||||
$row_attr = array();
|
||||
$row_attr['data-qm-type'] = ucfirst( $type );
|
||||
$row_attr['data-qm-key'] = $error_key;
|
||||
|
||||
if ( $error['trace'] ) {
|
||||
$component = $error['trace']->get_component();
|
||||
$row_attr['data-qm-component'] = $component->name;
|
||||
|
||||
if ( 'core' !== $component->context ) {
|
||||
$row_attr['data-qm-component'] .= ' non-core';
|
||||
}
|
||||
}
|
||||
|
||||
$attr = '';
|
||||
|
||||
foreach ( $row_attr as $a => $v ) {
|
||||
$attr .= ' ' . $a . '="' . esc_attr( $v ) . '"';
|
||||
}
|
||||
|
||||
$is_warning = ( 'errors' === $error_group && 'warning' === $type );
|
||||
|
||||
if ( $is_warning ) {
|
||||
$class = 'qm-warn';
|
||||
} else {
|
||||
$class = '';
|
||||
}
|
||||
|
||||
echo '<tr ' . $attr . 'class="' . esc_attr( $class ) . '">'; // WPCS: XSS ok.
|
||||
echo '<td scope="row" class="qm-nowrap">';
|
||||
|
||||
if ( $is_warning ) {
|
||||
echo '<span class="dashicons dashicons-warning" aria-hidden="true"></span>';
|
||||
} else {
|
||||
echo '<span class="dashicons" aria-hidden="true"></span>';
|
||||
}
|
||||
|
||||
echo esc_html( $title );
|
||||
echo '</td>';
|
||||
|
||||
echo '<td class="qm-ltr">' . esc_html( $error['message'] ) . '</td>';
|
||||
echo '<td class="qm-num">' . esc_html( number_format_i18n( $error['calls'] ) ) . '</td>';
|
||||
|
||||
$stack = array();
|
||||
|
||||
if ( $error['trace'] ) {
|
||||
$filtered_trace = $error['trace']->get_display_trace();
|
||||
|
||||
// debug_backtrace() (used within QM_Backtrace) doesn't like being used within an error handler so
|
||||
// we need to handle its somewhat unreliable stack trace items.
|
||||
// https://bugs.php.net/bug.php?id=39070
|
||||
// https://bugs.php.net/bug.php?id=64987
|
||||
foreach ( $filtered_trace as $i => $item ) {
|
||||
if ( isset( $item['file'] ) && isset( $item['line'] ) ) {
|
||||
$stack[] = self::output_filename( $item['display'], $item['file'], $item['line'] );
|
||||
} elseif ( 0 === $i ) {
|
||||
$stack[] = self::output_filename( $item['display'], $error['file'], $error['line'] );
|
||||
} else {
|
||||
$stack[] = $item['display'] . '<br><span class="qm-info qm-supplemental"><em>' . __( 'Unknown location', 'query-monitor' ) . '</em></span>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '<td class="qm-row-caller qm-row-stack qm-nowrap qm-ltr qm-has-toggle">';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
echo '<ol>';
|
||||
echo '<li>';
|
||||
echo self::output_filename( $error['filename'] . ':' . $error['line'], $error['file'], $error['line'], true ); // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
||||
}
|
||||
|
||||
echo '</ol></td>';
|
||||
|
||||
if ( ! empty( $component ) ) {
|
||||
echo '<td class="qm-nowrap">' . esc_html( $component->name ) . '</td>';
|
||||
} else {
|
||||
echo '<td><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></td>';
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_class( array $class ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( ! empty( $data['errors'] ) ) {
|
||||
foreach ( $data['errors'] as $type => $errors ) {
|
||||
$class[] = 'qm-' . $type;
|
||||
}
|
||||
}
|
||||
|
||||
return $class;
|
||||
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$menu_label = array();
|
||||
|
||||
$types = array(
|
||||
/* translators: %s: Number of deprecated PHP errors */
|
||||
'deprecated' => _nx_noop( '%s Deprecated', '%s Deprecated', 'PHP error level', 'query-monitor' ),
|
||||
/* translators: %s: Number of strict PHP errors */
|
||||
'strict' => _nx_noop( '%s Strict', '%s Stricts', 'PHP error level', 'query-monitor' ),
|
||||
/* translators: %s: Number of PHP notices */
|
||||
'notice' => _nx_noop( '%s Notice', '%s Notices', 'PHP error level', 'query-monitor' ),
|
||||
/* translators: %s: Number of PHP warnings */
|
||||
'warning' => _nx_noop( '%s Warning', '%s Warnings', 'PHP error level', 'query-monitor' ),
|
||||
);
|
||||
|
||||
$key = 'quiet';
|
||||
$generic = false;
|
||||
|
||||
foreach ( $types as $type => $label ) {
|
||||
|
||||
$count = 0;
|
||||
$has_errors = false;
|
||||
|
||||
if ( isset( $data['suppressed'][ $type ] ) ) {
|
||||
$has_errors = true;
|
||||
$generic = true;
|
||||
}
|
||||
if ( isset( $data['silenced'][ $type ] ) ) {
|
||||
$has_errors = true;
|
||||
$generic = true;
|
||||
}
|
||||
if ( isset( $data['errors'][ $type ] ) ) {
|
||||
$has_errors = true;
|
||||
$key = $type;
|
||||
$count += array_sum( wp_list_pluck( $data['errors'][ $type ], 'calls' ) );
|
||||
}
|
||||
|
||||
if ( ! $has_errors ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $count ) {
|
||||
$label = sprintf(
|
||||
translate_nooped_plural(
|
||||
$label,
|
||||
$count,
|
||||
'query-monitor'
|
||||
),
|
||||
number_format_i18n( $count )
|
||||
);
|
||||
$menu_label[] = $label;
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $menu_label ) && ! $generic ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
/* translators: %s: List of PHP error types */
|
||||
$title = __( 'PHP Errors (%s)', 'query-monitor' );
|
||||
|
||||
/* translators: used between list items, there is a space after the comma */
|
||||
$sep = __( ', ', 'query-monitor' );
|
||||
|
||||
if ( count( $menu_label ) ) {
|
||||
$title = sprintf(
|
||||
$title,
|
||||
implode( $sep, array_reverse( $menu_label ) )
|
||||
);
|
||||
} else {
|
||||
$title = __( 'PHP Errors', 'query-monitor' );
|
||||
}
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'id' => "query-monitor-{$key}s",
|
||||
'title' => $title,
|
||||
) );
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
if ( ! isset( $menu[ $this->collector->id() ] ) ) {
|
||||
return $menu;
|
||||
}
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$count = 0;
|
||||
$types = array(
|
||||
'suppressed',
|
||||
'silenced',
|
||||
'errors',
|
||||
);
|
||||
|
||||
foreach ( $types as $type ) {
|
||||
if ( ! empty( $data[ $type ] ) ) {
|
||||
foreach ( $data[ $type ] as $errors ) {
|
||||
$count += array_sum( wp_list_pluck( $errors, 'calls' ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$menu[ $this->collector->id() ]['title'] = esc_html( sprintf(
|
||||
/* translators: %s: Number of errors */
|
||||
__( 'PHP Errors (%s)', 'query-monitor' ),
|
||||
number_format_i18n( $count )
|
||||
) );
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_php_errors( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'php_errors' );
|
||||
if ( $collector ) {
|
||||
$output['php_errors'] = new QM_Output_Html_PHP_Errors( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_php_errors', 110, 2 );
|
||||
228
wordpress_plugins/query-monitor/output/html/request.php
Normal file
228
wordpress_plugins/query-monitor/output/html/request.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
/**
|
||||
* Request data output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Request extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Request Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 50 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Request', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
$db_queries = QM_Collectors::get( 'db_queries' );
|
||||
$raw_request = QM_Collectors::get( 'raw_request' );
|
||||
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
foreach ( array(
|
||||
'request' => __( 'Request', 'query-monitor' ),
|
||||
'matched_rule' => __( 'Matched Rule', 'query-monitor' ),
|
||||
'matched_query' => __( 'Matched Query', 'query-monitor' ),
|
||||
'query_string' => __( 'Query String', 'query-monitor' ),
|
||||
) as $item => $name ) {
|
||||
if ( is_admin() && ! isset( $data['request'][ $item ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! empty( $data['request'][ $item ] ) ) {
|
||||
if ( in_array( $item, array( 'request', 'matched_query', 'query_string' ), true ) ) {
|
||||
$value = self::format_url( $data['request'][ $item ] );
|
||||
} else {
|
||||
$value = esc_html( $data['request'][ $item ] );
|
||||
}
|
||||
} else {
|
||||
$value = '<em>' . esc_html__( 'none', 'query-monitor' ) . '</em>';
|
||||
}
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html( $name ) . '</h3>';
|
||||
echo '<p class="qm-ltr"><code>' . $value . '</code></p>'; // WPCS: XSS ok.
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
|
||||
echo '<div class="qm-boxed qm-boxed-wrap">';
|
||||
|
||||
if ( ! empty( $data['matching_rewrites'] ) ) {
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'All Matching Rewrite Rules', 'query-monitor' ) . '</h3>';
|
||||
echo '<table>';
|
||||
|
||||
foreach ( $data['matching_rewrites'] as $rule => $query ) {
|
||||
$query = str_replace( 'index.php?', '', $query );
|
||||
|
||||
echo '<tr>';
|
||||
echo '<td class="qm-ltr"><code>' . esc_html( $rule ) . '</code></td>';
|
||||
echo '<td class="qm-ltr"><code>';
|
||||
echo self::format_url( $query ); // WPCS: XSS ok.
|
||||
echo '</code></td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>';
|
||||
esc_html_e( 'Query Vars', 'query-monitor' );
|
||||
echo '</h3>';
|
||||
|
||||
if ( $db_queries ) {
|
||||
$db_queries_data = $db_queries->get_data();
|
||||
if ( ! empty( $db_queries_data['dbs']['$wpdb']->has_main_query ) ) {
|
||||
printf(
|
||||
'<p><button class="qm-filter-trigger" data-qm-target="db_queries-wpdb" data-qm-filter="caller" data-qm-value="qm-main-query">%s</button></p>',
|
||||
esc_html__( 'View Main Query', 'query-monitor' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $data['qvars'] ) ) {
|
||||
|
||||
echo '<table>';
|
||||
|
||||
foreach ( $data['qvars'] as $var => $value ) {
|
||||
|
||||
echo '<tr>';
|
||||
|
||||
if ( isset( $data['plugin_qvars'][ $var ] ) ) {
|
||||
echo '<th scope="row" class="qm-ltr"><span class="qm-current">' . esc_html( $var ) . '</span></td>';
|
||||
} else {
|
||||
echo '<th scope="row" class="qm-ltr">' . esc_html( $var ) . '</td>';
|
||||
}
|
||||
|
||||
if ( is_array( $value ) || is_object( $value ) ) {
|
||||
echo '<td class="qm-ltr"><pre>';
|
||||
echo esc_html( print_r( $value, true ) );
|
||||
echo '</pre></td>';
|
||||
} else {
|
||||
echo '<td class="qm-ltr qm-wrap">' . esc_html( $value ) . '</td>';
|
||||
}
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
echo '</table>';
|
||||
|
||||
} else {
|
||||
|
||||
echo '<p><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></p>';
|
||||
|
||||
}
|
||||
|
||||
echo '</section>';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Response', 'query-monitor' ) . '</h3>';
|
||||
echo '<h4>' . esc_html__( 'Queried Object', 'query-monitor' ) . '</h4>';
|
||||
|
||||
if ( ! empty( $data['queried_object'] ) ) {
|
||||
printf( // WPCS: XSS ok.
|
||||
'<p>%1$s (%2$s)</p>',
|
||||
esc_html( $data['queried_object']['title'] ),
|
||||
esc_html( get_class( $data['queried_object']['data'] ) )
|
||||
);
|
||||
} else {
|
||||
echo '<p><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></p>';
|
||||
}
|
||||
|
||||
echo '<h4>' . esc_html__( 'Current User', 'query-monitor' ) . '</h4>';
|
||||
|
||||
if ( ! empty( $data['user']['data'] ) ) {
|
||||
printf( // WPCS: XSS ok.
|
||||
'<p>%s</p>',
|
||||
esc_html( $data['user']['title'] )
|
||||
);
|
||||
} else {
|
||||
echo '<p><em>' . esc_html__( 'none', 'query-monitor' ) . '</em></p>';
|
||||
}
|
||||
|
||||
if ( ! empty( $data['multisite'] ) ) {
|
||||
echo '<h4>' . esc_html__( 'Multisite', 'query-monitor' ) . '</h4>';
|
||||
|
||||
foreach ( $data['multisite'] as $var => $value ) {
|
||||
printf( // WPCS: XSS ok.
|
||||
'<p>%s</p>',
|
||||
esc_html( $value['title'] )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
echo '</section>';
|
||||
|
||||
if ( ! empty( $raw_request ) ) {
|
||||
$raw_data = $raw_request->get_data();
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Request Data', 'query-monitor' ) . '</h3>';
|
||||
echo '<table>';
|
||||
|
||||
foreach ( array(
|
||||
'ip' => __( 'Remote IP', 'query-monitor' ),
|
||||
'method' => __( 'HTTP method', 'query-monitor' ),
|
||||
'url' => __( 'Requested URL', 'query-monitor' ),
|
||||
) as $item => $name ) {
|
||||
echo '<tr>';
|
||||
echo '<th scope="row">' . esc_html( $name ) . '</td>';
|
||||
echo '<td class="qm-ltr qm-wrap">' . esc_html( $raw_data['request'][ $item ] ) . '</td>';
|
||||
echo '</tr>';
|
||||
}
|
||||
|
||||
echo '</table>';
|
||||
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$count = isset( $data['plugin_qvars'] ) ? count( $data['plugin_qvars'] ) : 0;
|
||||
|
||||
$title = ( empty( $count ) )
|
||||
? __( 'Request', 'query-monitor' )
|
||||
/* translators: %s: Number of additional query variables */
|
||||
: __( 'Request (+%s)', 'query-monitor' );
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html( sprintf(
|
||||
$title,
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_request( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'request' );
|
||||
if ( $collector ) {
|
||||
$output['request'] = new QM_Output_Html_Request( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_request', 60, 2 );
|
||||
220
wordpress_plugins/query-monitor/output/html/theme.php
Normal file
220
wordpress_plugins/query-monitor/output/html/theme.php
Normal file
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
/**
|
||||
* Template and theme output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Theme extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Theme Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 60 );
|
||||
add_filter( 'qm/output/panel_menus', array( $this, 'panel_menu' ), 60 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Theme', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['stylesheet'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Theme', 'query-monitor' ) . '</h3>';
|
||||
echo '<p>' . esc_html( $data['stylesheet'] ) . '</p>';
|
||||
|
||||
if ( $data['is_child_theme'] ) {
|
||||
echo '<h3>' . esc_html__( 'Parent Theme', 'query-monitor' ) . '</h3>';
|
||||
echo '<p>' . esc_html( $data['template'] ) . '</p>';
|
||||
}
|
||||
|
||||
echo '</section>';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Template File', 'query-monitor' ) . '</h3>';
|
||||
|
||||
if ( ! empty( $data['template_path'] ) ) {
|
||||
if ( $data['is_child_theme'] ) {
|
||||
$display = $data['theme_template_file'];
|
||||
} else {
|
||||
$display = $data['template_file'];
|
||||
}
|
||||
if ( self::has_clickable_links() ) {
|
||||
$file = $data['template_path'];
|
||||
} else {
|
||||
$file = false;
|
||||
}
|
||||
echo '<p class="qm-ltr">' . self::output_filename( $display, $file, 0, true ) . '</p>'; // WPCS: XSS ok.
|
||||
} else {
|
||||
echo '<p><em>' . esc_html__( 'Unknown', 'query-monitor' ) . '</em></p>';
|
||||
}
|
||||
|
||||
if ( ! empty( $data['template_altered'] ) ) {
|
||||
printf(
|
||||
'<p><button class="qm-filter-trigger qm-filter-info" data-qm-target="response-concerned_hooks">%s</button></p>',
|
||||
esc_html__( 'Template Hooks in Use', 'query-monitor' )
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! empty( $data['template_hierarchy'] ) ) {
|
||||
echo '<h3>' . esc_html__( 'Template Hierarchy', 'query-monitor' ) . '</h3>';
|
||||
echo '<ol class="qm-ltr"><li>' . implode( '</li><li>', array_map( 'esc_html', $data['template_hierarchy'] ) ) . '</li></ol>';
|
||||
}
|
||||
|
||||
echo '</section>';
|
||||
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Template Parts', 'query-monitor' ) . '</h3>';
|
||||
|
||||
if ( ! empty( $data['template_parts'] ) ) {
|
||||
|
||||
if ( $data['is_child_theme'] ) {
|
||||
$parts = $data['theme_template_parts'];
|
||||
} else {
|
||||
$parts = $data['template_parts'];
|
||||
}
|
||||
|
||||
echo '<ul class="qm-ltr">';
|
||||
|
||||
foreach ( $parts as $filename => $display ) {
|
||||
echo '<li>';
|
||||
|
||||
if ( self::has_clickable_links() ) {
|
||||
echo self::output_filename( $display, $filename, 0, true ); // WPCS: XSS ok.
|
||||
} else {
|
||||
echo esc_html( $display );
|
||||
}
|
||||
|
||||
if ( $data['count_template_parts'][ $filename ] > 1 ) {
|
||||
$count = sprintf(
|
||||
/* translators: %s: The number of times that a template part file was included in the page */
|
||||
_nx( 'Included %s time', 'Included %s times', $data['count_template_parts'][ $filename ], 'template parts', 'query-monitor' ),
|
||||
esc_html( number_format_i18n( $data['count_template_parts'][ $filename ] ) )
|
||||
);
|
||||
echo '<br><span class="qm-info qm-supplemental">' . esc_html( $count ) . '</span>';
|
||||
}
|
||||
echo '</li>';
|
||||
}
|
||||
|
||||
echo '</ul>';
|
||||
|
||||
} else {
|
||||
echo '<p><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></p>';
|
||||
}
|
||||
|
||||
if ( $data['has_template_part_action'] ) {
|
||||
echo '<h4>' . esc_html__( 'Not Loaded', 'query-monitor' ) . '</h4>';
|
||||
|
||||
if ( ! empty( $data['unsuccessful_template_parts'] ) ) {
|
||||
echo '<ul>';
|
||||
|
||||
foreach ( $data['unsuccessful_template_parts'] as $requested ) {
|
||||
if ( $requested['name'] ) {
|
||||
echo '<li>';
|
||||
$text = $requested['slug'] . '-' . $requested['name'] . '.php';
|
||||
echo self::output_filename( $text, $requested['caller']['file'], $requested['caller']['line'], true ); // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
}
|
||||
|
||||
echo '<li>';
|
||||
$text = $requested['slug'] . '.php';
|
||||
echo self::output_filename( $text, $requested['caller']['file'], $requested['caller']['line'], true ); // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
}
|
||||
|
||||
echo '</ul>';
|
||||
} elseif ( $data['has_template_part_action'] ) {
|
||||
echo '<p><em>' . esc_html__( 'None', 'query-monitor' ) . '</em></p>';
|
||||
}
|
||||
}
|
||||
|
||||
echo '</section>';
|
||||
|
||||
if ( ! empty( $data['timber_files'] ) ) {
|
||||
echo '<section>';
|
||||
echo '<h3>' . esc_html__( 'Twig Template Files', 'query-monitor' ) . '</h3>';
|
||||
echo '<ul class="qm-ltr">';
|
||||
|
||||
foreach ( $data['timber_files'] as $filename ) {
|
||||
echo '<li>' . esc_html( $filename ) . '</li>';
|
||||
}
|
||||
|
||||
echo '</ul>';
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
if ( ! empty( $data['body_class'] ) ) {
|
||||
echo '<section>';
|
||||
|
||||
echo '<h3>' . esc_html__( 'Body Classes', 'query-monitor' ) . '</h3>';
|
||||
echo '<ul class="qm-ltr">';
|
||||
|
||||
foreach ( $data['body_class'] as $class ) {
|
||||
echo '<li>' . esc_html( $class ) . '</li>';
|
||||
}
|
||||
|
||||
echo '</ul>';
|
||||
echo '</section>';
|
||||
}
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( isset( $data['template_file'] ) ) {
|
||||
$name = ( $data['is_child_theme'] ) ? $data['theme_template_file'] : $data['template_file'];
|
||||
} else {
|
||||
$name = __( 'Unknown', 'query-monitor' );
|
||||
}
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html( sprintf(
|
||||
/* translators: %s: Template file name */
|
||||
__( 'Template: %s', 'query-monitor' ),
|
||||
$name
|
||||
) ),
|
||||
) );
|
||||
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
public function panel_menu( array $menu ) {
|
||||
if ( isset( $menu[ $this->collector->id() ] ) ) {
|
||||
$menu[ $this->collector->id() ]['title'] = __( 'Template', 'query-monitor' );
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_theme( array $output, QM_Collectors $collectors ) {
|
||||
if ( is_admin() ) {
|
||||
return $output;
|
||||
}
|
||||
$collector = QM_Collectors::get( 'response' );
|
||||
if ( $collector ) {
|
||||
$output['response'] = new QM_Output_Html_Theme( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_theme', 70, 2 );
|
||||
207
wordpress_plugins/query-monitor/output/html/timing.php
Normal file
207
wordpress_plugins/query-monitor/output/html/timing.php
Normal file
@@ -0,0 +1,207 @@
|
||||
<?php
|
||||
/**
|
||||
* Timing and profiling output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Timing extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Timing Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 15 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Timing', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( empty( $data['timing'] ) && empty( $data['warning'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Tracked Function', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Started', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Stopped', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Time', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col" class="qm-num">' . esc_html__( 'Memory', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
if ( ! empty( $data['timing'] ) ) {
|
||||
foreach ( $data['timing'] as $row ) {
|
||||
|
||||
$component = $row['trace']->get_component();
|
||||
$trace = $row['trace']->get_filtered_trace();
|
||||
$file = self::output_filename( $row['function'], $trace[0]['file'], $trace[0]['line'] );
|
||||
|
||||
echo '<tr>';
|
||||
|
||||
if ( self::has_clickable_links() ) {
|
||||
echo '<td class="qm-ltr">';
|
||||
echo $file; // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-ltr qm-has-toggle">';
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<ol>';
|
||||
echo '<li>';
|
||||
echo $file; // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
echo '</ol></td>';
|
||||
}
|
||||
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( number_format_i18n( $row['start_time'], 4 ) )
|
||||
);
|
||||
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( number_format_i18n( $row['end_time'], 4 ) )
|
||||
);
|
||||
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( number_format_i18n( $row['function_time'], 4 ) )
|
||||
);
|
||||
|
||||
$mem = sprintf(
|
||||
/* translators: %s: Approximate memory used in kilobytes */
|
||||
__( '~%s kB', 'query-monitor' ),
|
||||
number_format_i18n( $row['function_memory'] / 1024 )
|
||||
);
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( $mem )
|
||||
);
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
esc_html( $component->name )
|
||||
);
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
if ( ! empty( $row['laps'] ) ) {
|
||||
foreach ( $row['laps'] as $lap_id => $lap ) {
|
||||
echo '<tr>';
|
||||
|
||||
echo '<td class="qm-ltr"><code>— ';
|
||||
echo esc_html( $row['function'] . ': ' . $lap_id );
|
||||
echo '</code></td>';
|
||||
|
||||
echo '<td class="qm-num"></td>';
|
||||
echo '<td class="qm-num"></td>';
|
||||
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( number_format_i18n( $lap['time_used'], 4 ) )
|
||||
);
|
||||
|
||||
$mem = sprintf(
|
||||
/* translators: %s: Approximate memory used in kilobytes */
|
||||
__( '~%s kB', 'query-monitor' ),
|
||||
number_format_i18n( $lap['memory_used'] / 1024 )
|
||||
);
|
||||
printf(
|
||||
'<td class="qm-num">%s</td>',
|
||||
esc_html( $mem )
|
||||
);
|
||||
echo '<td class="qm-nowrap"></td>';
|
||||
|
||||
echo '</tr>';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! empty( $data['warning'] ) ) {
|
||||
foreach ( $data['warning'] as $row ) {
|
||||
$component = $row['trace']->get_component();
|
||||
$trace = $row['trace']->get_filtered_trace();
|
||||
$file = self::output_filename( $row['function'], $trace[0]['file'], $trace[0]['line'] );
|
||||
|
||||
echo '<tr class="qm-warn">';
|
||||
if ( self::has_clickable_links() ) {
|
||||
echo '<td class="qm-ltr">';
|
||||
echo $file; // WPCS: XSS ok.
|
||||
echo '</td>';
|
||||
} else {
|
||||
echo '<td class="qm-ltr qm-has-toggle">';
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
echo '<ol>';
|
||||
echo '<li>';
|
||||
echo $file; // WPCS: XSS ok.
|
||||
echo '</li>';
|
||||
echo '</ol></td>';
|
||||
}
|
||||
|
||||
printf(
|
||||
'<td colspan="4"><span class="dashicons dashicons-warning" aria-hidden="true"></span>%s</td>',
|
||||
esc_html( $row['message'] )
|
||||
);
|
||||
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
esc_html( $component->name )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
echo '</tbody>';
|
||||
|
||||
$this->after_tabular_output();
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( ! empty( $data['timing'] ) || ! empty( $data['warning'] ) ) {
|
||||
$count = 0;
|
||||
if ( ! empty( $data['timing'] ) ) {
|
||||
$count += count( $data['timing'] );
|
||||
}
|
||||
if ( ! empty( $data['warning'] ) ) {
|
||||
$count += count( $data['warning'] );
|
||||
}
|
||||
/* translators: %s: Number of function timing results that are available */
|
||||
$label = __( 'Timings (%s)', 'query-monitor' );
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html( sprintf(
|
||||
$label,
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
}
|
||||
|
||||
return $menu;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_timing( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'timing' );
|
||||
if ( $collector ) {
|
||||
$output['timing'] = new QM_Output_Html_Timing( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_timing', 15, 2 );
|
||||
156
wordpress_plugins/query-monitor/output/html/transients.php
Normal file
156
wordpress_plugins/query-monitor/output/html/transients.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
/**
|
||||
* Transient storage output for HTML pages.
|
||||
*
|
||||
* @package query-monitor
|
||||
*/
|
||||
|
||||
class QM_Output_Html_Transients extends QM_Output_Html {
|
||||
|
||||
/**
|
||||
* Collector instance.
|
||||
*
|
||||
* @var QM_Collector_Transients Collector.
|
||||
*/
|
||||
protected $collector;
|
||||
|
||||
public function __construct( QM_Collector $collector ) {
|
||||
parent::__construct( $collector );
|
||||
add_filter( 'qm/output/menus', array( $this, 'admin_menu' ), 100 );
|
||||
}
|
||||
|
||||
public function name() {
|
||||
return __( 'Transients', 'query-monitor' );
|
||||
}
|
||||
|
||||
public function output() {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
|
||||
if ( ! empty( $data['trans'] ) ) {
|
||||
|
||||
$this->before_tabular_output();
|
||||
|
||||
echo '<thead>';
|
||||
echo '<tr>';
|
||||
echo '<th scope="col">' . esc_html__( 'Updated Transient', 'query-monitor' ) . '</th>';
|
||||
if ( $data['has_type'] ) {
|
||||
echo '<th scope="col">' . esc_html_x( 'Type', 'transient type', 'query-monitor' ) . '</th>';
|
||||
}
|
||||
echo '<th scope="col">' . esc_html__( 'Expiration', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html_x( 'Size', 'size of transient value', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Caller', 'query-monitor' ) . '</th>';
|
||||
echo '<th scope="col">' . esc_html__( 'Component', 'query-monitor' ) . '</th>';
|
||||
echo '</tr>';
|
||||
echo '</thead>';
|
||||
|
||||
echo '<tbody>';
|
||||
|
||||
foreach ( $data['trans'] as $row ) {
|
||||
$component = $row['component'];
|
||||
|
||||
echo '<tr>';
|
||||
printf(
|
||||
'<td class="qm-ltr"><code>%s</code></td>',
|
||||
esc_html( $row['name'] )
|
||||
);
|
||||
if ( $data['has_type'] ) {
|
||||
printf(
|
||||
'<td class="qm-ltr qm-nowrap">%s</td>',
|
||||
esc_html( $row['type'] )
|
||||
);
|
||||
}
|
||||
|
||||
if ( 0 === $row['expiration'] ) {
|
||||
printf(
|
||||
'<td class="qm-nowrap"><em>%s</em></td>',
|
||||
esc_html__( 'none', 'query-monitor' )
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s <span class="qm-info">(~%s)</span></td>',
|
||||
esc_html( $row['expiration'] ),
|
||||
esc_html( $row['exp_diff'] )
|
||||
);
|
||||
}
|
||||
|
||||
printf(
|
||||
'<td class="qm-nowrap">~%s</td>',
|
||||
esc_html( $row['size_formatted'] )
|
||||
);
|
||||
|
||||
$stack = array();
|
||||
|
||||
foreach ( $row['filtered_trace'] as $item ) {
|
||||
$stack[] = self::output_filename( $item['display'], $item['calling_file'], $item['calling_line'] );
|
||||
}
|
||||
|
||||
$caller = array_shift( $stack );
|
||||
|
||||
echo '<td class="qm-has-toggle qm-nowrap qm-ltr">';
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo self::build_toggler(); // WPCS: XSS ok;
|
||||
}
|
||||
|
||||
echo '<ol>';
|
||||
|
||||
echo "<li>{$caller}</li>"; // WPCS: XSS ok.
|
||||
|
||||
if ( ! empty( $stack ) ) {
|
||||
echo '<div class="qm-toggled"><li>' . implode( '</li><li>', $stack ) . '</li></div>'; // WPCS: XSS ok.
|
||||
}
|
||||
|
||||
echo '</ol></td>';
|
||||
|
||||
printf(
|
||||
'<td class="qm-nowrap">%s</td>',
|
||||
esc_html( $component->name )
|
||||
);
|
||||
|
||||
echo '</tr>';
|
||||
|
||||
}
|
||||
|
||||
$this->after_tabular_output();
|
||||
} else {
|
||||
$this->before_non_tabular_output();
|
||||
|
||||
$notice = __( 'No transients set.', 'query-monitor' );
|
||||
echo $this->build_notice( $notice ); // WPCS: XSS ok.
|
||||
|
||||
$this->after_non_tabular_output();
|
||||
}
|
||||
}
|
||||
|
||||
public function admin_menu( array $menu ) {
|
||||
|
||||
$data = $this->collector->get_data();
|
||||
$count = isset( $data['trans'] ) ? count( $data['trans'] ) : 0;
|
||||
|
||||
$title = ( empty( $count ) )
|
||||
? __( 'Transient Updates', 'query-monitor' )
|
||||
/* translators: %s: Number of transient values that were updated */
|
||||
: __( 'Transient Updates (%s)', 'query-monitor' );
|
||||
|
||||
$menu[ $this->collector->id() ] = $this->menu( array(
|
||||
'title' => esc_html( sprintf(
|
||||
$title,
|
||||
number_format_i18n( $count )
|
||||
) ),
|
||||
) );
|
||||
return $menu;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function register_qm_output_html_transients( array $output, QM_Collectors $collectors ) {
|
||||
$collector = QM_Collectors::get( 'transients' );
|
||||
if ( $collector ) {
|
||||
$output['transients'] = new QM_Output_Html_Transients( $collector );
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
add_filter( 'qm/outputter/html', 'register_qm_output_html_transients', 100, 2 );
|
||||
Reference in New Issue
Block a user