Completed
Push — add/double-encode-message ( 8b6530...2d4e84 )
by
unknown
14:26 queued 05:57
created

Jetpack_Search_Debug_Bar::instance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Singleton class instantiated by Jetpack_Searc_Debug_Bar::instance() that handles
5
 * rendering the Jetpack Search debug bar menu item and panel.
6
 */
7
class Jetpack_Search_Debug_Bar extends Debug_Bar_Panel {
8
	/**
9
	 * Holds singleton instance
10
	 *
11
	 * @var Jetpack_Search_Debug_Bar
12
	 */
13
	protected static $instance = null;
14
15
	/**
16
	 * The title to use in the debug bar navigation
17
	 *
18
	 * @var string
19
	 */
20
	public $title;
21
22
	/**
23
	 * Constructor
24
	 */
25
	public function __construct() {
26
		$this->title( esc_html__( 'Jetpack Search', 'jetpack' ) );
27
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
28
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
29
		add_action( 'login_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
30
		add_action( 'enqueue_embed_scripts', array( $this, 'enqueue_scripts' ) );
31
	}
32
33
	/**
34
	 * Returns the singleton instance of Jetpack_Search_Debug_Bar
35
	 *
36
	 * @return Jetpack_Search_Debug_Bar
37
	 */
38
	public static function instance() {
39
		if ( is_null( self::$instance ) ) {
40
			self::$instance = new Jetpack_Search_Debug_Bar();
41
		}
42
		return self::$instance;
43
	}
44
45
	/**
46
	 * Enqueues styles for our panel in the debug bar
47
	 *
48
	 * @return void
49
	 */
50
	public function enqueue_scripts() {
51
		// Do not enqueue scripts if we haven't already enqueued Debug Bar or Query Monitor styles.
52
		if ( ! wp_style_is( 'debug-bar' ) && ! wp_style_is( 'query-monitor' ) ) {
53
			return;
54
		}
55
56
		wp_enqueue_style(
57
			'jetpack-search-debug-bar',
58
			plugins_url( '3rd-party/debug-bar/debug-bar.css', JETPACK__PLUGIN_FILE )
59
		);
60
		wp_enqueue_script(
61
			'jetpack-search-debug-bar',
62
			plugins_url( '3rd-party/debug-bar/debug-bar.js', JETPACK__PLUGIN_FILE ),
63
			array( 'jquery' )
64
		);
65
	}
66
67
	/**
68
	 * Should the Jetpack Search Debug Bar show?
69
	 *
70
	 * Since we've previously done a check for the search module being activated, let's just return true.
71
	 * Later on, we can update this to only show when `is_search()` is true.
72
	 *
73
	 * @return boolean
74
	 */
75
	public function is_visible() {
76
		return true;
77
	}
78
79
	/**
80
	 * Renders the panel content
81
	 *
82
	 * @return void
83
	 */
84
	public function render() {
85
		if ( ! class_exists( 'Jetpack_Search' ) ) {
86
			return;
87
		}
88
89
		$jetpack_search = Jetpack_Search::instance();
90
		$last_query_info = $jetpack_search->get_last_query_info();
91
92
		// If not empty, let's reshuffle the order of some things.
93
		if ( ! empty( $last_query_info ) ) {
94
			$args     = $last_query_info['args'];
95
			$response = $last_query_info['response'];
96
			$response_code = $last_query_info['response_code'];
97
98
			unset( $last_query_info['args'] );
99
			unset( $last_query_info['response'] );
100
			unset( $last_query_info['response_code'] );
101
102
			if ( is_null( $last_query_info['es_time'] ) ) {
103
				$last_query_info['es_time'] = esc_html_x(
104
					'cache hit',
105
					'displayed in search results when results are cached',
106
					'jetpack'
107
				);
108
			}
109
110
			$temp = array_merge(
111
				array( 'response_code' => $response_code ),
112
				array( 'args' => $args ),
113
				$last_query_info,
114
				array( 'response' => $response )
115
			);
116
117
			$last_query_info = $temp;
118
		}
119
		?>
120
		<div class="jetpack-search-debug-bar">
121
			<h2><?php esc_html_e( 'Last query information:', 'jetpack' ); ?></h2>
122
			<?php if ( empty( $last_query_info ) ) : ?>
123
					<?php echo esc_html_x( 'None', 'Text displayed when there is no information', 'jetpack' ); ?>
124
			<?php
125
				else :
126
					foreach ( $last_query_info as $key => $info ) :
0 ignored issues
show
Bug introduced by
The expression $last_query_info of type boolean|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
127
					?>
128
						<h3><?php echo esc_html( $key ); ?></h3>
129
					<?php
130
					if ( 'response' !== $key && 'args' !== $key ) :
131
					?>
132
						<pre><?php print_r( esc_html( $info ) ); ?></pre>
133
					<?php
134
					else :
135
						$this->render_json_toggle( $info );
136
					endif;
137
					?>
138
					<?php
139
					endforeach;
140
			endif;
141
			?>
142
		</div><!-- Closes .jetpack-search-debug-bar -->
143
		<?php
144
	}
145
146
	/**
147
	 * Responsible for rendering the HTML necessary for the JSON toggle
148
	 *
149
	 * @param array $value The resonse from the API as an array.
150
	 * @return void
151
	 */
152
	public function render_json_toggle( $value ) {
153
	?>
154
		<div class="json-toggle-wrap">
155
			<pre class="json"><?php
156
				// esc_html() will not double-encode entities (&amp; -> &amp;amp;).
157
				// If any entities are part of the JSON blob, we want to re-encoode them
158
				// (double-encode them) so that they are displayed correctly in the debug
159
				// bar.
160
				// Use _wp_specialchars() "manually" to ensure entities are encoded correctly.
161
				echo _wp_specialchars(
162
					wp_json_encode( $value ),
163
					ENT_NOQUOTES, // Don't need to encode quotes (output is for a text node).
164
					'UTF-8',      // wp_json_encode() outputs UTF-8 (really just ASCII), not the blog's charset.
165
					true          // Do "double-encode" existing HTML entities
166
				);
167
			?></pre>
168
			<span class="pretty toggle"><?php echo esc_html_x( 'Pretty', 'label for formatting JSON', 'jetpack' ); ?></span>
169
			<span class="ugly toggle"><?php echo esc_html_x( 'Minify', 'label for formatting JSON', 'jetpack' ); ?></span>
170
		</div>
171
	<?php
172
	}
173
}
174