2
2
/**
3
3
* Extends WPGraphQL's Query Analyzer to add custom heuristic rules and metrics.
4
4
*
5
- * @package WPGraphQL\Debug
5
+ * @package WPGraphQL\Debug\Analysis
6
6
*/
7
7
8
8
declare (strict_types=1 );
9
9
10
10
namespace WPGraphQL \Debug \Analysis ;
11
11
12
- use WPGraphQL \Debug \Analysis \Metrics \ Complexity ;
12
+ use WPGraphQL \Debug \Analysis \Interfaces \ AnalyzerItemInterface ;
13
13
use WPGraphQL \Utils \QueryAnalyzer as OriginalQueryAnalyzer ;
14
14
15
15
/**
16
- * Class QueryAnalyzerExtension
16
+ * Class QueryAnalyzer
17
17
*
18
18
* This class hooks into the WPGraphQL Query Analyzer to add custom analysis.
19
19
*/
20
20
class QueryAnalyzer {
21
21
22
- /**
23
- * @var QueryAnalyzer The instance of the WPGraphQL Query Analyzer.
24
- */
25
- protected OriginalQueryAnalyzer $ query_analyzer ;
22
+ /**
23
+ * @var OriginalQueryAnalyzer The instance of the WPGraphQL Query Analyzer from the core plugin .
24
+ */
25
+ protected OriginalQueryAnalyzer $ query_analyzer ;
26
26
27
- /**
28
- * @var string|null The GraphQL query string for the current request .
29
- */
30
- protected ? string $ currentQuery = null ;
27
+ /**
28
+ * @var AnalyzerItemInterface[] An array of registered analyzer items (metrics and rules) .
29
+ */
30
+ protected array $ analyzerItems = [] ;
31
31
32
- /**
33
- * @var array<string,mixed> The variables for the current GraphQL request.
34
- */
35
- protected array $ currentVariables = [];
32
+ /**
33
+ * Constructor for the QueryAnalyzerExtension.
34
+ *
35
+ * @param OriginalQueryAnalyzer $query_analyzer The instance of the WPGraphQL Query Analyzer.
36
+ */
37
+ public function __construct ( OriginalQueryAnalyzer $ query_analyzer ) {
38
+ $ this ->query_analyzer = $ query_analyzer ;
39
+ }
36
40
37
- /**
38
- * Constructor for the QueryAnalyzerExtension.
39
- *
40
- * @param OriginalQueryAnalyzer $query_analyzer The instance of the WPGraphQL Query Analyzer.
41
- */
42
- public function __construct ( OriginalQueryAnalyzer $ query_analyzer ) {
43
- $ this ->query_analyzer = $ query_analyzer ;
44
- }
41
+ /**
42
+ * Adds an AnalyzerItem (metric or rule) to be processed.
43
+ *
44
+ * @param AnalyzerItemInterface $item The item to add.
45
+ * @return void
46
+ */
47
+ public function addAnalyzerItem ( AnalyzerItemInterface $ item ): void {
48
+ $ this ->analyzerItems [] = $ item ;
49
+ }
45
50
46
- /**
47
- * Initializes the extension by adding necessary WordPress hooks.
48
- */
49
- public function init (): void {
50
- add_filter ( 'graphql_query_analyzer_graphql_keys ' , [ $ this , 'addMetricsToAnalyzerOutput ' ], 10 , 5 );
51
- }
51
+ /**
52
+ * Initializes the extension by adding necessary WordPress hooks.
53
+ */
54
+ public function init (): void {
55
+ // This filter allows us to inject custom data into the 'debugExtensions' part of the GraphQL response.
56
+ add_filter ( 'graphql_query_analyzer_graphql_keys ' , [ $ this , 'addAnalysisToOutput ' ], 10 , 5 );
57
+ }
52
58
53
- /**
54
- * Adds new metrics and analysis results to the Query Analyzer's output.
55
- * This method is a callback for the 'graphql_query_analyzer_graphql_keys' filter.
56
- *
57
- * @param array<string,mixed> $graphql_keys Existing data from the Query Analyzer.
58
- * @param string $return_keys The keys returned to the X-GraphQL-Keys header.
59
- * @param string $skipped_keys The keys that were skipped.
60
- * @param string[] $return_keys_array The keys returned in array format.
61
- * @param string[] $skipped_keys_array The keys skipped in array format.
62
- * @return array<string,mixed> The modified GraphQL keys with custom metrics.
63
- */
64
- public function addMetricsToAnalyzerOutput (
65
- array $ graphql_keys ,
66
- string $ return_keys ,
67
- string $ skipped_keys ,
68
- array $ return_keys_array ,
69
- array $ skipped_keys_array
70
- ): array {
71
- $ complexityValue = null ;
72
- $ complexityNote = 'Could not compute complexity ' ;
59
+ /**
60
+ * Adds new metrics and analysis results to the Query Analyzer's output.
61
+ * This method is a callback for the 'graphql_query_analyzer_graphql_keys' filter.
62
+ *
63
+ * @param array<string,mixed> $graphql_keys Existing data from the Query Analyzer.
64
+ * @param string $return_keys The keys returned to the X-GraphQL-Keys header. (unused here)
65
+ * @param string $skipped_keys The keys that were skipped. (unused here)
66
+ * @param string[] $return_keys_array The keys returned in array format. (unused here)
67
+ * @param string[] $skipped_keys_array The keys skipped in array format. (unused here)
68
+ * @return array<string,mixed> The modified GraphQL keys with custom metrics.
69
+ */
70
+ public function addAnalysisToOutput (
71
+ array $ graphql_keys ,
72
+ string $ return_keys , // Keep for filter signature, but not used.
73
+ string $ skipped_keys , // Keep for filter signature, but not used.
74
+ array $ return_keys_array , // Keep for filter signature, but not used.
75
+ array $ skipped_keys_array // Keep for filter signature, but not used.
76
+ ): array {
77
+ if ( ! isset ( $ graphql_keys ['debugExtensions ' ] ) ) {
78
+ $ graphql_keys ['debugExtensions ' ] = [];
79
+ }
73
80
74
- $ request = $ this ->query_analyzer ->get_request ();
75
- $ currentQuery = $ request ->params ->query ?? null ;
76
- $ currentVariables = (array ) ( $ request ->params ->variables ?? [] );
81
+ $ request = $ this ->query_analyzer ->get_request ();
82
+ $ currentQuery = $ request ->params ->query ?? null ;
83
+ $ currentVariables = (array ) ( $ request ->params ->variables ?? [] );
84
+ $ schema = $ this ->query_analyzer ->get_schema ();
77
85
78
- // Add some logging to debug.
79
- error_log ( 'QueryAnalyzerExtension: addCustomMetricsToAnalyzerOutput called. ' );
80
- error_log ( 'QueryAnalyzerExtension: Retrieved Query: ' . ( $ currentQuery ?? 'NULL ' ) );
81
- error_log ( 'QueryAnalyzerExtension: Retrieved Variables: ' . print_r ( $ currentVariables , true ) );
82
- if ( ! empty ( $ currentQuery ) ) {
83
- try {
84
- $ complexityMetrics = new Complexity ();
85
- $ schema = $ this ->query_analyzer ->get_schema ();
86
- $ complexityValue = $ complexityMetrics ->calculate ( $ currentQuery , $ currentVariables , $ schema );
86
+ foreach ( $ this ->analyzerItems as $ item ) {
87
+ try {
88
+ if ( ! empty ( $ currentQuery ) ) {
89
+ $ result = $ item ->analyze ( $ currentQuery , $ currentVariables , $ schema );
90
+ } else {
91
+ $ result = [
92
+ 'value ' => null ,
93
+ 'note ' => 'No query provided for analysis. ' ,
94
+ ];
95
+ }
96
+ } catch ( \Exception $ e ) {
97
+ error_log ( sprintf (
98
+ 'WPGraphQL Debug Extensions: Analysis item "%s" failed: %s ' ,
99
+ $ item ->getKey (),
100
+ $ e ->getMessage ()
101
+ ) );
102
+ $ result = [
103
+ 'value ' => null ,
104
+ 'note ' => 'Analysis failed: ' . $ e ->getMessage (),
105
+ 'error ' => true ,
106
+ ];
107
+ }
87
108
88
- } catch (\Exception $ e ) {
89
- error_log ( 'WPGraphQL Debug Extensions: Complexity calculation failed: ' . $ e ->getMessage () );
90
- $ complexityNote .= ': ' . $ e ->getMessage ();
91
- }
92
- }
93
- if ( ! isset ( $ graphql_keys ['debugExtensions ' ] ) ) {
94
- $ graphql_keys ['debugExtensions ' ] = [];
95
- }
96
- $ graphql_keys ['debugExtensions ' ]['complexity ' ] = $ complexityValue ;
109
+ $ graphql_keys ['debugExtensions ' ][ $ item ->getKey () ] = $ result ;
110
+ }
97
111
98
- return $ graphql_keys ;
99
- }
112
+ return $ graphql_keys ;
113
+ }
100
114
}
0 commit comments