### Chassis path mapping example (alternative) Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/clickable-stack-traces-and-function-names.md Alternative example for Chassis path mapping if the default '/chassis/' path is not used. ```php add_filter( 'qm/output/file_path_map', function( $map ) { $map['/chassis/'] = '/path/to/local/project/'; return $map; } ); ``` -------------------------------- ### Install PHP dependencies Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Installs the PHP dependencies required for development. ```bash composer install ``` -------------------------------- ### Chassis or Vagrant-based VM path mapping example Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/clickable-stack-traces-and-function-names.md Example of how to map server paths to local paths for Chassis or other Vagrant-based VMs using the 'qm/output/file_path_map' filter. ```php add_filter( 'qm/output/file_path_map', function( $map ) { $map['/vagrant/'] = '/path/to/local/project/'; return $map; } ); ``` -------------------------------- ### VVV path mapping example Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/clickable-stack-traces-and-function-names.md Example of how to map server paths to local paths for VVV environments using the 'qm/output/file_path_map' filter. ```php add_filter( 'qm/output/file_path_map', function( $map ) { $map['/srv/'] = '/path/to/vvv/'; return $map; } ); ``` -------------------------------- ### Start Docker containers for tests Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Starts the Docker containers required for running integration and acceptance tests. ```bash composer test:start ``` -------------------------------- ### Install Node dependencies Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Installs the Node.js dependencies required for development. ```bash npm install ``` -------------------------------- ### Profiling with start and stop actions Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md Basic profiling can be performed and displayed in the Timings panel in Query Monitor using actions in your code. ```php do_action( 'qm/start', 'foo' ); // Run some code my_potentially_slow_function(); // Stop the 'foo' timer: do_action( 'qm/stop', 'foo' ); ``` -------------------------------- ### REST API Response Example Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/rest-api-requests.md An example of the 'qm' property within a JSON response from a WordPress REST API endpoint, detailing database queries, cache performance, HTTP requests, and logged messages. ```json { "db_queries": { "dbs": { "$wpdb": { "total": 15, "time": 0.0108, "queries": [ { "sql": "SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'", "time": 0.0011, "stack": [ "wp_load_alloptions()", "is_blog_installed()", "wp_not_installed()" ], "result": 317 }, { "sql": "SELECT * FROM wp_users WHERE ID = '1' LIMIT 1", "time": 0.0003, "stack": [ "WP_User::get_data_by()", "WP_User->__construct()", "wp_set_current_user()", "_wp_get_current_user()", "wp_get_current_user()", "get_current_user_id()", "get_user_option()", "Classic_Editor::get_settings()", "Classic_Editor::init_actions()", "do_action('plugins_loaded')" ], "result": 1 }, { "sql": "SELECT wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish')) ORDER BY wp_posts.post_date DESC LIMIT 0, 5", "time": 0.0003, "stack": [ "WP_Query->get_posts()", "WP_Query->query()", "get_posts()", "DoubleUnderscore\entrypoint()", "do_action('init')" ], "result": 5 } ] } }, "errors": { "total": 1, "errors": [ { "caller": "do_action('init')", "caller_name": "do_action('init')", "sql": "SELECT * FROM table_that_does_not_exist", "ltime": 0, "result": { "errors": { "1146": [ "Table 'wp.table_that_does_not_exist' doesn't exist" ] } } } ] }, "dupes": { "total": 1, "queries": { "SELECT wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish')) ORDER BY wp_posts.post_date DESC LIMIT 0, 5": [ 3, 14, 35 ] } } }, "cache": { "hit_percentage": 67.8, "hits": 931, "misses": 442 }, "http": { "total": 1, "time": 0.6586, "requests": [ { "url": "https://example.org", "method": "GET", "response": { "code": 200, "message": "OK" }, "time": 0.6586, "stack": [ "WP_Http->request()", "WP_Http->get()", "wp_remote_get()", "DoubleUnderscore\entrypoint()", "do_action('init')" ] } ] }, "logger": { "warning": [ { "message": "Preloading was not found, generating fresh", "stack": [ "DoubleUnderscore\dispatcher()", "DoubleUnderscore\entrypoint()", "do_action('init')" ] } ], "debug": [ { "message": "Language: en_US", "stack": [ "DoubleUnderscore\do_logs()", "DoubleUnderscore\entrypoint()", "do_action('init')" ] } ] } } ``` -------------------------------- ### Watch for changes and build assets Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Starts a file watcher that automatically compiles React components when changes are detected. ```bash npm run watch ``` -------------------------------- ### More examples Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/assertions.md You can use this assertion feature to ensure your code is behaving as expected, for example to assert how many database queries are being performed or not performed. ```php foreach ( $posts as $post ) { $before = $wpdb->num_queries; $this->process_post( $post ); $after = $wpdb->num_queries; // Assert that no database queries are performed as we process each post: do_action( 'qm/assert', $after === $before ); } ``` -------------------------------- ### Basic usage Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/assertions.md The `qm/assert` action accepts an assertion value as its first parameter which you'll usually provide in the form of an expression. This should be a boolean `true` or `false` value, although technically anything truthy or falsey is accepted. If the assertion fails then Query Monitor will show an error in the Logs panel, which in turn causes a red warning to appear in the admin toolbar so you get notified about the failure. If the assertion passes then a debug level message will be shown in the Logs panel, which helps you confirm that your assertion is being executed. The second parameter is an optional short description of the assertion. If provided, this will be shown along with the assertion failure or pass message. The third parameter is an optional value of any type that will get output below the error message if the assertion fails. This is useful for debugging an unexpected value. ```php do_action( 'qm/assert', $value === 5 ); do_action( 'qm/assert', $value === 5, 'Value is 5' ); do_action( 'qm/assert', $value === 5, 'Value is 5', $value ); ``` -------------------------------- ### Report only warnings from child theme, silence parent theme errors Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/silencing-errors.md This example demonstrates how to configure Query Monitor to only report warnings from a child theme (identified by 'stylesheet') and completely silence all errors from its parent theme (identified by 'template'). ```php add_filter( 'qm/collect/php_error_levels', function( array $levels ) { $levels['theme']['stylesheet'] = ( E_WARNING & E_USER_WARNING ); $levels['theme']['template'] = ( 0 ); return $levels; } ); ``` -------------------------------- ### Performance Profiling with Query Monitor Source: https://github.com/johnbillion/query-monitor/blob/develop/README.md Shows how to use `qm/start` and `qm/stop` actions to profile code execution and display timing information in the Timings panel. ```php // Start the 'foo' timer: do_action( 'qm/start', 'foo' ); // Run some code my_potentially_slow_function(); // Stop the 'foo' timer: do_action( 'qm/stop', 'foo' ); ``` -------------------------------- ### Using static logging methods Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md Finally, the static logging methods on the `QM` class can be used instead of calling `do_action()`. ```php QM::error( 'Everything is broken' ); ``` -------------------------------- ### Profiling with laps Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md Timers can also make use of laps with the `qm/lap` action. ```php // Start the 'bar' timer: do_action( 'qm/start', 'bar' ); // Iterate over some data: foreach ( range( 1, 10 ) as $i ) { my_potentially_slow_function( $i ); do_action( 'qm/lap', 'bar' ); } // Stop the 'bar' timer: do_action( 'qm/stop', 'bar' ); ``` -------------------------------- ### Build the assets Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Compiles the React components. ```bash npm run build ``` -------------------------------- ### Run Composer tests Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md Command to run tests using Composer. ```bash composer test ``` -------------------------------- ### Check build artifacts Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md Command to create a zip archive to check for files that shouldn't be part of the build. ```bash git archive --output=qm.zip HEAD ``` -------------------------------- ### Run a single acceptance test Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Executes a specific acceptance test file. ```bash composer test:acceptance -- tests/acceptance/EnqueuedScripts.spec.ts ``` -------------------------------- ### Run acceptance tests Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Executes the acceptance tests. ```bash composer test:acceptance ``` -------------------------------- ### Logging with contextual interpolation Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md Contextual interpolation can be used via the curly brace syntax. ```php do_action( 'qm/warning', 'Unexpected value of {foo} encountered', [ 'foo' => $foo, ] ); ``` -------------------------------- ### Run integration tests Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Executes the integration tests. ```bash composer test:integration ``` -------------------------------- ### Manual symlink creation (macOS/Linux) Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/db-php-symlink.md Command to manually create the db.php symlink on macOS or Linux systems. ```bash ln -s /path/to/wordpress/wp-content/plugins/query-monitor/wp-content/db.php /path/to/wordpress/wp-content/db.php ``` -------------------------------- ### Run linting Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Applies code style and quality checks. ```bash npm run lint ``` -------------------------------- ### Push develop to trunk Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md Command to push the develop branch to the trunk. ```bash git push origin develop:trunk ``` -------------------------------- ### Build the browser dev tools extension Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Builds the browser developer tools extension for Query Monitor. ```bash npm run build:extension ``` -------------------------------- ### Run PHPStan Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Performs static analysis using PHPStan. ```bash composer test:phpstan ``` -------------------------------- ### Manual symlink creation (Windows) Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/db-php-symlink.md Command to manually create the db.php symlink on Windows systems, requiring administrator privileges. ```batch mklink C:\path\to\wordpress\wp-content\db.php C:\path\to\wordpress\wp-content\plugins\query-monitor\wp-content\db.php ``` -------------------------------- ### Logging a variable Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md Variables of any type can be logged and they'll be formatted appropriately. ```php $var = [ 1, 2, 3 ]; do_action( 'qm/debug', $var ); ``` -------------------------------- ### Enable User Capabilities Panel Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/user-capabilities.md Add this line to your wp-config.php file to enable the User Capabilities panel in Query Monitor. ```php define( 'QM_ENABLE_CAPS_PANEL', true ); ``` -------------------------------- ### Run PHP CodeSniffer Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Executes PHP CodeSniffer for PHP linting. ```bash composer test:phpcs ``` -------------------------------- ### Static assertion method Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/assertions.md The static assertion method on the `QM` class can be used instead of calling `do_action()`. ```php QM::assert( $value === 5 ); QM::assert( $value === 5, 'Value is 5' ); QM::assert( $value === 5, 'Value is 5', $value ); ``` -------------------------------- ### Preconditions Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/assertions.md Preconditions can be used to assert a certain state before performing logic based on expectations. ```php do_action( 'qm/assert', is_array( $data ), 'Data is an array', $data ); do_action( 'qm/assert', array_key_exists( 'foo', $data ), 'Data contains foo', $data ); ``` -------------------------------- ### Logging an Exception Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md A `WP_Error`, `Exception`, or `Throwable` object can be passed directly into the logger. ```php try { // your code } catch ( Exception $e ) { do_action( 'qm/error', $e ); } ``` -------------------------------- ### Enable Query Monitor WP-CLI command Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/help/db-php-symlink.md This command can be used to enable the Query Monitor db.php symlink via WP-CLI. ```bash wp qm enable ``` -------------------------------- ### Push develop branch Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md Command to push the develop branch to the origin. ```bash git push origin develop ``` -------------------------------- ### General Panel Styling Source: https://github.com/johnbillion/query-monitor/blob/develop/extension/panel.html CSS rules for the html, body, and the main waiting state overlay. ```css html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; } .qm-waiting { position: fixed; inset: 0; display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: #666; } ``` -------------------------------- ### Push develop to release branch Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md Command to push the develop branch to the release branch. ```bash git push origin develop:release ``` -------------------------------- ### Run type checking Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Performs type checking on the codebase. ```bash npm run typecheck ``` -------------------------------- ### Bump version: minor Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md NPM command to bump the minor version number. ```bash npm run bump:minor ``` -------------------------------- ### Waiting Button Styling Source: https://github.com/johnbillion/query-monitor/blob/develop/extension/panel.html CSS rules for the button within the waiting card. ```css .qm-waiting-button { display: inline-block; padding: 0.5em 1em; background: #2271b1; color: #fff; text-decoration: none; border-radius: 4px; } ``` -------------------------------- ### Guzzle HTTP Client Integration Source: https://github.com/johnbillion/query-monitor/blob/develop/README.md Illustrates how to add Query Monitor middleware to a Guzzle HTTP client to log requests that bypass WordPress's HTTP API. ```php use GuzzleHttp\HandlerStack; use GuzzleHttp\Client; // Add Query Monitor middleware to your Guzzle client $stack = HandlerStack::create(); $stack->push(QM_Collector_HTTP::guzzle_middleware()); $client = new Client(['handler' => $stack]); // All requests will now appear in Query Monitor $response = $client->get('https://api.example.com/data'); ``` -------------------------------- ### Bump version: major Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md NPM command to bump the major version number. ```bash npm run bump:major ``` -------------------------------- ### Logging a WP_Error object Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md A `WP_Error`, `Exception`, or `Throwable` object can be passed directly into the logger. ```php if ( is_wp_error( $response ) ) { do_action( 'qm/error', $response ); } ``` -------------------------------- ### Bump version: patch Source: https://github.com/johnbillion/query-monitor/blob/develop/RELEASING.md NPM command to bump the patch version number. ```bash npm run bump:patch ``` -------------------------------- ### Logging a simple debug message Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/profiling-and-logging.md Messages and variables can be logged in Query Monitor similarly to how you can call `console.log` in JavaScript to log data from WordPress to the console. This can be used as a replacement for `var_dump()`. ```php do_action( 'qm/debug', 'This happened!' ); ``` -------------------------------- ### Using with Existing Handler Stack Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/guzzle-http-requests.md Integrate Query Monitor middleware into an existing custom handler stack. ```php $stack = HandlerStack::create(); $stack->push( Middleware::retry( /* retry config */ ) ); $stack->push( QM_Collector_HTTP::guzzle_middleware() ); // Add QM middleware $stack->push( Middleware::log( $logger, $formatter ) ); $client = new Client( [ 'handler' => $stack ] ); ``` -------------------------------- ### Waiting Card Styling Source: https://github.com/johnbillion/query-monitor/blob/develop/extension/panel.html CSS rules for the card displayed when the Query Monitor is waiting for data. ```css .qm-waiting-card { padding: 2em; border: 1px solid #ccc; border-radius: 8px; background: #f7f7f7; text-align: center; max-width: 28em; } .qm-waiting-card hr, .qm-waiting-card p { margin: 0 0 1em; } ``` -------------------------------- ### Postconditions Source: https://github.com/johnbillion/query-monitor/blob/develop/docs/wordpress-debugging/assertions.md Postconditions can be used to assert that a particular outcome occurred. ```php do_action( 'qm/assert', did_action( 'my-action' ) ); ``` -------------------------------- ### Stop Docker containers for tests Source: https://github.com/johnbillion/query-monitor/blob/develop/CONTRIBUTING.md Stops the Docker containers used for running integration and acceptance tests. ```bash composer test:stop ```