/var/www/html_nl/wp-content/plugins/query-monitor/collectors/db_dupes.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php declare(strict_types 1);
/**
 * Duplicate database query collector.
 *
 * @package query-monitor
 */

if ( ! defined'ABSPATH' ) ) {
    exit;
}

/**
 * @extends QM_DataCollector<QM_Data_DB_Dupes>
 */
class QM_Collector_DB_Dupes extends QM_DataCollector {

    public 
$id 'db_dupes';

    public function 
get_storage(): QM_Data {
        return new 
QM_Data_DB_Dupes();
    }

    
/**
     * @return void
     */
    
public function process() {
        
/** @var QM_Collector_DB_Queries|null $dbq */
        
$dbq QM_Collectors::get'db_queries' );

        if ( ! 
$dbq ) {
            return;
        }

        
/** @var QM_Data_DB_Queries $dbq_data */
        
$dbq_data $dbq->get_data();

        if ( empty( 
$dbq_data->dupes ) ) {
            return;
        }

        
// Filter out SQL queries that do not have dupes
        
$this->data->dupes array_filter$dbq_data->dupes, array( $this'filter_dupe_items' ) );

        
// Ignore dupes from `WP_Query->set_found_posts()`
        
unset( $this->data->dupes['SELECT FOUND_ROWS()'] );

        
$stacks = array();
        
$callers = array();
        
$components = array();
        
$times = array();

        
// Loop over all SQL queries that have dupes
        
foreach ( $this->data->dupes as $sql => $query_ids ) {

            
// Loop over each query
            
foreach ( $query_ids as $query_id ) {

                if ( isset( 
$dbq_data->rows$query_id ]['trace'] ) ) {
                    
/** @var QM_Backtrace */
                    
$trace $dbq_data->rows$query_id ]['trace'];
                    
$stack array_column$trace->get_filtered_trace(), 'id' );
                    
$component $trace->get_component();

                    
// Populate the component counts for this query
                    
if ( isset( $components$sql ][ $component->name ] ) ) {
                        
$components$sql ][ $component->name ]++;
                    } else {
                        
$components$sql ][ $component->name ] = 1;
                    }
                } else {
                    
/** @var array<int, string> */
                    
$stack $dbq_data->rows$query_id ]['stack'];
                }

                
// Populate the caller counts for this query
                
if ( isset( $callers$sql ][ $stack[0] ] ) ) {
                    
$callers$sql ][ $stack[0] ]++;
                } else {
                    
$callers$sql ][ $stack[0] ] = 1;
                }

                
// Populate the stack for this query
                
$stacks$sql ][] = $stack;

                
// Populate the time for this query
                
if ( isset( $times$sql ] ) ) {
                    
$times$sql ] += $dbq->data->rows$query_id ]['ltime'];
                } else {
                    
$times$sql ] = $dbq->data->rows$query_id ]['ltime'];
                }
            }

            
// Get the callers which are common to all stacks for this query
            
$common call_user_func_array'array_intersect'$stacks$sql ] );

            
// Remove callers which are common to all stacks for this query
            
foreach ( $stacks$sql ] as $i => $stack ) {
                
$stacks$sql ][ $i ] = array_valuesarray_diff$stack$common ) );

                
// No uncommon callers within the stack? Just use the topmost caller.
                
if ( empty( $stacks$sql ][ $i ] ) ) {
                    
$stacks$sql ][ $i ] = array_keys$callers$sql ] );
                }
            }

            
// Wave a magic wand
            
$sources$sql ] = array_count_valuesarray_column$stacks$sql ], ) );

        }

        if ( ! empty( 
$sources ) ) {
            
$this->data->dupe_sources $sources;
            
$this->data->dupe_callers $callers;
            
$this->data->dupe_components $components;
            
$this->data->dupe_times $times;
        }

    }
}

/**
 * @param array<string, QM_Collector> $collectors
 * @param QueryMonitor $qm
 * @return array<string, QM_Collector>
 */
function register_qm_collector_db_dupes( array $collectorsQueryMonitor $qm ) {
    
$collectors['db_dupes'] = new QM_Collector_DB_Dupes();
    return 
$collectors;
}

add_filter'qm/collectors''register_qm_collector_db_dupes'25);