PluginProbe
ElasticPress / 5.0.2
ElasticPress v5.0.2
5.3.5 5.3.4 3.6.5 3.6.6 4.0.0 4.0.1 4.1.0 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.6.0 4.6.1 4.7.0 4.7.1 4.7.2 5.0.0 5.0.1 5.0.2 All 108 releases
elasticpress / includes / classes / StatusReport / FailedQueries.php

FailedQueries.php in ElasticPress 5.0.2, at includes/classes/StatusReport/FailedQueries.php

187 lines 4.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Failed Queries report class
4 *
5 * @since 4.4.0
6 * @package elasticpress
7 */
8
9 namespace ElasticPress\StatusReport;
10
11 use \ElasticPress\QueryLogger;
12 use \ElasticPress\Utils;
13
14 defined( 'ABSPATH' ) || exit;
15
16 /**
17 * FailedQueries report class
18 *
19 * @package ElasticPress
20 */
21 class FailedQueries extends Report {
22
23 /**
24 * The logger instance
25 *
26 * @var QueryLogger
27 */
28 protected $query_logger;
29
30 /**
31 * Class constructor
32 *
33 * @param QueryLogger $query_logger The logger instance
34 */
35 public function __construct( QueryLogger $query_logger ) {
36 $this->query_logger = $query_logger;
37 }
38
39 /**
40 * Return the report title
41 *
42 * @return string
43 */
44 public function get_title() : string {
45 return __( 'Failed Queries', 'elasticpress' );
46 }
47
48 /**
49 * Return the report fields
50 *
51 * @return array
52 */
53 public function get_groups() : array {
54 $this->maybe_clear_logs();
55
56 $logs = $this->query_logger->get_logs( false );
57
58 $labels = [
59 'wp_url' => esc_html__( 'Page URL', 'elasticpress' ),
60 'es_req' => esc_html__( 'Elasticsearch Request', 'elasticpress' ),
61 'request_id' => esc_html__( 'Request ID', 'elasticpress' ),
62 'timestamp' => esc_html__( 'Time', 'elasticpress' ),
63 'query_time' => esc_html__( 'Time Spent (ms)', 'elasticpress' ),
64 'wp_args' => esc_html__( 'WP Query Args', 'elasticpress' ),
65 'status_code' => esc_html__( 'HTTP Status Code', 'elasticpress' ),
66 'body' => esc_html__( 'Query Body', 'elasticpress' ),
67 'result' => esc_html__( 'Query Result', 'elasticpress' ),
68 ];
69
70 $groups = [];
71 foreach ( $logs as $log ) {
72 list( $error, $solution ) = $this->analyze_log( $log );
73
74 $fields = [
75 'error' => [
76 'label' => __( 'Error', 'elasticpress' ),
77 'value' => $error,
78 ],
79 'recommended_solution' => [
80 'label' => __( 'Recommended Solution', 'elasticpress' ),
81 'value' => $solution,
82 ],
83 ];
84
85 foreach ( $log as $field => $value ) {
86 // Already outputted in the title
87 if ( in_array( $field, [ 'wp_url', 'timestamp' ], true ) ) {
88 continue;
89 }
90
91 $fields[ $field ] = [
92 'label' => $labels[ $field ] ?? $field,
93 'value' => $value,
94 ];
95 }
96
97 $groups[] = [
98 'title' => sprintf( '%s (%s)', $log['wp_url'], date_i18n( 'Y-m-d H:i:s', $log['timestamp'] ) ),
99 'fields' => $fields,
100 ];
101 }
102
103 return $groups;
104 }
105
106 /**
107 * Return the output of a button to clear the logged queries
108 *
109 * @return string
110 */
111 public function get_actions() : array {
112 global $wp;
113
114 $logs = $this->query_logger->get_logs( false );
115
116 if ( empty( $logs ) ) {
117 return [];
118 }
119
120 $label = __( 'Clear query log', 'elasticpress' );
121 $href = wp_nonce_url( add_query_arg( [ $_GET ], $wp->request ), 'ep-clear-logged-queries', '_wpnonce' ); // phpcs:ignore WordPress.Security.NonceVerification
122
123 return [
124 [
125 'href' => $href,
126 'label' => $label,
127 ],
128 ];
129 }
130
131 /**
132 * If a nonce is present, clear the logs
133 */
134 protected function maybe_clear_logs() {
135 if ( empty( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'ep-clear-logged-queries' ) ) { // phpcs:ignore WordPress.Security.NonceVerification
136 return;
137 }
138
139 $this->query_logger->clear_logs();
140
141 if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) {
142 $redirect_url = network_admin_url( 'admin.php?page=elasticpress-status-report' );
143 } else {
144 $redirect_url = admin_url( 'admin.php?page=elasticpress-status-report' );
145 }
146
147 wp_safe_redirect( $redirect_url );
148 exit();
149 }
150
151 /**
152 * Given a log, try to find the error and its solution
153 *
154 * @param array $log The log
155 * @return array The error in index 0, solution in index 1
156 */
157 public function analyze_log( $log ) {
158 if ( is_array( $log['result'] ) && ! empty( $log['result']['is_wp_error'] ) ) {
159 return [
160 $log['result']['message'],
161 __( 'It seems WordPress was not able to complete the request. Review the error message and your configuration.', 'elasticpress' ),
162 ];
163 }
164
165 $error = Utils\get_elasticsearch_error_reason( $log );
166
167 $solution = ( ! empty( $error ) ) ?
168 ( new \ElasticPress\ElasticsearchErrorInterpreter() )->maybe_suggest_solution_for_es( $error )['solution'] :
169 '';
170
171 return [ $error, $solution ];
172 }
173
174 /**
175 * DEPRECATED. Given an Elasticsearch error, try to suggest a solution
176 *
177 * @deprecated 5.0.0
178 * @param string $error The error
179 * @return string
180 */
181 protected function maybe_suggest_solution_for_es( $error ) {
182 _deprecated_function( __METHOD__, '5.0.0', '\ElasticPress\ElasticsearchErrorInterpreter::maybe_suggest_solution_for_es()' );
183
184 return ( new \ElasticPress\ElasticsearchErrorInterpreter() )->maybe_suggest_solution_for_es( $error )['solution'];
185 }
186 }
187